diff options
| author | Oscar Lim <olim@ucla.edu> | 2016-05-07 14:37:25 -0700 |
|---|---|---|
| committer | Oscar Lim <olim@ucla.edu> | 2016-05-08 16:01:40 -0700 |
| commit | 8c1a0fca53bf11f2b7ce708c8c5bdb05e5a55701 (patch) | |
| tree | 9624af38c4ba35de244da2281e08049589140e20 /src | |
| parent | 040d7066649ddfcb72424b1cb70d6ad00ea84a21 (diff) | |
| download | luasystem-8c1a0fca53bf11f2b7ce708c8c5bdb05e5a55701.tar.gz luasystem-8c1a0fca53bf11f2b7ce708c8c5bdb05e5a55701.tar.bz2 luasystem-8c1a0fca53bf11f2b7ce708c8c5bdb05e5a55701.zip | |
Support for monotime
Provide `monotime` function with at least 1 millisecond resolution.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 26 | ||||
| -rw-r--r-- | src/time.c | 40 | ||||
| -rw-r--r-- | src/time_osx.h | 66 |
3 files changed, 124 insertions, 8 deletions
diff --git a/src/Makefile b/src/Makefile index 25f468d..10fc31a 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -4,13 +4,28 @@ | |||
| 4 | # environment. | 4 | # environment. |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | # PLAT: linux macosx win32 mingw | 7 | # PLAT: linux macosx win32 mingw freebsd |
| 8 | # platform to build for | 8 | # platform to build for |
| 9 | ifeq ($(origin PLAT),undefined) | ||
| 10 | UNAME_S:=$(shell uname -s) | ||
| 11 | ifeq ($(UNAME_S),Linux) | ||
| 12 | PLAT=linux | ||
| 13 | endif | ||
| 14 | ifeq ($(UNAME_S),Darwin) | ||
| 15 | PLAT=macosx | ||
| 16 | endif | ||
| 17 | ifeq ($(UNAME_S),FreeBSD) | ||
| 18 | PLAT=freebsd | ||
| 19 | endif | ||
| 20 | ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW) | ||
| 21 | PLAT=mingw | ||
| 22 | endif | ||
| 23 | endif | ||
| 9 | PLAT?=linux | 24 | PLAT?=linux |
| 10 | 25 | ||
| 11 | # LUA_VERSION: 5.1 5.2 5.3 | 26 | # LUA_VERSION: 5.1 5.2 5.3 |
| 12 | # lua version to build against | 27 | # lua version to build against |
| 13 | LUA_VERSION?=5.1 | 28 | LUA_VERSION?=$(basename $(word 2,$(shell lua -v))) |
| 14 | 29 | ||
| 15 | # MYCFLAGS: to be set by user if needed | 30 | # MYCFLAGS: to be set by user if needed |
| 16 | MYCFLAGS= | 31 | MYCFLAGS= |
| @@ -130,7 +145,7 @@ CC_linux=gcc | |||
| 130 | DEF_linux= | 145 | DEF_linux= |
| 131 | CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ | 146 | CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ |
| 132 | -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden | 147 | -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden |
| 133 | LDFLAGS_linux=-O -shared -fpic -o | 148 | LDFLAGS_linux=-lrt -O -shared -fpic -o |
| 134 | LD_linux=gcc | 149 | LD_linux=gcc |
| 135 | 150 | ||
| 136 | #------ | 151 | #------ |
| @@ -151,7 +166,7 @@ LD_freebsd=gcc | |||
| 151 | SO_mingw=dll | 166 | SO_mingw=dll |
| 152 | O_mingw=o | 167 | O_mingw=o |
| 153 | CC_mingw=gcc | 168 | CC_mingw=gcc |
| 154 | DEF_mingw=-DWINVER=0x0501 | 169 | DEF_mingw=-DWINVER=0x0600 -D_WIN32_WINNT=0x0600 |
| 155 | CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ | 170 | CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ |
| 156 | -fvisibility=hidden | 171 | -fvisibility=hidden |
| 157 | LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o | 172 | LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o |
| @@ -165,7 +180,8 @@ SO_win32=dll | |||
| 165 | O_win32=obj | 180 | O_win32=obj |
| 166 | CC_win32=cl | 181 | CC_win32=cl |
| 167 | DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \ | 182 | DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \ |
| 168 | //D "_CRT_SECURE_NO_WARNINGS" //D "_WINDLL" | 183 | //D "_CRT_SECURE_NO_WARNINGS" //D "_WINDLL" \ |
| 184 | //D"WINVER=0x0600" //D"_WIN32_WINNT=0x0600" | ||
| 169 | CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo | 185 | CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo |
| 170 | LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \ | 186 | LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \ |
| 171 | //MANIFEST //MANIFESTFILE:"intermediate.manifest" \ | 187 | //MANIFEST //MANIFESTFILE:"intermediate.manifest" \ |
| @@ -10,6 +10,10 @@ | |||
| 10 | #include <sys/time.h> | 10 | #include <sys/time.h> |
| 11 | #endif | 11 | #endif |
| 12 | 12 | ||
| 13 | #ifdef __APPLE__ | ||
| 14 | #include "time_osx.h" | ||
| 15 | #endif | ||
| 16 | |||
| 13 | #include "compat.h" | 17 | #include "compat.h" |
| 14 | 18 | ||
| 15 | /*------------------------------------------------------------------------- | 19 | /*------------------------------------------------------------------------- |
| @@ -23,7 +27,7 @@ static double time_gettime(void) { | |||
| 23 | double t; | 27 | double t; |
| 24 | GetSystemTimeAsFileTime(&ft); | 28 | GetSystemTimeAsFileTime(&ft); |
| 25 | /* Windows file time (time since January 1, 1601 (UTC)) */ | 29 | /* Windows file time (time since January 1, 1601 (UTC)) */ |
| 26 | t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); | 30 | t = ft.dwLowDateTime*1.0e-7 + ft.dwHighDateTime*(4294967296.0*1.0e-7); |
| 27 | /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ | 31 | /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ |
| 28 | return (t - 11644473600.0); | 32 | return (t - 11644473600.0); |
| 29 | } | 33 | } |
| @@ -32,12 +36,32 @@ static double time_gettime(void) { | |||
| 32 | struct timeval v; | 36 | struct timeval v; |
| 33 | gettimeofday(&v, (struct timezone *) NULL); | 37 | gettimeofday(&v, (struct timezone *) NULL); |
| 34 | /* Unix Epoch time (time since January 1, 1970 (UTC)) */ | 38 | /* Unix Epoch time (time since January 1, 1970 (UTC)) */ |
| 35 | return v.tv_sec + v.tv_usec/1.0e6; | 39 | return v.tv_sec + v.tv_usec*1.0e-6; |
| 36 | } | 40 | } |
| 37 | #endif | 41 | #endif |
| 38 | 42 | ||
| 39 | /*------------------------------------------------------------------------- | 43 | /*------------------------------------------------------------------------- |
| 40 | * Returns the time the system has been up, in secconds. | 44 | * Gets monotonic time in s |
| 45 | * Returns | ||
| 46 | * time in s. | ||
| 47 | *-------------------------------------------------------------------------*/ | ||
| 48 | #ifdef _WIN32 | ||
| 49 | WINBASEAPI ULONGLONG WINAPI GetTickCount64(VOID); | ||
| 50 | |||
| 51 | static double time_monotime(void) { | ||
| 52 | ULONGLONG ms = GetTickCount64(); | ||
| 53 | return ms*1.0e-3; | ||
| 54 | } | ||
| 55 | #else | ||
| 56 | static double time_monotime(void) { | ||
| 57 | struct timespec ts; | ||
| 58 | clock_gettime(CLOCK_MONOTONIC, &ts); | ||
| 59 | return ts.tv_sec + ts.tv_nsec*1.0e-9; | ||
| 60 | } | ||
| 61 | #endif | ||
| 62 | |||
| 63 | /*------------------------------------------------------------------------- | ||
| 64 | * Returns the current system time, 1970 (UTC), in secconds. | ||
| 41 | *-------------------------------------------------------------------------*/ | 65 | *-------------------------------------------------------------------------*/ |
| 42 | static int time_lua_gettime(lua_State *L) | 66 | static int time_lua_gettime(lua_State *L) |
| 43 | { | 67 | { |
| @@ -46,6 +70,15 @@ static int time_lua_gettime(lua_State *L) | |||
| 46 | } | 70 | } |
| 47 | 71 | ||
| 48 | /*------------------------------------------------------------------------- | 72 | /*------------------------------------------------------------------------- |
| 73 | * Returns the monotonic time the system has been up, in secconds. | ||
| 74 | *-------------------------------------------------------------------------*/ | ||
| 75 | static int time_lua_monotime(lua_State *L) | ||
| 76 | { | ||
| 77 | lua_pushnumber(L, time_monotime()); | ||
| 78 | return 1; | ||
| 79 | } | ||
| 80 | |||
| 81 | /*------------------------------------------------------------------------- | ||
| 49 | * Sleep for n seconds. | 82 | * Sleep for n seconds. |
| 50 | *-------------------------------------------------------------------------*/ | 83 | *-------------------------------------------------------------------------*/ |
| 51 | #ifdef _WIN32 | 84 | #ifdef _WIN32 |
| @@ -79,6 +112,7 @@ static int time_lua_sleep(lua_State *L) | |||
| 79 | 112 | ||
| 80 | static luaL_Reg func[] = { | 113 | static luaL_Reg func[] = { |
| 81 | { "gettime", time_lua_gettime }, | 114 | { "gettime", time_lua_gettime }, |
| 115 | { "monotime", time_lua_monotime }, | ||
| 82 | { "sleep", time_lua_sleep }, | 116 | { "sleep", time_lua_sleep }, |
| 83 | { NULL, NULL } | 117 | { NULL, NULL } |
| 84 | }; | 118 | }; |
diff --git a/src/time_osx.h b/src/time_osx.h new file mode 100644 index 0000000..3308318 --- /dev/null +++ b/src/time_osx.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | #ifndef TIME_OSX_H | ||
| 2 | #define TIME_OSX_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * clock_gettime() | ||
| 6 | * | ||
| 7 | * OS X doesn't implement the clock_gettime() POSIX interface, but does | ||
| 8 | * provide a monotonic clock through mach_absolute_time(). On i386 and | ||
| 9 | * x86_64 architectures this clock is in nanosecond units, but not so on | ||
| 10 | * other devices. mach_timebase_info() provides the conversion parameters. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <time.h> /* struct timespec */ | ||
| 15 | #include <errno.h> /* errno EINVAL */ | ||
| 16 | #include <sys/time.h> /* TIMEVAL_TO_TIMESPEC struct timeval gettimeofday(3) */ | ||
| 17 | #include <mach/mach_time.h> /* mach_timebase_info_data_t mach_timebase_info() mach_absolute_time() */ | ||
| 18 | |||
| 19 | |||
| 20 | #define CLOCK_REALTIME 0 | ||
| 21 | #define CLOCK_VIRTUAL 1 | ||
| 22 | #define CLOCK_PROF 2 | ||
| 23 | #define CLOCK_MONOTONIC 3 | ||
| 24 | |||
| 25 | static mach_timebase_info_data_t clock_timebase = { | ||
| 26 | .numer = 1, .denom = 1, | ||
| 27 | }; /* clock_timebase */ | ||
| 28 | |||
| 29 | void clock_gettime_init(void) __attribute__((constructor)); | ||
| 30 | |||
| 31 | void clock_gettime_init(void) { | ||
| 32 | if (mach_timebase_info(&clock_timebase) != KERN_SUCCESS) | ||
| 33 | __builtin_abort(); | ||
| 34 | } /* clock_gettime_init() */ | ||
| 35 | |||
| 36 | static int clock_gettime(int clockid, struct timespec *ts) { | ||
| 37 | switch (clockid) { | ||
| 38 | case CLOCK_REALTIME: { | ||
| 39 | struct timeval tv; | ||
| 40 | |||
| 41 | if (0 != gettimeofday(&tv, 0)) | ||
| 42 | return -1; | ||
| 43 | |||
| 44 | TIMEVAL_TO_TIMESPEC(&tv, ts); | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | case CLOCK_MONOTONIC: { | ||
| 49 | unsigned long long abt; | ||
| 50 | |||
| 51 | abt = mach_absolute_time(); | ||
| 52 | abt = abt * clock_timebase.numer / clock_timebase.denom; | ||
| 53 | |||
| 54 | ts->tv_sec = abt / 1000000000UL; | ||
| 55 | ts->tv_nsec = abt % 1000000000UL; | ||
| 56 | |||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | default: | ||
| 60 | errno = EINVAL; | ||
| 61 | |||
| 62 | return -1; | ||
| 63 | } /* switch() */ | ||
| 64 | } /* clock_gettime() */ | ||
| 65 | |||
| 66 | #endif /* TIME_OSX_H */ | ||
