#ifndef VLIBC_TIME_H #define VLIBC_TIME_H /* * vlibc — . * * Calendar time, clock ids, and interval timers. The ISO C functions * (time, clock, timespec_get, difftime, asctime/ctime/mktime/gmtime/ * localtime, strftime) and the POSIX clock_* / timer_* / sleep family are * thin, level-gated wrappers over the Linux time syscalls. * * Level 1 (onlyposix): time, clock, timespec_get, difftime, * clock_gettime/settime/getres/getcpuclockid, * clock_nanosleep, nanosleep, sleep, and the * broken-down-time/formatting declarations * (mktime, gmtime/localtime and _r forms, asctime, * ctime, strftime, tzset). * Level 2 (muslmimic): POSIX interval timers (timer_create/delete/ * settime/gettime/getoverrun) and the XSI * conveniences (timegm, strftime_l, usleep, * asctime_r, ctime_r, strptime, tzname/daylight/ * timezone). * * The scalar time types (time_t, clock_t, clockid_t, pid_t, timer_t and * useconds_t) come from , which this header includes; struct * timespec and struct tm are defined here. timer_t is the * opaque pointer type (kernel timer ids are returned through it); struct * sigevent and struct itimerspec stay forward-declared here — their kernel * ABI mirrors are private to the timer implementation (see src/time/ * timer.c) and to consumers that define matching structs. * * The clock ids and TIMER_ABSTIME mirror the kernel ABI (x86_64): the * CLOCK_* values are passed to SYS_clock_* and SYS_timer_* unchanged, and * TIMER_ABSTIME is the timer_settime/clock_nanosleep flag bit. */ #include #include #include #ifdef __cplusplus extern "C" { #endif /* Base argument of timespec_get(); the only base defined by ISO C. */ #define TIME_UTC 1 /* Ticks per second reported by clock() (vlibc always reports 1 MHz). */ #define CLOCKS_PER_SEC 1000000 /* Clock ids (kernel ABI; SYS_clock_* argument). */ #define CLOCK_REALTIME 0 /* wall clock since the Epoch */ #define CLOCK_MONOTONIC 1 /* monotonic since boot */ #define CLOCK_PROCESS_CPUTIME_ID 2 /* CPU time of this process */ #define CLOCK_THREAD_CPUTIME_ID 3 /* CPU time of this thread */ /* Flag for absolute (vs relative) timer expiry. */ #define TIMER_ABSTIME 1 /* * Elapsed time, seconds + nanoseconds. Kernel ABI layout (x86_64): the * wrappers pass this straight to the clock/nanosleep/timer syscalls. */ struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds (0..999999999) */ }; /* * Broken-down civil time. tm_gmtoff and tm_zone are the XSI extensions * (seconds east of UTC / timezone name) carried for glibc compatibility. */ struct tm { int tm_sec; /* seconds after the minute (0..60) */ int tm_min; /* minutes after the hour (0..59) */ int tm_hour; /* hours since midnight (0..23) */ int tm_mday; /* day of the month (1..31) */ int tm_mon; /* months since January (0..11) */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday (0..6) */ int tm_yday; /* days since January 1 (0..365) */ int tm_isdst; /* daylight-saving flag */ long tm_gmtoff; /* seconds east of UTC */ const char *tm_zone; /* timezone abbreviation */ }; /* Return the current wall-clock time in seconds; if t is not NULL store it * there too, and return (time_t)-1 with errno set on failure. */ time_t time(time_t *t); /* Approximate processor time in CLOCKS_PER_SEC units since an arbitrary * epoch, or (clock_t)-1 with errno set on failure. */ clock_t clock(void); /* Store the current time for base into ts and return base; return 0 if * base is not TIME_UTC or the clock cannot be read. */ int timespec_get(struct timespec *ts, int base); /* Read the given clock into tp. Return 0 or -1 with errno set. */ int clock_gettime(clockid_t clockid, struct timespec *tp); /* Set the given clock from tp. Return 0 or -1 with errno set. */ int clock_settime(clockid_t clockid, const struct timespec *tp); /* Resolution of the given clock; store it in res when res is not NULL. * Return 0 or -1 with errno set. */ int clock_getres(clockid_t clockid, struct timespec *res); /* Clock id measuring the CPU time of the given process (0 = calling * process). Return 0, or -1 with errno set when the process is unknown. */ int clock_getcpuclockid(pid_t pid, clockid_t *clock_id); /* Sleep on the given clock. Without TIMER_ABSTIME request is relative and * the sleep restarts from remain on signal interruption. */ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *request, struct timespec *remain); /* Sleep request seconds; when interrupted and remain is not NULL the sleep * restarts from the remaining time. Return 0 or -1 with errno set. */ int nanosleep(const struct timespec *request, struct timespec *remain); /* Sleep seconds (whole seconds; signals can shorten the sleep, which is * then resumed). Return the unslept seconds, normally 0. */ unsigned int sleep(unsigned int seconds); /* Convert broken-down civil time back to calendar seconds. */ time_t mktime(struct tm *tm); /* Broken-down local time; localtime uses an internal static buffer. * Return NULL on error. */ struct tm * localtime(const time_t *timer); /* Broken-down local time into buf. Return buf or NULL on error. */ struct tm * localtime_r(const time_t *timer, struct tm *buf); /* Broken-down UTC; gmtime uses an internal static buffer. */ struct tm * gmtime(const time_t *timer); /* Broken-down UTC into buf. Return buf or NULL on error. */ struct tm * gmtime_r(const time_t *timer, struct tm *buf); /* Fixed-format rendering of broken-down time ("Sun Sep 16 01:03:52 1973"). */ char * asctime(const struct tm *tm); /* asctime(localtime(timer)); fixed-format wall-clock rendering. */ char * ctime(const time_t *timer); /* Format broken-down time per format into s (at most maxsize bytes); * return the bytes written (0 when the buffer was too small). */ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr); /* Seconds between two calendar times (b subtracted from a). */ double difftime(time_t a, time_t b); /* Establish the local timezone from TZ / the system default. */ void tzset(void); #if VLIBC_LEVEL_GE(2) /* Level 2 (muslmimic): POSIX interval timers and XSI conveniences. */ /* Opaque kernel-ABI structures; consumers define layout-compatible structs * (see src/time/timer.c). */ struct sigevent; struct itimerspec; /* Create a per-process interval timer on clockid; the timer id is stored * through timerid. Return 0 or -1 with errno set. */ int timer_create(clockid_t clockid, const struct sigevent *restrict evp, timer_t *restrict timerid); /* Destroy the given timer. Return 0 or -1 with errno set. */ int timer_delete(timer_t timerid); /* Arm/disarm the timer; when old_value is not NULL the previous setting is * stored there. Return 0 or -1 with errno set. */ int timer_settime(timer_t timerid, int flags, const struct itimerspec *restrict new_value, struct itimerspec *restrict old_value); /* Remaining time until the timer expires (and its interval). Return 0 or * -1 with errno set. */ int timer_gettime(timer_t timerid, struct itimerspec *curr_value); /* Number of timer expirations between the most recent signal delivery and * the one before it; -1 with errno set when there was no pending delivery. */ int timer_getoverrun(timer_t timerid); /* mktime in UTC rather than local time. */ time_t timegm(struct tm *tm); /* strftime with an explicit locale object (locale_t is not yet defined; * the locale argument is an opaque pointer). */ size_t strftime_l(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr, void *loc); /* Microsecond sleep (whole microseconds; signals resume the sleep). * Return 0 or the unslept microseconds with errno set. */ useconds_t usleep(useconds_t usec); /* asctime into a caller-provided buffer of at least 26 bytes. */ char * asctime_r(const struct tm *tm, char *buf); /* ctime into a caller-provided buffer of at least 26 bytes. */ char * ctime_r(const time_t *timer, char *buf); /* Parse format from s into broken-down time; return the first character * not consumed, or NULL when the format did not match. */ char * strptime(const char *restrict s, const char *restrict format, struct tm *restrict tm); /* Timezone state maintained by tzset(). */ extern char *tzname[2]; extern int daylight; extern long timezone; #endif /* VLIBC_LEVEL_GE(2) */ #ifdef __cplusplus } #endif #endif /* VLIBC_TIME_H */