diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2023-11-09 23:03:21 +0100 |
---|---|---|
committer | Thijs Schreijer <thijs@thijsschreijer.nl> | 2023-11-15 19:17:57 +0100 |
commit | d45768de3e6f7b28bfecf4d19b192ccac9ce5dc2 (patch) | |
tree | 2d4f86ec87eb87a77f6663924aaaa9286756ce3e /src/time.c | |
parent | d4222ce6da2a2d7179fc79f9d0cc65fd6c09a686 (diff) | |
download | luasystem-d45768de3e6f7b28bfecf4d19b192ccac9ce5dc2.tar.gz luasystem-d45768de3e6f7b28bfecf4d19b192ccac9ce5dc2.tar.bz2 luasystem-d45768de3e6f7b28bfecf4d19b192ccac9ce5dc2.zip |
feat(*): add environment variable and random functions
Diffstat (limited to 'src/time.c')
-rw-r--r-- | src/time.c | 87 |
1 files changed, 58 insertions, 29 deletions
@@ -1,3 +1,4 @@ | |||
1 | /// @submodule system | ||
1 | #include <lua.h> | 2 | #include <lua.h> |
2 | #include <lauxlib.h> | 3 | #include <lauxlib.h> |
3 | 4 | ||
@@ -50,11 +51,8 @@ static double time_gettime(void) { | |||
50 | } | 51 | } |
51 | #endif | 52 | #endif |
52 | 53 | ||
53 | /*------------------------------------------------------------------------- | 54 | |
54 | * Gets monotonic time in s | 55 | |
55 | * Returns | ||
56 | * time in s. | ||
57 | *-------------------------------------------------------------------------*/ | ||
58 | #ifdef _WIN32 | 56 | #ifdef _WIN32 |
59 | WINBASEAPI ULONGLONG WINAPI GetTickCount64(VOID); | 57 | WINBASEAPI ULONGLONG WINAPI GetTickCount64(VOID); |
60 | 58 | ||
@@ -70,53 +68,84 @@ static double time_monotime(void) { | |||
70 | } | 68 | } |
71 | #endif | 69 | #endif |
72 | 70 | ||
73 | /*------------------------------------------------------------------------- | 71 | |
74 | * Returns the current system time, 1970 (UTC), in secconds. | 72 | |
75 | *-------------------------------------------------------------------------*/ | 73 | /*** |
74 | Get system time. | ||
75 | The time is returned as the seconds since the epoch (1 January 1970 00:00:00). | ||
76 | @function gettime | ||
77 | @treturn number seconds (fractional) | ||
78 | */ | ||
76 | static int time_lua_gettime(lua_State *L) | 79 | static int time_lua_gettime(lua_State *L) |
77 | { | 80 | { |
78 | lua_pushnumber(L, time_gettime()); | 81 | lua_pushnumber(L, time_gettime()); |
79 | return 1; | 82 | return 1; |
80 | } | 83 | } |
81 | 84 | ||
82 | /*------------------------------------------------------------------------- | 85 | |
83 | * Returns the monotonic time the system has been up, in secconds. | 86 | |
84 | *-------------------------------------------------------------------------*/ | 87 | /*** |
88 | Get monotonic time. | ||
89 | The time is returned as the seconds since system start. | ||
90 | @function monotime | ||
91 | @treturn number seconds (fractional) | ||
92 | */ | ||
85 | static int time_lua_monotime(lua_State *L) | 93 | static int time_lua_monotime(lua_State *L) |
86 | { | 94 | { |
87 | lua_pushnumber(L, time_monotime()); | 95 | lua_pushnumber(L, time_monotime()); |
88 | return 1; | 96 | return 1; |
89 | } | 97 | } |
90 | 98 | ||
91 | /*------------------------------------------------------------------------- | 99 | |
92 | * Sleep for n seconds. | 100 | |
93 | *-------------------------------------------------------------------------*/ | 101 | /*** |
102 | Sleep without a busy loop. | ||
103 | This function will sleep, without doing a busy-loop and wasting CPU cycles. | ||
104 | @function sleep | ||
105 | @tparam number seconds seconds to sleep (fractional). | ||
106 | @tparam[opt=16] integer precision minimum stepsize in milliseconds (Windows only, ignored elsewhere) | ||
107 | @return `true` on success, or `nil+err` on failure | ||
108 | */ | ||
94 | #ifdef _WIN32 | 109 | #ifdef _WIN32 |
95 | static int time_lua_sleep(lua_State *L) | 110 | static int time_lua_sleep(lua_State *L) |
96 | { | 111 | { |
97 | double n = luaL_checknumber(L, 1); | 112 | double n = luaL_checknumber(L, 1); |
98 | if (n < 0.0) n = 0.0; | 113 | |
99 | if (n < DBL_MAX/1000.0) n *= 1000.0; | 114 | int precision = luaL_optinteger(L, 2, 16); |
100 | if (n > INT_MAX) n = INT_MAX; | 115 | if (precision < 0 || precision > 16) precision = 16; |
101 | Sleep((int)n); | 116 | |
102 | return 0; | 117 | if (n > 0.0) { |
118 | if (n < DBL_MAX/1000.0) n *= 1000.0; | ||
119 | if (n > INT_MAX) n = INT_MAX; | ||
120 | if (timeBeginPeriod(precision) != TIMERR_NOERROR) { | ||
121 | lua_pushnil(L); | ||
122 | lua_pushstring(L, "failed to set timer precision"); | ||
123 | return 2; | ||
124 | }; | ||
125 | Sleep((int)n); | ||
126 | timeEndPeriod(precision); | ||
127 | } | ||
128 | lua_pushboolean(L, 1); | ||
129 | return 1; | ||
103 | } | 130 | } |
104 | #else | 131 | #else |
105 | static int time_lua_sleep(lua_State *L) | 132 | static int time_lua_sleep(lua_State *L) |
106 | { | 133 | { |
107 | double n = luaL_checknumber(L, 1); | 134 | double n = luaL_checknumber(L, 1); |
108 | struct timespec t, r; | 135 | struct timespec t, r; |
109 | if (n < 0.0) n = 0.0; | 136 | if (n > 0.0) { |
110 | if (n > INT_MAX) n = INT_MAX; | 137 | if (n > INT_MAX) n = INT_MAX; |
111 | t.tv_sec = (int) n; | 138 | t.tv_sec = (int) n; |
112 | n -= t.tv_sec; | 139 | n -= t.tv_sec; |
113 | t.tv_nsec = (int) (n * 1000000000); | 140 | t.tv_nsec = (int) (n * 1000000000); |
114 | if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; | 141 | if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; |
115 | while (nanosleep(&t, &r) != 0) { | 142 | while (nanosleep(&t, &r) != 0) { |
116 | t.tv_sec = r.tv_sec; | 143 | t.tv_sec = r.tv_sec; |
117 | t.tv_nsec = r.tv_nsec; | 144 | t.tv_nsec = r.tv_nsec; |
145 | } | ||
118 | } | 146 | } |
119 | return 0; | 147 | lua_pushboolean(L, 1); |
148 | return 1; | ||
120 | } | 149 | } |
121 | #endif | 150 | #endif |
122 | 151 | ||