diff options
author | Oscar Lim <olim@ucla.edu> | 2016-01-24 22:53:37 -0800 |
---|---|---|
committer | Oscar Lim <olim@ucla.edu> | 2016-02-10 23:45:49 -0800 |
commit | 7499b422e3f07bf25704cbf7989e845f89697fa8 (patch) | |
tree | 524d8a262a9d61486b858e70c64f8aedbda43095 /src/time.c | |
download | luasystem-7499b422e3f07bf25704cbf7989e845f89697fa8.tar.gz luasystem-7499b422e3f07bf25704cbf7989e845f89697fa8.tar.bz2 luasystem-7499b422e3f07bf25704cbf7989e845f89697fa8.zip |
Support for gettime and sleep functions
Provide `gettime` and `sleep` functions with at least 1 millisecond
resolution.
Diffstat (limited to 'src/time.c')
-rw-r--r-- | src/time.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/time.c b/src/time.c new file mode 100644 index 0000000..3f61001 --- /dev/null +++ b/src/time.c | |||
@@ -0,0 +1,89 @@ | |||
1 | #include <lua.h> | ||
2 | #include <lauxlib.h> | ||
3 | |||
4 | #ifdef _WIN32 | ||
5 | #include <windows.h> | ||
6 | #else | ||
7 | #include <time.h> | ||
8 | #include <sys/time.h> | ||
9 | #endif | ||
10 | |||
11 | #include "compat.h" | ||
12 | |||
13 | /*------------------------------------------------------------------------- | ||
14 | * Gets time in s, relative to January 1, 1970 (UTC) | ||
15 | * Returns | ||
16 | * time in s. | ||
17 | *-------------------------------------------------------------------------*/ | ||
18 | #ifdef _WIN32 | ||
19 | static double time_gettime(void) { | ||
20 | FILETIME ft; | ||
21 | double t; | ||
22 | GetSystemTimeAsFileTime(&ft); | ||
23 | /* Windows file time (time since January 1, 1601 (UTC)) */ | ||
24 | t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); | ||
25 | /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ | ||
26 | return (t - 11644473600.0); | ||
27 | } | ||
28 | #else | ||
29 | static double time_gettime(void) { | ||
30 | struct timeval v; | ||
31 | gettimeofday(&v, (struct timezone *) NULL); | ||
32 | /* Unix Epoch time (time since January 1, 1970 (UTC)) */ | ||
33 | return v.tv_sec + v.tv_usec/1.0e6; | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | /*------------------------------------------------------------------------- | ||
38 | * Returns the time the system has been up, in secconds. | ||
39 | *-------------------------------------------------------------------------*/ | ||
40 | static int time_lua_gettime(lua_State *L) | ||
41 | { | ||
42 | lua_pushnumber(L, time_gettime()); | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | /*------------------------------------------------------------------------- | ||
47 | * Sleep for n seconds. | ||
48 | *-------------------------------------------------------------------------*/ | ||
49 | #ifdef _WIN32 | ||
50 | static int time_lua_sleep(lua_State *L) | ||
51 | { | ||
52 | double n = luaL_checknumber(L, 1); | ||
53 | if (n < 0.0) n = 0.0; | ||
54 | if (n < DBL_MAX/1000.0) n *= 1000.0; | ||
55 | if (n > INT_MAX) n = INT_MAX; | ||
56 | Sleep((int)n); | ||
57 | return 0; | ||
58 | } | ||
59 | #else | ||
60 | static int time_lua_sleep(lua_State *L) | ||
61 | { | ||
62 | double n = luaL_checknumber(L, 1); | ||
63 | struct timespec t, r; | ||
64 | if (n < 0.0) n = 0.0; | ||
65 | if (n > INT_MAX) n = INT_MAX; | ||
66 | t.tv_sec = (int) n; | ||
67 | n -= t.tv_sec; | ||
68 | t.tv_nsec = (int) (n * 1000000000); | ||
69 | if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; | ||
70 | while (nanosleep(&t, &r) != 0) { | ||
71 | t.tv_sec = r.tv_sec; | ||
72 | t.tv_nsec = r.tv_nsec; | ||
73 | } | ||
74 | return 0; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | static luaL_Reg func[] = { | ||
79 | { "gettime", time_lua_gettime }, | ||
80 | { "sleep", time_lua_sleep }, | ||
81 | { NULL, NULL } | ||
82 | }; | ||
83 | |||
84 | /*------------------------------------------------------------------------- | ||
85 | * Initializes module | ||
86 | *-------------------------------------------------------------------------*/ | ||
87 | void time_open(lua_State *L) { | ||
88 | luaL_setfuncs(L, func, 0); | ||
89 | } | ||