mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-05 00:02:41 +03:00
time: Add TIME_MONOTONIC, TIME_ACTIVE, and TIME_THREAD_ACTIVE
The TIME_MONOTONIC maps to POSIX's CLOCK_MONOTONIC, TIME_ACTIVE to CLOCK_PROCESS_CPUTIME_ID, and TIME_THREAD_ACTIVE to CLOCK_THREAD_CPUTIME_ID. No Linux specific timer are added as extension. Co-authored-by: Yonggang Luo <luoyonggang@gmail.com> Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
This commit is contained in:
3
NEWS
3
NEWS
@@ -46,6 +46,9 @@ Major new features:
|
|||||||
lgammaf/lgammaf_r, log10f, sinhf, sqrtf, tgammaf, y0/j0, y1/j1, and yn/jn
|
lgammaf/lgammaf_r, log10f, sinhf, sqrtf, tgammaf, y0/j0, y1/j1, and yn/jn
|
||||||
were moved to compat symbols, allowing improvements in performance.
|
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:
|
Deprecated and removed features, and other changes affecting compatibility:
|
||||||
|
|
||||||
* Support for dumped heaps has been removed - malloc_set_state() now always
|
* Support for dumped heaps has been removed - malloc_set_state() now always
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
# include <time-clockid.h>
|
# include <time-clockid.h>
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
# include <verify.h>
|
||||||
|
|
||||||
extern __typeof (strftime_l) __strftime_l;
|
extern __typeof (strftime_l) __strftime_l;
|
||||||
libc_hidden_proto (__strftime_l)
|
libc_hidden_proto (__strftime_l)
|
||||||
@@ -536,6 +537,17 @@ time64_now (void)
|
|||||||
return ts.tv_sec;
|
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 NSEC_PER_SEC 1000000000L /* Nanoseconds per second. */
|
||||||
#define USEC_PER_SEC 1000000L /* Microseconds per second. */
|
#define USEC_PER_SEC 1000000L /* Microseconds per second. */
|
||||||
#define NSEC_PER_USEC 1000L /* Nanoseconds per microsecond. */
|
#define NSEC_PER_USEC 1000L /* Nanoseconds per microsecond. */
|
||||||
|
|||||||
@@ -629,6 +629,19 @@ Systems may support more than just this @w{ISO C} clock.
|
|||||||
Store into @code{*@var{ts}} the current time according to the @w{ISO
|
Store into @code{*@var{ts}} the current time according to the @w{ISO
|
||||||
C} time @var{base}.
|
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.
|
The return value is @var{base} on success and @code{0} on failure.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,7 @@
|
|||||||
int
|
int
|
||||||
__timespec_get64 (struct __timespec64 *ts, int base)
|
__timespec_get64 (struct __timespec64 *ts, int base)
|
||||||
{
|
{
|
||||||
if (base == TIME_UTC)
|
return __clock_gettime64 (clock_from_timebase (base), ts) == 0 ? base : 0;
|
||||||
{
|
|
||||||
__clock_gettime64 (CLOCK_REALTIME, ts);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __TIMESIZE != 64
|
#if __TIMESIZE != 64
|
||||||
@@ -42,7 +37,7 @@ __timespec_get (struct timespec *ts, int base)
|
|||||||
|
|
||||||
ret = __timespec_get64 (&tp64, base);
|
ret = __timespec_get64 (&tp64, base);
|
||||||
|
|
||||||
if (ret == TIME_UTC)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
if (! in_time_t_range (tp64.tv_sec))
|
if (! in_time_t_range (tp64.tv_sec))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,12 +22,7 @@
|
|||||||
int
|
int
|
||||||
__timespec_getres64 (struct __timespec64 *ts, int base)
|
__timespec_getres64 (struct __timespec64 *ts, int base)
|
||||||
{
|
{
|
||||||
if (base == TIME_UTC)
|
return __clock_getres64 (clock_from_timebase (base), ts) == 0 ? base : 0;
|
||||||
{
|
|
||||||
__clock_getres64 (CLOCK_REALTIME, ts);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __TIMESIZE != 64
|
#if __TIMESIZE != 64
|
||||||
@@ -40,8 +35,7 @@ __timespec_getres (struct timespec *ts, int base)
|
|||||||
struct __timespec64 tp64;
|
struct __timespec64 tp64;
|
||||||
|
|
||||||
ret = __timespec_getres64 (&tp64, base);
|
ret = __timespec_getres64 (&tp64, base);
|
||||||
|
if (ret != 0 && ts != NULL)
|
||||||
if (ret == TIME_UTC && ts != NULL)
|
|
||||||
*ts = valid_timespec64_to_timespec (tp64);
|
*ts = valid_timespec64_to_timespec (tp64);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ typedef __pid_t pid_t;
|
|||||||
/* Time base values for timespec_get. */
|
/* Time base values for timespec_get. */
|
||||||
# define TIME_UTC 1
|
# define TIME_UTC 1
|
||||||
#endif
|
#endif
|
||||||
|
#if __GLIBC_USE (ISOC23)
|
||||||
|
# define TIME_MONOTONIC 2
|
||||||
|
# define TIME_ACTIVE 3
|
||||||
|
# define TIME_THREAD_ACTIVE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,5 @@
|
|||||||
int
|
int
|
||||||
timespec_get (struct timespec *ts, int base)
|
timespec_get (struct timespec *ts, int base)
|
||||||
{
|
{
|
||||||
if (base == TIME_UTC)
|
return __clock_gettime (clock_from_timebase (base), ts) == 0 ? base : 0;
|
||||||
{
|
|
||||||
__clock_gettime (CLOCK_REALTIME, ts);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,10 +23,5 @@
|
|||||||
int
|
int
|
||||||
timespec_getres (struct timespec *ts, int base)
|
timespec_getres (struct timespec *ts, int base)
|
||||||
{
|
{
|
||||||
if (base == TIME_UTC)
|
return __clock_getres (clock_from_timebase (base), ts) == 0 ? base : 0;
|
||||||
{
|
|
||||||
__clock_getres (CLOCK_REALTIME, ts);
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,23 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <support/check.h>
|
#include <support/check.h>
|
||||||
|
|
||||||
static int
|
static void
|
||||||
do_test (void)
|
test_timespec_get (int timebase)
|
||||||
{
|
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
TEST_COMPARE (timespec_get (&ts, 0), 0);
|
TEST_COMPARE (timespec_get (&ts, timebase), timebase);
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
TEST_COMPARE (timespec_get (&ts, TIME_UTC), TIME_UTC);
|
|
||||||
TEST_VERIFY (ts.tv_nsec >= 0);
|
TEST_VERIFY (ts.tv_nsec >= 0);
|
||||||
TEST_VERIFY (ts.tv_nsec < 1000000000);
|
TEST_VERIFY (ts.tv_nsec < 1000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
test_timespec_get (TIME_UTC);
|
||||||
|
test_timespec_get (TIME_MONOTONIC);
|
||||||
|
test_timespec_get (TIME_ACTIVE);
|
||||||
|
test_timespec_get (TIME_THREAD_ACTIVE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,32 +19,40 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <support/check.h>
|
#include <support/check.h>
|
||||||
|
|
||||||
static int
|
static void
|
||||||
do_test (void)
|
test_timespec_getres (int clockid, int timebase)
|
||||||
{
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
TEST_COMPARE (timespec_getres (&ts, 0), 0);
|
|
||||||
TEST_COMPARE (timespec_getres (NULL, 0), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
TEST_COMPARE (timespec_getres (&ts, TIME_UTC), TIME_UTC);
|
TEST_COMPARE (timespec_getres (&ts, TIME_UTC), TIME_UTC);
|
||||||
/* Expect all supported systems to support TIME_UTC with
|
/* Expect all supported systems to support 'timebase' with
|
||||||
resolution better than one second. */
|
resolution better than one second. */
|
||||||
TEST_VERIFY (ts.tv_sec == 0);
|
TEST_VERIFY (ts.tv_sec == 0);
|
||||||
TEST_VERIFY (ts.tv_nsec > 0);
|
TEST_VERIFY (ts.tv_nsec > 0);
|
||||||
TEST_VERIFY (ts.tv_nsec < 1000000000);
|
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
|
/* Expect the resolution to be the same as that reported for
|
||||||
CLOCK_REALTIME with clock_getres. */
|
'clockid' with clock_getres. */
|
||||||
struct timespec cts;
|
struct timespec cts;
|
||||||
TEST_COMPARE (clock_getres (CLOCK_REALTIME, &cts), 0);
|
TEST_COMPARE (clock_getres (CLOCK_REALTIME, &cts), 0);
|
||||||
TEST_COMPARE (ts.tv_sec, cts.tv_sec);
|
TEST_COMPARE (ts.tv_sec, cts.tv_sec);
|
||||||
TEST_COMPARE (ts.tv_nsec, cts.tv_nsec);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user