1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-12 08:30:26 +00:00

Implement janet_gettime() for win32 and macos; need testing

This commit is contained in:
Ico Doornekamp 2023-05-20 12:00:15 +02:00
parent aaf3d08bcd
commit e8e5f66f4c
2 changed files with 55 additions and 30 deletions

View File

@ -1280,8 +1280,8 @@ JANET_CORE_FN(os_time,
JANET_CORE_FN(os_clock, JANET_CORE_FN(os_clock,
"(os/clock &opt source)", "(os/clock &opt source)",
"Return the number of whole + fractional seconds of the requested clock source.\n\n" "Return the number of whole + fractional seconds of the requested clock source.\n\n"
"The `source` argument is the identifier of the particular clock source to use, when not " "The `source` argument selects the clock source to use, when not specified the default "
"specified the default is `:realtime`:\n" "is `:realtime`:\n"
"- :realtime: Return the real (i.e., wall-clock) time. This clock is affected by discontinuous " "- :realtime: Return the real (i.e., wall-clock) time. This clock is affected by discontinuous "
" jumps in the system time\n" " jumps in the system time\n"
"- :monotonic: Return the number of whole + fractional seconds since some fixed point in " "- :monotonic: Return the number of whole + fractional seconds since some fixed point in "
@ -1299,7 +1299,7 @@ JANET_CORE_FN(os_clock,
} else if (janet_cstrcmp(sourcestr, "cputime") == 0) { } else if (janet_cstrcmp(sourcestr, "cputime") == 0) {
source = JANET_TIME_CPUTIME; source = JANET_TIME_CPUTIME;
} else { } else {
janet_panicf("expected :real-time, :monotonic, or :cputime, got %v", argv[0]); janet_panicf("expected :realtime, :monotonic, or :cputime, got %v", argv[0]);
} }
} }
struct timespec tv; struct timespec tv;

View File

@ -875,7 +875,9 @@ int32_t janet_sorted_keys(const JanetKV *dict, int32_t cap, int32_t *index_buffe
/* Clock shims for various platforms */ /* Clock shims for various platforms */
#ifdef JANET_GETTIME #ifdef JANET_GETTIME
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
int janet_gettime(struct timespec *spec) { #include <profileapi.h>
int janet_gettime(struct timespec *spec, enum JanetTimeSource source) {
if (source == JANET_TIME_REALTIME) {
FILETIME ftime; FILETIME ftime;
GetSystemTimeAsFileTime(&ftime); GetSystemTimeAsFileTime(&ftime);
int64_t wintime = (int64_t)(ftime.dwLowDateTime) | ((int64_t)(ftime.dwHighDateTime) << 32); int64_t wintime = (int64_t)(ftime.dwLowDateTime) | ((int64_t)(ftime.dwHighDateTime) << 32);
@ -884,13 +886,26 @@ int janet_gettime(struct timespec *spec) {
spec->tv_sec = wintime / 10000000LL; spec->tv_sec = wintime / 10000000LL;
/* Resolution is 100 nanoseconds. */ /* Resolution is 100 nanoseconds. */
spec->tv_nsec = wintime % 10000000LL * 100; spec->tv_nsec = wintime % 10000000LL * 100;
} else if (source == JANET_TIME_MONOTONIC) {
LARGE_INTEGER count;
LARGE_INTEGER perf_freq;
QueryPerformanceCounter(&count);
QueryPerformanceFrequency(&perf_freq);
spec->tv_sec = count.QuadPart / perf_freq.QuadPart;
spec->tv_nsec = (count.QuadPart % perf_freq.QuadPart) * 1000000000 / perf_freq.QuadPart;
} else if (source == JANET_TIME_CPUTIME) {
float tmp = clock();
spec->tv_sec = tmp / CLOCKS_PER_SEC;
spec->tv_nsec = (tmp - spec->tv_sec * CLOCKS_PER_SEC) * 1e9 / CLOCKS_PER_SEC;
}
return 0; return 0;
} }
/* clock_gettime() wasn't available on Mac until 10.12. */ /* clock_gettime() wasn't available on Mac until 10.12. */
#elif defined(JANET_APPLE) && !defined(MAC_OS_X_VERSION_10_12) #elif defined(JANET_APPLE) && !defined(MAC_OS_X_VERSION_10_12)
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/mach.h> #include <mach/mach.h>
int janet_gettime(struct timespec *spec) { int janet_gettime(struct timespec *spec, enum JanetTimeSource source) {
if (source == JANET_TIME_REALTIME) {
clock_serv_t cclock; clock_serv_t cclock;
mach_timespec_t mts; mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
@ -898,21 +913,31 @@ int janet_gettime(struct timespec *spec) {
mach_port_deallocate(mach_task_self(), cclock); mach_port_deallocate(mach_task_self(), cclock);
spec->tv_sec = mts.tv_sec; spec->tv_sec = mts.tv_sec;
spec->tv_nsec = mts.tv_nsec; spec->tv_nsec = mts.tv_nsec;
} else if (source == JANET_TIME_MONOTONIC) {
clock_serv_t cclock;
int nsecs;
mach_msg_type_number_t count;
host_get_clock_service(mach_host_self(), clock, &cclock);
clock_get_attributes(cclock, CLOCK_GET_TIME_RES, (clock_attr_t)&nsecs, &count);
mach_port_deallocate(mach_task_self(), cclock);
clock_getres(CLOCK_MONOTONIC, spec);
}
if (source == JANET_TIME_CPUTIME) {
clock_t tmp = clock();
spec->tv_sec = tmp;
spec->tv_nsec = (tmp - spec->tv_sec) * 1.0e9;
}
return 0; return 0;
} }
#else #else
int janet_gettime(struct timespec *spec, enum JanetTimeSource source) { int janet_gettime(struct timespec *spec, enum JanetTimeSource source) {
clockid_t cid = JANET_TIME_REALTIME; clockid_t cid = JANET_TIME_REALTIME;
switch (source) { if (source == JANET_TIME_REALTIME) {
case JANET_TIME_REALTIME:
cid = CLOCK_REALTIME; cid = CLOCK_REALTIME;
break; } else if (source == JANET_TIME_MONOTONIC) {
case JANET_TIME_MONOTONIC:
cid = CLOCK_MONOTONIC; cid = CLOCK_MONOTONIC;
break; } else if (source == JANET_TIME_CPUTIME) {
case JANET_TIME_CPUTIME:
cid = CLOCK_PROCESS_CPUTIME_ID; cid = CLOCK_PROCESS_CPUTIME_ID;
break;
} }
return clock_gettime(cid, spec); return clock_gettime(cid, spec);
} }