c11: Improve timespec_get to support TIME_MONOTONIC TIME_ACTIVE TIME_THREAD_ACTIVE TIME_MONOTONIC_RAW

As c11 already provided timespec_get, to avoid symbol conflict, use c23_timespec_get as the function name
and define timespec_get c23_timespec_get to achieve that

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Acked-by: David Heidelberg <david.heidelberg@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23733>
This commit is contained in:
Yonggang Luo 2023-02-12 00:15:19 +08:00 committed by Marge Bot
parent 785ca13323
commit 66a99f619f
3 changed files with 93 additions and 14 deletions

View File

@ -1282,7 +1282,6 @@ endforeach
functions_to_detect = {
'strtof': '',
'mkostemp': '',
'timespec_get': '#include <time.h>',
'memfd_create': '',
'random_r': '',
'flock': '',

View File

@ -30,14 +30,24 @@
#include "c11/time.h"
#ifndef HAVE_TIMESPEC_GET
#ifdef _TIMESPEC_GET_NEED_IMPL
#if defined(_WIN32) && !defined(HAVE_PTHREAD)
#include "c11/threads.h"
#include <windows.h>
static LARGE_INTEGER frequency;
static
void
c23_timespec_get_init(void)
{
QueryPerformanceFrequency(&frequency);
}
int
timespec_get(struct timespec *ts, int base)
c23_timespec_get(struct timespec *ts, int base)
{
/* difference between 1970 and 1601 */
#define _TIMESPEC_IMPL_UNIX_EPOCH_IN_TICKS 116444736000000000ull
@ -57,6 +67,25 @@ timespec_get(struct timespec *ts, int base)
ts->tv_sec = ticks / _TIMESPEC_IMPL_TICKS_PER_SECONDS;
ts->tv_nsec = (ticks % _TIMESPEC_IMPL_TICKS_PER_SECONDS) * 100;
return base;
} else if (base == TIME_MONOTONIC || base == TIME_MONOTONIC_RAW) {
if (frequency.QuadPart == 0) {
static once_flag once = ONCE_FLAG_INIT;
call_once(&once, c23_timespec_get_init);
}
if (frequency.QuadPart != 0) {
LARGE_INTEGER now;
LONGLONG sec;
LONGLONG nsec;
QueryPerformanceCounter(&now);
sec = now.QuadPart / frequency.QuadPart;
nsec = (now.QuadPart - sec * frequency.QuadPart)
* 1000000000UL / frequency.QuadPart;
ts->tv_sec = (time_t)sec;
ts->tv_nsec = (long)nsec;
return base;
}
/* Otherwise timespec_get with TIME_MONOTONIC or TIME_MONOTONIC_RAW failed */
return 0;
}
return 0;
#undef _TIMESPEC_IMPL_UNIX_EPOCH_IN_TICKS
@ -65,14 +94,42 @@ timespec_get(struct timespec *ts, int base)
#else
int
timespec_get(struct timespec *ts, int base)
int c23_timespec_get(struct timespec *ts, int base)
{
if (!ts)
return 0;
if (base == TIME_UTC) {
clock_gettime(CLOCK_REALTIME, ts);
return base;
switch (base)
{
case TIME_UTC:
if (clock_gettime(CLOCK_REALTIME, ts) == 0)
return base;
break;
#ifdef CLOCK_MONOTONIC
case TIME_MONOTONIC:
if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
return base;
break;
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
case TIME_ACTIVE:
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ts) == 0)
return base;
break;
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
case TIME_THREAD_ACTIVE:
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, ts) == 0)
return base;
break;
#endif
#ifdef CLOCK_MONOTONIC_RAW
case TIME_MONOTONIC_RAW:
if (clock_gettime(CLOCK_MONOTONIC_RAW, ts) == 0)
return base;
break;
#endif
default:
break;
}
return 0;
}

View File

@ -12,8 +12,31 @@
/*---------------------------- macros ---------------------------*/
#ifndef TIME_UTC
/* Refer to https://htmlpreview.github.io/?https://icube-forge.unistra.fr/icps/c23-library/-/raw/main/README.html#time_monotonic-time_active-time_thread_active */
#if defined(TIME_UTC) && \
defined(TIME_MONOTONIC) && \
defined(TIME_ACTIVE) && \
defined(TIME_THREAD_ACTIVE) && \
defined(TIME_MONOTONIC_RAW)
/* all needed time base is implemented */
#else
#define _TIMESPEC_GET_NEED_IMPL
#endif
#ifdef _TIMESPEC_GET_NEED_IMPL
#undef TIME_UTC
#undef TIME_MONOTONIC
#undef TIME_ACTIVE
#undef TIME_THREAD_ACTIVE
#undef TIME_MONOTONIC_RAW
/* c11 */
#define TIME_UTC 1
/* c23 */
#define TIME_MONOTONIC 2
#define TIME_ACTIVE 3
#define TIME_THREAD_ACTIVE 4
#define TIME_MONOTONIC_RAW 5
#define timespec_get c23_timespec_get
#endif
#ifdef __cplusplus
@ -37,22 +60,22 @@ struct timespec
/*-------------------------- functions --------------------------*/
#if !defined(HAVE_TIMESPEC_GET)
#define _HAVE_TIMESPEC_GET_NEED_DECL
#if defined(_TIMESPEC_GET_NEED_IMPL)
#define _TIMESPEC_GET_NEED_DECL
#elif defined(__APPLE__) && defined(__cplusplus) && (__cplusplus < 201703L)
/* On macOS, the guard for declaration of timespec_get is by
* (defined(__cplusplus) && __cplusplus >= 201703L),
* fix the declaration for C++14 and lower here
*/
#define _HAVE_TIMESPEC_GET_NEED_DECL
#define _TIMESPEC_GET_NEED_DECL
#endif
#ifdef _HAVE_TIMESPEC_GET_NEED_DECL
#ifdef _TIMESPEC_GET_NEED_DECL
/*-------------------- 7.25.7 Time functions --------------------*/
// 7.25.6.1
int
timespec_get(struct timespec *ts, int base);
#undef _HAVE_TIMESPEC_GET_NEED_DECL
#undef _TIMESPEC_GET_NEED_DECL
#endif
#ifdef __cplusplus