aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--README.md1
-rw-r--r--luasystem-0.1.1-0.rockspec12
-rw-r--r--luasystem-scm-0.rockspec12
-rw-r--r--spec/time_spec.lua11
-rw-r--r--src/Makefile26
-rw-r--r--src/time.c40
-rw-r--r--src/time_osx.h66
8 files changed, 173 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index 4d83c2a..4f4d685 100644
--- a/Makefile
+++ b/Makefile
@@ -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
10ifeq ($(origin PLAT),undefined)
11UNAME_S:=$(shell uname -s)
12ifeq ($(UNAME_S),Linux)
13 PLAT=linux
14endif
15ifeq ($(UNAME_S),Darwin)
16 PLAT=macosx
17endif
18ifeq ($(UNAME_S),FreeBSD)
19 PLAT=freebsd
20endif
21ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW)
22 PLAT=mingw
23endif
24endif
10PLAT?= linux 25PLAT?= linux
11PLATS= macosx linux win32 mingw freebsd 26PLATS= macosx linux win32 mingw freebsd
12 27
diff --git a/README.md b/README.md
index 240c478..3aac3a1 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@ Supports Lua >= 5.1 and luajit >= 2.0.0.
9 9
10Currently the following functions are supported: 10Currently the following functions are supported:
11* gettime 11* gettime
12* monotime
12* sleep 13* sleep
13 14
14License 15License
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
19local function make_platform(plat) 19local 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
36build = { 45build = {
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
19local function make_platform(plat) 19local 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
36build = { 45build = {
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)
20end) 31end)
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
9ifeq ($(origin PLAT),undefined)
10UNAME_S:=$(shell uname -s)
11ifeq ($(UNAME_S),Linux)
12 PLAT=linux
13endif
14ifeq ($(UNAME_S),Darwin)
15 PLAT=macosx
16endif
17ifeq ($(UNAME_S),FreeBSD)
18 PLAT=freebsd
19endif
20ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW)
21 PLAT=mingw
22endif
23endif
9PLAT?=linux 24PLAT?=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
13LUA_VERSION?=5.1 28LUA_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
16MYCFLAGS= 31MYCFLAGS=
@@ -130,7 +145,7 @@ CC_linux=gcc
130DEF_linux= 145DEF_linux=
131CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ 146CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
132 -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden 147 -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
133LDFLAGS_linux=-O -shared -fpic -o 148LDFLAGS_linux=-lrt -O -shared -fpic -o
134LD_linux=gcc 149LD_linux=gcc
135 150
136#------ 151#------
@@ -151,7 +166,7 @@ LD_freebsd=gcc
151SO_mingw=dll 166SO_mingw=dll
152O_mingw=o 167O_mingw=o
153CC_mingw=gcc 168CC_mingw=gcc
154DEF_mingw=-DWINVER=0x0501 169DEF_mingw=-DWINVER=0x0600 -D_WIN32_WINNT=0x0600
155CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ 170CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \
156 -fvisibility=hidden 171 -fvisibility=hidden
157LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o 172LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o
@@ -165,7 +180,8 @@ SO_win32=dll
165O_win32=obj 180O_win32=obj
166CC_win32=cl 181CC_win32=cl
167DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \ 182DEF_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"
169CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo 185CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo
170LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \ 186LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
171 //MANIFEST //MANIFESTFILE:"intermediate.manifest" \ 187 //MANIFEST //MANIFESTFILE:"intermediate.manifest" \
diff --git a/src/time.c b/src/time.c
index 43d0e35..353f259 100644
--- a/src/time.c
+++ b/src/time.c
@@ -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
49WINBASEAPI ULONGLONG WINAPI GetTickCount64(VOID);
50
51static double time_monotime(void) {
52 ULONGLONG ms = GetTickCount64();
53 return ms*1.0e-3;
54}
55#else
56static 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 *-------------------------------------------------------------------------*/
42static int time_lua_gettime(lua_State *L) 66static 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 *-------------------------------------------------------------------------*/
75static 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
80static luaL_Reg func[] = { 113static 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
25static mach_timebase_info_data_t clock_timebase = {
26 .numer = 1, .denom = 1,
27}; /* clock_timebase */
28
29void clock_gettime_init(void) __attribute__((constructor));
30
31void clock_gettime_init(void) {
32 if (mach_timebase_info(&clock_timebase) != KERN_SUCCESS)
33 __builtin_abort();
34} /* clock_gettime_init() */
35
36static 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 */