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:
@@ -1282,7 +1282,6 @@ endforeach
|
|||||||
functions_to_detect = {
|
functions_to_detect = {
|
||||||
'strtof': '',
|
'strtof': '',
|
||||||
'mkostemp': '',
|
'mkostemp': '',
|
||||||
'timespec_get': '#include <time.h>',
|
|
||||||
'memfd_create': '',
|
'memfd_create': '',
|
||||||
'random_r': '',
|
'random_r': '',
|
||||||
'flock': '',
|
'flock': '',
|
||||||
|
@@ -30,14 +30,24 @@
|
|||||||
|
|
||||||
#include "c11/time.h"
|
#include "c11/time.h"
|
||||||
|
|
||||||
#ifndef HAVE_TIMESPEC_GET
|
#ifdef _TIMESPEC_GET_NEED_IMPL
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(HAVE_PTHREAD)
|
#if defined(_WIN32) && !defined(HAVE_PTHREAD)
|
||||||
|
|
||||||
|
#include "c11/threads.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
static LARGE_INTEGER frequency;
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
c23_timespec_get_init(void)
|
||||||
|
{
|
||||||
|
QueryPerformanceFrequency(&frequency);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
timespec_get(struct timespec *ts, int base)
|
c23_timespec_get(struct timespec *ts, int base)
|
||||||
{
|
{
|
||||||
/* difference between 1970 and 1601 */
|
/* difference between 1970 and 1601 */
|
||||||
#define _TIMESPEC_IMPL_UNIX_EPOCH_IN_TICKS 116444736000000000ull
|
#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_sec = ticks / _TIMESPEC_IMPL_TICKS_PER_SECONDS;
|
||||||
ts->tv_nsec = (ticks % _TIMESPEC_IMPL_TICKS_PER_SECONDS) * 100;
|
ts->tv_nsec = (ticks % _TIMESPEC_IMPL_TICKS_PER_SECONDS) * 100;
|
||||||
return base;
|
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;
|
return 0;
|
||||||
#undef _TIMESPEC_IMPL_UNIX_EPOCH_IN_TICKS
|
#undef _TIMESPEC_IMPL_UNIX_EPOCH_IN_TICKS
|
||||||
@@ -65,14 +94,42 @@ timespec_get(struct timespec *ts, int base)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int
|
int c23_timespec_get(struct timespec *ts, int base)
|
||||||
timespec_get(struct timespec *ts, int base)
|
|
||||||
{
|
{
|
||||||
if (!ts)
|
if (!ts)
|
||||||
return 0;
|
return 0;
|
||||||
if (base == TIME_UTC) {
|
switch (base)
|
||||||
clock_gettime(CLOCK_REALTIME, ts);
|
{
|
||||||
return 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,31 @@
|
|||||||
|
|
||||||
/*---------------------------- macros ---------------------------*/
|
/*---------------------------- 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
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -37,22 +60,22 @@ struct timespec
|
|||||||
|
|
||||||
/*-------------------------- functions --------------------------*/
|
/*-------------------------- functions --------------------------*/
|
||||||
|
|
||||||
#if !defined(HAVE_TIMESPEC_GET)
|
#if defined(_TIMESPEC_GET_NEED_IMPL)
|
||||||
#define _HAVE_TIMESPEC_GET_NEED_DECL
|
#define _TIMESPEC_GET_NEED_DECL
|
||||||
#elif defined(__APPLE__) && defined(__cplusplus) && (__cplusplus < 201703L)
|
#elif defined(__APPLE__) && defined(__cplusplus) && (__cplusplus < 201703L)
|
||||||
/* On macOS, the guard for declaration of timespec_get is by
|
/* On macOS, the guard for declaration of timespec_get is by
|
||||||
* (defined(__cplusplus) && __cplusplus >= 201703L),
|
* (defined(__cplusplus) && __cplusplus >= 201703L),
|
||||||
* fix the declaration for C++14 and lower here
|
* fix the declaration for C++14 and lower here
|
||||||
*/
|
*/
|
||||||
#define _HAVE_TIMESPEC_GET_NEED_DECL
|
#define _TIMESPEC_GET_NEED_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _HAVE_TIMESPEC_GET_NEED_DECL
|
#ifdef _TIMESPEC_GET_NEED_DECL
|
||||||
/*-------------------- 7.25.7 Time functions --------------------*/
|
/*-------------------- 7.25.7 Time functions --------------------*/
|
||||||
// 7.25.6.1
|
// 7.25.6.1
|
||||||
int
|
int
|
||||||
timespec_get(struct timespec *ts, int base);
|
timespec_get(struct timespec *ts, int base);
|
||||||
#undef _HAVE_TIMESPEC_GET_NEED_DECL
|
#undef _TIMESPEC_GET_NEED_DECL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Reference in New Issue
Block a user