diff options
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | luasystem-0.1.1-0.rockspec | 12 | ||||
-rw-r--r-- | luasystem-scm-0.rockspec | 12 | ||||
-rw-r--r-- | spec/time_spec.lua | 11 | ||||
-rw-r--r-- | src/Makefile | 26 | ||||
-rw-r--r-- | src/time.c | 40 | ||||
-rw-r--r-- | src/time_osx.h | 66 |
8 files changed, 173 insertions, 10 deletions
@@ -7,6 +7,21 @@ | |||
7 | # install-all install for lua51 lua52 lua53 | 7 | # install-all install for lua51 lua52 lua53 |
8 | # print print the build settings | 8 | # print print the build settings |
9 | 9 | ||
10 | ifeq ($(origin PLAT),undefined) | ||
11 | UNAME_S:=$(shell uname -s) | ||
12 | ifeq ($(UNAME_S),Linux) | ||
13 | PLAT=linux | ||
14 | endif | ||
15 | ifeq ($(UNAME_S),Darwin) | ||
16 | PLAT=macosx | ||
17 | endif | ||
18 | ifeq ($(UNAME_S),FreeBSD) | ||
19 | PLAT=freebsd | ||
20 | endif | ||
21 | ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW) | ||
22 | PLAT=mingw | ||
23 | endif | ||
24 | endif | ||
10 | PLAT?= linux | 25 | PLAT?= linux |
11 | PLATS= macosx linux win32 mingw freebsd | 26 | PLATS= macosx linux win32 mingw freebsd |
12 | 27 | ||
@@ -9,6 +9,7 @@ Supports Lua >= 5.1 and luajit >= 2.0.0. | |||
9 | 9 | ||
10 | Currently the following functions are supported: | 10 | Currently the following functions are supported: |
11 | * gettime | 11 | * gettime |
12 | * monotime | ||
12 | * sleep | 13 | * sleep |
13 | 14 | ||
14 | License | 15 | License |
diff --git a/luasystem-0.1.1-0.rockspec b/luasystem-0.1.1-0.rockspec index 40c8b74..9c5f88d 100644 --- a/luasystem-0.1.1-0.rockspec +++ b/luasystem-0.1.1-0.rockspec | |||
@@ -18,16 +18,25 @@ dependencies = { | |||
18 | 18 | ||
19 | local function make_platform(plat) | 19 | local function make_platform(plat) |
20 | local defines = { | 20 | local defines = { |
21 | linux = { }, | ||
22 | unix = { }, | ||
23 | macosx = { }, | ||
24 | win32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" }, | ||
25 | mingw32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" }, | ||
26 | } | ||
27 | local libraries = { | ||
28 | linux = { "rt" }, | ||
21 | unix = { }, | 29 | unix = { }, |
22 | macosx = { }, | 30 | macosx = { }, |
23 | win32 = { }, | 31 | win32 = { }, |
24 | mingw32 = { "WINVER=0x0501" }, | 32 | mingw32 = { }, |
25 | } | 33 | } |
26 | return { | 34 | return { |
27 | modules = { | 35 | modules = { |
28 | ['system.core'] = { | 36 | ['system.core'] = { |
29 | sources = { 'src/core.c', 'src/compat.c', 'src/time.c', }, | 37 | sources = { 'src/core.c', 'src/compat.c', 'src/time.c', }, |
30 | defines = defines[plat], | 38 | defines = defines[plat], |
39 | libraries = libraries[plat], | ||
31 | }, | 40 | }, |
32 | }, | 41 | }, |
33 | } | 42 | } |
@@ -36,6 +45,7 @@ end | |||
36 | build = { | 45 | build = { |
37 | type = 'builtin', | 46 | type = 'builtin', |
38 | platforms = { | 47 | platforms = { |
48 | linux = make_platform('linux'), | ||
39 | unix = make_platform('unix'), | 49 | unix = make_platform('unix'), |
40 | macosx = make_platform('macosx'), | 50 | macosx = make_platform('macosx'), |
41 | win32 = make_platform('win32'), | 51 | win32 = make_platform('win32'), |
diff --git a/luasystem-scm-0.rockspec b/luasystem-scm-0.rockspec index 83f4172..1093ac4 100644 --- a/luasystem-scm-0.rockspec +++ b/luasystem-scm-0.rockspec | |||
@@ -18,16 +18,25 @@ dependencies = { | |||
18 | 18 | ||
19 | local function make_platform(plat) | 19 | local function make_platform(plat) |
20 | local defines = { | 20 | local defines = { |
21 | linux = { }, | ||
22 | unix = { }, | ||
23 | macosx = { }, | ||
24 | win32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" }, | ||
25 | mingw32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" }, | ||
26 | } | ||
27 | local libraries = { | ||
28 | linux = { "rt" }, | ||
21 | unix = { }, | 29 | unix = { }, |
22 | macosx = { }, | 30 | macosx = { }, |
23 | win32 = { }, | 31 | win32 = { }, |
24 | mingw32 = { "WINVER=0x0501" }, | 32 | mingw32 = { }, |
25 | } | 33 | } |
26 | return { | 34 | return { |
27 | modules = { | 35 | modules = { |
28 | ['system.core'] = { | 36 | ['system.core'] = { |
29 | sources = { 'src/core.c', 'src/compat.c', 'src/time.c', }, | 37 | sources = { 'src/core.c', 'src/compat.c', 'src/time.c', }, |
30 | defines = defines[plat], | 38 | defines = defines[plat], |
39 | libraries = libraries[plat], | ||
31 | }, | 40 | }, |
32 | }, | 41 | }, |
33 | } | 42 | } |
@@ -36,6 +45,7 @@ end | |||
36 | build = { | 45 | build = { |
37 | type = 'builtin', | 46 | type = 'builtin', |
38 | platforms = { | 47 | platforms = { |
48 | linux = make_platform('linux'), | ||
39 | unix = make_platform('unix'), | 49 | unix = make_platform('unix'), |
40 | macosx = make_platform('macosx'), | 50 | macosx = make_platform('macosx'), |
41 | win32 = make_platform('win32'), | 51 | win32 = make_platform('win32'), |
diff --git a/spec/time_spec.lua b/spec/time_spec.lua index c9d3d6d..e1b457a 100644 --- a/spec/time_spec.lua +++ b/spec/time_spec.lua | |||
@@ -12,9 +12,20 @@ describe('Test time functions', function() | |||
12 | assert.is_near(expected, avg, 1 + delta) | 12 | assert.is_near(expected, avg, 1 + delta) |
13 | end) | 13 | end) |
14 | 14 | ||
15 | it('monottime returns monotonically increasing time', function() | ||
16 | local starttime = system.monotime() | ||
17 | local endtime = system.monotime() | ||
18 | local delta = endtime - starttime | ||
19 | assert.is_true(starttime > 0) | ||
20 | assert.is_true(delta >= 0) | ||
21 | assert.is_true(system.monotime() - endtime >= 0) | ||
22 | end) | ||
23 | |||
15 | it('sleep will wait for specified amount of time', function() | 24 | it('sleep will wait for specified amount of time', function() |
16 | local starttime = system.gettime() | 25 | local starttime = system.gettime() |
26 | local starttick = system.monotime() | ||
17 | system.sleep(0.5) | 27 | system.sleep(0.5) |
18 | assert.is_near(0.5, system.gettime() - starttime, 0.1) | 28 | assert.is_near(0.5, system.gettime() - starttime, 0.1) |
29 | assert.is_near(0.5, system.monotime() - starttick, 0.1) | ||
19 | end) | 30 | end) |
20 | end) | 31 | end) |
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 */ | ||