summaryrefslogtreecommitdiff
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 @@
# install-all install for lua51 lua52 lua53
# print print the build settings
+ifeq ($(origin PLAT),undefined)
+UNAME_S:=$(shell uname -s)
+ifeq ($(UNAME_S),Linux)
+ PLAT=linux
+endif
+ifeq ($(UNAME_S),Darwin)
+ PLAT=macosx
+endif
+ifeq ($(UNAME_S),FreeBSD)
+ PLAT=freebsd
+endif
+ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW)
+ PLAT=mingw
+endif
+endif
PLAT?= linux
PLATS= macosx linux win32 mingw freebsd
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.
Currently the following functions are supported:
* gettime
+* monotime
* sleep
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 = {
local function make_platform(plat)
local defines = {
+ linux = { },
+ unix = { },
+ macosx = { },
+ win32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
+ mingw32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
+ }
+ local libraries = {
+ linux = { "rt" },
unix = { },
macosx = { },
win32 = { },
- mingw32 = { "WINVER=0x0501" },
+ mingw32 = { },
}
return {
modules = {
['system.core'] = {
sources = { 'src/core.c', 'src/compat.c', 'src/time.c', },
defines = defines[plat],
+ libraries = libraries[plat],
},
},
}
@@ -36,6 +45,7 @@ end
build = {
type = 'builtin',
platforms = {
+ linux = make_platform('linux'),
unix = make_platform('unix'),
macosx = make_platform('macosx'),
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 = {
local function make_platform(plat)
local defines = {
+ linux = { },
+ unix = { },
+ macosx = { },
+ win32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
+ mingw32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
+ }
+ local libraries = {
+ linux = { "rt" },
unix = { },
macosx = { },
win32 = { },
- mingw32 = { "WINVER=0x0501" },
+ mingw32 = { },
}
return {
modules = {
['system.core'] = {
sources = { 'src/core.c', 'src/compat.c', 'src/time.c', },
defines = defines[plat],
+ libraries = libraries[plat],
},
},
}
@@ -36,6 +45,7 @@ end
build = {
type = 'builtin',
platforms = {
+ linux = make_platform('linux'),
unix = make_platform('unix'),
macosx = make_platform('macosx'),
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()
assert.is_near(expected, avg, 1 + delta)
end)
+ it('monottime returns monotonically increasing time', function()
+ local starttime = system.monotime()
+ local endtime = system.monotime()
+ local delta = endtime - starttime
+ assert.is_true(starttime > 0)
+ assert.is_true(delta >= 0)
+ assert.is_true(system.monotime() - endtime >= 0)
+ end)
+
it('sleep will wait for specified amount of time', function()
local starttime = system.gettime()
+ local starttick = system.monotime()
system.sleep(0.5)
assert.is_near(0.5, system.gettime() - starttime, 0.1)
+ assert.is_near(0.5, system.monotime() - starttick, 0.1)
end)
end)
diff --git a/src/Makefile b/src/Makefile
index 25f468d..10fc31a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,13 +4,28 @@
# environment.
#
-# PLAT: linux macosx win32 mingw
+# PLAT: linux macosx win32 mingw freebsd
# platform to build for
+ifeq ($(origin PLAT),undefined)
+UNAME_S:=$(shell uname -s)
+ifeq ($(UNAME_S),Linux)
+ PLAT=linux
+endif
+ifeq ($(UNAME_S),Darwin)
+ PLAT=macosx
+endif
+ifeq ($(UNAME_S),FreeBSD)
+ PLAT=freebsd
+endif
+ifeq ($(patsubst MINGW%,MINGW,$(UNAME_S)),MINGW)
+ PLAT=mingw
+endif
+endif
PLAT?=linux
# LUA_VERSION: 5.1 5.2 5.3
# lua version to build against
-LUA_VERSION?=5.1
+LUA_VERSION?=$(basename $(word 2,$(shell lua -v)))
# MYCFLAGS: to be set by user if needed
MYCFLAGS=
@@ -130,7 +145,7 @@ CC_linux=gcc
DEF_linux=
CFLAGS_linux= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \
-Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden
-LDFLAGS_linux=-O -shared -fpic -o
+LDFLAGS_linux=-lrt -O -shared -fpic -o
LD_linux=gcc
#------
@@ -151,7 +166,7 @@ LD_freebsd=gcc
SO_mingw=dll
O_mingw=o
CC_mingw=gcc
-DEF_mingw=-DWINVER=0x0501
+DEF_mingw=-DWINVER=0x0600 -D_WIN32_WINNT=0x0600
CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \
-fvisibility=hidden
LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o
@@ -165,7 +180,8 @@ SO_win32=dll
O_win32=obj
CC_win32=cl
DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \
- //D "_CRT_SECURE_NO_WARNINGS" //D "_WINDLL"
+ //D "_CRT_SECURE_NO_WARNINGS" //D "_WINDLL" \
+ //D"WINVER=0x0600" //D"_WIN32_WINNT=0x0600"
CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo
LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
//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 @@
#include <sys/time.h>
#endif
+#ifdef __APPLE__
+#include "time_osx.h"
+#endif
+
#include "compat.h"
/*-------------------------------------------------------------------------
@@ -23,7 +27,7 @@ static double time_gettime(void) {
double t;
GetSystemTimeAsFileTime(&ft);
/* Windows file time (time since January 1, 1601 (UTC)) */
- t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
+ t = ft.dwLowDateTime*1.0e-7 + ft.dwHighDateTime*(4294967296.0*1.0e-7);
/* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
return (t - 11644473600.0);
}
@@ -32,12 +36,32 @@ static double time_gettime(void) {
struct timeval v;
gettimeofday(&v, (struct timezone *) NULL);
/* Unix Epoch time (time since January 1, 1970 (UTC)) */
- return v.tv_sec + v.tv_usec/1.0e6;
+ return v.tv_sec + v.tv_usec*1.0e-6;
}
#endif
/*-------------------------------------------------------------------------
- * Returns the time the system has been up, in secconds.
+ * Gets monotonic time in s
+ * Returns
+ * time in s.
+ *-------------------------------------------------------------------------*/
+#ifdef _WIN32
+WINBASEAPI ULONGLONG WINAPI GetTickCount64(VOID);
+
+static double time_monotime(void) {
+ ULONGLONG ms = GetTickCount64();
+ return ms*1.0e-3;
+}
+#else
+static double time_monotime(void) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts.tv_sec + ts.tv_nsec*1.0e-9;
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Returns the current system time, 1970 (UTC), in secconds.
*-------------------------------------------------------------------------*/
static int time_lua_gettime(lua_State *L)
{
@@ -46,6 +70,15 @@ static int time_lua_gettime(lua_State *L)
}
/*-------------------------------------------------------------------------
+ * Returns the monotonic time the system has been up, in secconds.
+ *-------------------------------------------------------------------------*/
+static int time_lua_monotime(lua_State *L)
+{
+ lua_pushnumber(L, time_monotime());
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
* Sleep for n seconds.
*-------------------------------------------------------------------------*/
#ifdef _WIN32
@@ -79,6 +112,7 @@ static int time_lua_sleep(lua_State *L)
static luaL_Reg func[] = {
{ "gettime", time_lua_gettime },
+ { "monotime", time_lua_monotime },
{ "sleep", time_lua_sleep },
{ NULL, NULL }
};
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 @@
+#ifndef TIME_OSX_H
+#define TIME_OSX_H
+
+/*
+ * clock_gettime()
+ *
+ * OS X doesn't implement the clock_gettime() POSIX interface, but does
+ * provide a monotonic clock through mach_absolute_time(). On i386 and
+ * x86_64 architectures this clock is in nanosecond units, but not so on
+ * other devices. mach_timebase_info() provides the conversion parameters.
+ *
+ */
+
+#include <time.h> /* struct timespec */
+#include <errno.h> /* errno EINVAL */
+#include <sys/time.h> /* TIMEVAL_TO_TIMESPEC struct timeval gettimeofday(3) */
+#include <mach/mach_time.h> /* mach_timebase_info_data_t mach_timebase_info() mach_absolute_time() */
+
+
+#define CLOCK_REALTIME 0
+#define CLOCK_VIRTUAL 1
+#define CLOCK_PROF 2
+#define CLOCK_MONOTONIC 3
+
+static mach_timebase_info_data_t clock_timebase = {
+ .numer = 1, .denom = 1,
+}; /* clock_timebase */
+
+void clock_gettime_init(void) __attribute__((constructor));
+
+void clock_gettime_init(void) {
+ if (mach_timebase_info(&clock_timebase) != KERN_SUCCESS)
+ __builtin_abort();
+} /* clock_gettime_init() */
+
+static int clock_gettime(int clockid, struct timespec *ts) {
+ switch (clockid) {
+ case CLOCK_REALTIME: {
+ struct timeval tv;
+
+ if (0 != gettimeofday(&tv, 0))
+ return -1;
+
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+
+ return 0;
+ }
+ case CLOCK_MONOTONIC: {
+ unsigned long long abt;
+
+ abt = mach_absolute_time();
+ abt = abt * clock_timebase.numer / clock_timebase.denom;
+
+ ts->tv_sec = abt / 1000000000UL;
+ ts->tv_nsec = abt % 1000000000UL;
+
+ return 0;
+ }
+ default:
+ errno = EINVAL;
+
+ return -1;
+ } /* switch() */
+} /* clock_gettime() */
+
+#endif /* TIME_OSX_H */