lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Thursday, January 08, 2015 09:39:13 AM Roberto Ierusalimschy wrote:
> > I've been using gettimeofday to return microsecond resolution in os.time.
> > [...]
> Can you show your implementation?

I hastily added the rounding l_checktime yesterday to make os.date stop 
complaining. gettimeofday falls back to time(NULL) on error. _ftime claims to 
only fail on invalid input (NULL pointer).

-- 
tom <telliamed@whoopdedo.org>
diff --git a/src/loslib.c b/src/loslib.c
index 20359b2..1af3f4d 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -15,11 +15,18 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <math.h>
 
 #include "lua.h"
 
 #include "lauxlib.h"
 #include "lualib.h"
+#ifdef LUA_USE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+#ifdef LUA_USE_FTIME
+#include <sys/timeb.h>
+#endif
 
 
 #if !defined(LUA_STRFTIMEOPTIONS)	/* { */
@@ -46,7 +53,21 @@
 */
 #define l_timet			lua_Integer
 #define l_pushtime(L,t)		lua_pushinteger(L,(lua_Integer)(t))
+
+#if defined(LUA_USE_GETTIMEOFDAY) || defined(LUA_USE_FTIME)
+
+static time_t l_checktime(lua_State *L, int a) {
+    lua_Number n = luaL_checknumber(L, a) + 0.5;
+    l_timet t = l_floor(n);
+    if ((lua_Number)t == n) {
+	t -= t & 1;  /* round half even */
+    }
+    return t;
+}
+
+#else
 #define l_checktime(L,a)	((time_t)luaL_checkinteger(L,a))
+#endif
 
 #endif				/* } */
 
@@ -271,8 +292,24 @@ static int os_date (lua_State *L) {
 
 static int os_time (lua_State *L) {
   time_t t;
-  if (lua_isnoneornil(L, 1))  /* called without args? */
+  if (lua_isnoneornil(L, 1)) {  /* called without args? */
+#ifdef LUA_USE_GETTIMEOFDAY
+    struct timeval tv;
+    if (0 == gettimeofday(&tv, NULL)) {
+      lua_pushnumber(L, (lua_Number)tv.tv_sec + (lua_Number)tv.tv_usec * 0.000001);
+      return 1;
+    }
+    else
+      t = time(NULL);  /* get current time */
+#elif defined(LUA_USE_FTIME)
+    struct _timeb tb;
+    _ftime(&tb);
+    lua_pushnumber(L, (lua_Number)tb.time + (lua_Number)tb.millitm * 0.001);
+    return 1;
+#else
     t = time(NULL);  /* get current time */
+#endif
+  }
   else {
     struct tm ts;
     luaL_checktype(L, 1, LUA_TTABLE);
diff --git a/src/luaconf.h b/src/luaconf.h
index fd28d21..367f592 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -55,6 +55,7 @@
 #if defined(LUA_USE_WINDOWS)
 #define LUA_DL_DLL	/* enable support for DLL */
 #define LUA_USE_C89	/* broadly, Windows is C89 */
+#define LUA_USE_FTIME
 #endif
 
 
@@ -62,6 +63,7 @@
 #define LUA_USE_POSIX
 #define LUA_USE_DLOPEN		/* needs an extra library: -ldl */
 #define LUA_USE_READLINE	/* needs some extra libraries */
+#define LUA_USE_GETTIMEOFDAY
 #endif