Skip to content

Commit

Permalink
Fix cnex to deal with certain Linux variations on time/clock handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
gitlarryf authored and ghewgill committed Jan 30, 2024
1 parent 5406111 commit acd44b1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
7 changes: 7 additions & 0 deletions exec/cnex/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
lib/runtime_posix.c
)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
# Not all flavors of Linx will have the function clock_gettime(), and some have it in a different include.
# See exec/cnex/lib/time_linux.c for more information.
include(CheckSymbolExists)
check_symbol_exists(clock_gettime "time.h;sys/time.h" HAVE_CLOCK_GETTIME)
if(HAVE_CLOCK_GETTIME)
add_definitions(-DHAVE_CLOCK_GETTIME)
endif()
set(platform_cnex
rtl_posix.c
lib/file_posix.c
Expand Down
17 changes: 17 additions & 0 deletions exec/cnex/lib/time_linux.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#ifdef HAVE_CLOCK_GETTIME
#include <time.h>
#else
#include <sys/time.h>
#endif

#include "cell.h"
#include "exec.h"
Expand All @@ -9,17 +13,30 @@


static Number NANOSECONDS_PER_SECOND;
static Number MICROSECONDS_PER_SECOND;

void time_initModule()
{
NANOSECONDS_PER_SECOND = number_from_uint64(1000000000LL);
MICROSECONDS_PER_SECOND = number_from_uint64(1000000LL);
}

void time_tick(TExecutor *exec)
{
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;

clock_gettime(CLOCK_MONOTONIC, &ts);

push(exec->stack, cell_fromNumber(number_add(number_from_uint64(ts.tv_sec), number_divide(number_from_uint64(ts.tv_nsec), NANOSECONDS_PER_SECOND))));
#else
// Not all Linux distros will have clock_gettime(), so we'll resort to gettimeofday() in those cases. Note the difference between
// between timespec and timeval structures as well; where timeval has a tv_usec (Microseconds), vs. tv_nsec (Nanoseconds) member.
// This means we have to divide by 1,000,000, not 1,000,000,000, when using timeval and gettimeofday().
struct timeval tv;

gettimeofday(&tv, NULL);

push(exec->stack, cell_fromNumber(number_add(number_from_uint64(tv.tv_sec), number_divide(number_from_uint64(tv.tv_usec), MICROSECONDS_PER_SECOND))));
#endif
}

0 comments on commit acd44b1

Please sign in to comment.