millis() on linux system

I am trying to port some software/library from arduino to linux/raspberry pi. One of the things I can't do is a system tick that is unaffected by any change of system clock (manual change or day light timing or anything).

I've found code here but it doesn't compile on my Debian "undefined reference".

unsigned long millis(void)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts );
    return ( ts.tv_sec * 1000 + ts.tv_nsec / 1000000L );
}


unsigned long micros(void)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts );
    return ( ts.tv_sec * 1000000L + ts.tv_nsec / 1000L );
}

I did man page on my system and got a page that describes how to use this function but I don't seem to be able to compile the above code without error. The time.h is riddled with #ifdef and here is the relevant part:

# ifdef __USE_POSIX199309
/* Pause execution for a number of nanoseconds.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int nanosleep (__const struct timespec *__requested_time,
                      struct timespec *__remaining);


/* Get resolution of clock CLOCK_ID.  */
extern int clock_getres (clockid_t __clock_id, struct timespec *__res) __THROW;

/* Get current value of clock CLOCK_ID and store it in TP.  */
extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;

/* Set clock CLOCK_ID to value TP.  */
extern int clock_settime (clockid_t __clock_id, __const struct timespec *__tp)
     __THROW;

#  ifdef __USE_XOPEN2K
/* High-resolution sleep with the specified clock.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int clock_nanosleep (clockid_t __clock_id, int __flags,
                            __const struct timespec *__req,
                            struct timespec *__rem);

/* Return clock ID for CPU-time clock.  */
extern int clock_getcpuclockid (pid_t __pid, clockid_t *__clock_id) __THROW;
#  endif


/* Create new per-process timer using CLOCK_ID.  */
extern int timer_create (clockid_t __clock_id,
                         struct sigevent *__restrict __evp,
                         timer_t *__restrict __timerid) __THROW;

/* Delete timer TIMERID.  */
extern int timer_delete (timer_t __timerid) __THROW;

/* Set timer TIMERID to VALUE, returning old value in OVLAUE.  */
extern int timer_settime (timer_t __timerid, int __flags,
                          __const struct itimerspec *__restrict __value,
                          struct itimerspec *__restrict __ovalue) __THROW;

/* Get current value of timer TIMERID and store it in VLAUE.  */
extern int timer_gettime (timer_t __timerid, struct itimerspec *__value)
     __THROW;

/* Get expiration overrun for timer TIMERID.  */
extern int timer_getoverrun (timer_t __timerid) __THROW;
# endif

So if I don't define __USE_POSIX199309 I don't even get these functions. So I added the define in my compiler option -D__USE_POSIX199309. This portion is displayed in regular color coding by eclipse after I added the option. Still same error. Any insight?

Try gettimeofday() :

Standard C Library Functions                     gettimeofday(3C)

NAME
    gettimeofday, settimeofday - get or set the date and time

SYNOPSIS
    #include <sys/time.h>

int gettimeofday(struct timeval *tp, void *);

int settimeofday(struct timeval *tp, void *);

DESCRIPTION
    The gettimeofday()  function  gets  and  the  settimeofday()
    function  sets  the system's notion of the current time. The
    current  time  is  expressed  in  elapsed  seconds  and
    microseconds since 00:00 Universal Coordinated Time, January
    1, 1970. The resolution of  the  system  clock  is  hardware
    dependent;  the time may be updated continuously or in clock
    ticks.

Here are some macros that I copied from a benchmar program:

/* copied from mpbench */
#define TIMER_CLEAR     (tv1.tv_sec = tv1.tv_usec = tv2.tv_sec = tv2.tv_usec = 0)
#define TIMER_START     gettimeofday(&tv1, (struct timezone*)0)
#define TIMER_ELAPSED   ((tv2.tv_usec-tv1.tv_usec)+((tv2.tv_sec-tv1.tv_sec)*1000000))
#define TIMER_STOP      gettimeofday(&tv2, (struct timezone*)0)
struct timeval tv1,tv2;

....
main()
...
  TIMER_CLEAR;
  TIMER_START;

/* code to instrument goes here */
...

          TIMER_STOP;
          printf("# threads, calls, seconds, calls/s\n");
          printf("%d,%d,%f,%f\n", omp_get_num_threads(), counter, TIMER_ELAPSED/1000000.0, counter / (TIMER_ELAPSED/1000000.0));

I've used this on Solaris and various flavors of linux (although not Debian).

-j

Thank you kg4wsv! This would be useful to set time on the raspberry pi at start up with an RTC besides used as ticks. So "resolution depends on system" means if I set say 0us and then 250us and the system may not even do anything if it is not able to set its clock with accuracy of 250us, right?

So "resolution depends on system" means if I set say 0us and then 250us and the system may not even do anything if it is not able to set its clock with accuracy of 250us, right?

That's my understanding. I've never used this to set time, only to instrument code, and every system has reported at least millisecond resolution.

To set time, I've always used the command line (date, rdate, or ntpdate) or an ntp client daemon.

-j

Great! Thanks. I found system() call pretty useful. When don't know how to delete a file, just system("rm file"); until I figure it out in C library :slight_smile:

I found system() call pretty useful.

Yeah, but it's dangerous from a security standpoint and it involves a lot of overhead (fork()/exec() )

When don't know how to delete a file, just system("rm file"); until I figure it out in C library

I think that one's unlink().

-j