lgammaf/lgammaf_r, log10f, sinhf, sqrtf, tgammaf, y0/j0, y1/j1, and yn/jn
were moved to compat symbols, allowing improvements in performance.
+* The ISO C23 optional time base TIME_MONOTONIC, TIME_ACTIVE, and
+ TIME_THREAD_ACTIVE have been added.
+
Deprecated and removed features, and other changes affecting compatibility:
* Support for dumped heaps has been removed - malloc_set_state() now always
# include <time-clockid.h>
# include <sys/time.h>
# include <stdint.h>
+# include <verify.h>
extern __typeof (strftime_l) __strftime_l;
libc_hidden_proto (__strftime_l)
return ts.tv_sec;
}
+/* Helper that converts from C timebase to POSIX clockid_t. */
+static inline clockid_t
+clock_from_timebase (int timebase)
+{
+ verify (TIME_UTC - 1 == CLOCK_REALTIME);
+ verify (TIME_MONOTONIC - 1 == CLOCK_MONOTONIC);
+ verify (TIME_ACTIVE - 1 == CLOCK_PROCESS_CPUTIME_ID);
+ verify (TIME_THREAD_ACTIVE - 1 == CLOCK_THREAD_CPUTIME_ID);
+ return timebase - 1;
+}
+
#define NSEC_PER_SEC 1000000000L /* Nanoseconds per second. */
#define USEC_PER_SEC 1000000L /* Microseconds per second. */
#define NSEC_PER_USEC 1000L /* Nanoseconds per microsecond. */
Store into @code{*@var{ts}} the current time according to the @w{ISO
C} time @var{base}.
+The base @code{TIME_UTC} returns the time since the epoch. It corresponds
+to @code{CLOCK_REALTIME}.
+
+The base @code{TIME_MONOTONIC} returns a monotonically nondecreasing time since
+an unspecified point in the past that may change if the system is rebooted or
+suspended. It corresponds to @code{CLOCK_MONOTONIC}.
+
+The base @code{TIME_ACTIVE} returns the CPU time consumed by the process
+(including all threads). It corresponds to @code{CLOCK_PROCESS_CPUTIME_ID}.
+
+The base @code{TIME_THREAD_ACTIVE} returns the CPU time consumed by the
+calling thread. It corresponds to @code{CLOCK_THREAD_CPUTIME_ID}.
+
The return value is @var{base} on success and @code{0} on failure.
@end deftypefun
int
__timespec_get64 (struct __timespec64 *ts, int base)
{
- if (base == TIME_UTC)
- {
- __clock_gettime64 (CLOCK_REALTIME, ts);
- return base;
- }
- return 0;
+ return __clock_gettime64 (clock_from_timebase (base), ts) == 0 ? base : 0;
}
#if __TIMESIZE != 64
ret = __timespec_get64 (&tp64, base);
- if (ret == TIME_UTC)
+ if (ret != 0)
{
if (! in_time_t_range (tp64.tv_sec))
{
int
__timespec_getres64 (struct __timespec64 *ts, int base)
{
- if (base == TIME_UTC)
- {
- __clock_getres64 (CLOCK_REALTIME, ts);
- return base;
- }
- return 0;
+ return __clock_getres64 (clock_from_timebase (base), ts) == 0 ? base : 0;
}
#if __TIMESIZE != 64
struct __timespec64 tp64;
ret = __timespec_getres64 (&tp64, base);
-
- if (ret == TIME_UTC && ts != NULL)
+ if (ret != 0 && ts != NULL)
*ts = valid_timespec64_to_timespec (tp64);
return ret;
/* Time base values for timespec_get. */
# define TIME_UTC 1
#endif
+#if __GLIBC_USE (ISOC23)
+# define TIME_MONOTONIC 2
+# define TIME_ACTIVE 3
+# define TIME_THREAD_ACTIVE 4
+#endif
__BEGIN_DECLS
int
timespec_get (struct timespec *ts, int base)
{
- if (base == TIME_UTC)
- {
- __clock_gettime (CLOCK_REALTIME, ts);
- return base;
- }
- return 0;
+ return __clock_gettime (clock_from_timebase (base), ts) == 0 ? base : 0;
}
int
timespec_getres (struct timespec *ts, int base)
{
- if (base == TIME_UTC)
- {
- __clock_getres (CLOCK_REALTIME, ts);
- return base;
- }
- return 0;
+ return __clock_getres (clock_from_timebase (base), ts) == 0 ? base : 0;
}
#include <time.h>
#include <support/check.h>
+static void
+test_timespec_get (int timebase)
+{
+ struct timespec ts;
+ TEST_COMPARE (timespec_get (&ts, timebase), timebase);
+ TEST_VERIFY (ts.tv_nsec >= 0);
+ TEST_VERIFY (ts.tv_nsec < 1000000000);
+}
+
static int
do_test (void)
{
- {
- struct timespec ts;
- TEST_COMPARE (timespec_get (&ts, 0), 0);
- }
-
- {
- struct timespec ts;
- TEST_COMPARE (timespec_get (&ts, TIME_UTC), TIME_UTC);
- TEST_VERIFY (ts.tv_nsec >= 0);
- TEST_VERIFY (ts.tv_nsec < 1000000000);
- }
+ test_timespec_get (TIME_UTC);
+ test_timespec_get (TIME_MONOTONIC);
+ test_timespec_get (TIME_ACTIVE);
+ test_timespec_get (TIME_THREAD_ACTIVE);
return 0;
}
#include <time.h>
#include <support/check.h>
+static void
+test_timespec_getres (int clockid, int timebase)
+{
+ struct timespec ts;
+ TEST_COMPARE (timespec_getres (&ts, TIME_UTC), TIME_UTC);
+ /* Expect all supported systems to support 'timebase' with
+ resolution better than one second. */
+ TEST_VERIFY (ts.tv_sec == 0);
+ TEST_VERIFY (ts.tv_nsec > 0);
+ TEST_VERIFY (ts.tv_nsec < 1000000000);
+ /* Expect the resolution to be the same as that reported for
+ 'clockid' with clock_getres. */
+ struct timespec cts;
+ TEST_COMPARE (clock_getres (CLOCK_REALTIME, &cts), 0);
+ TEST_COMPARE (ts.tv_sec, cts.tv_sec);
+ TEST_COMPARE (ts.tv_nsec, cts.tv_nsec);
+}
+
static int
do_test (void)
{
{
struct timespec ts;
+ /* Invalid timebase. */
TEST_COMPARE (timespec_getres (&ts, 0), 0);
+ /* Invalid timespec. */
TEST_COMPARE (timespec_getres (NULL, 0), 0);
}
- {
- struct timespec ts;
- TEST_COMPARE (timespec_getres (&ts, TIME_UTC), TIME_UTC);
- /* Expect all supported systems to support TIME_UTC with
- resolution better than one second. */
- TEST_VERIFY (ts.tv_sec == 0);
- TEST_VERIFY (ts.tv_nsec > 0);
- TEST_VERIFY (ts.tv_nsec < 1000000000);
- TEST_COMPARE (timespec_getres (NULL, TIME_UTC), TIME_UTC);
- /* Expect the resolution to be the same as that reported for
- CLOCK_REALTIME with clock_getres. */
- struct timespec cts;
- TEST_COMPARE (clock_getres (CLOCK_REALTIME, &cts), 0);
- TEST_COMPARE (ts.tv_sec, cts.tv_sec);
- TEST_COMPARE (ts.tv_nsec, cts.tv_nsec);
- }
+ test_timespec_getres (CLOCK_REALTIME, TIME_UTC);
+ test_timespec_getres (CLOCK_MONOTONIC, TIME_MONOTONIC);
+ test_timespec_getres (CLOCK_PROCESS_CPUTIME_ID, TIME_ACTIVE);
+ test_timespec_getres (CLOCK_THREAD_CPUTIME_ID, TIME_THREAD_ACTIVE);
return 0;
}