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 | |
download | luasystem-7499b422e3f07bf25704cbf7989e845f89697fa8.zip |
Support for gettime and sleep functions
Provide `gettime` and `sleep` functions with at least 1 millisecond
resolution.
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | .travis.yml | 23 | ||||
-rw-r--r-- | .travis_setup.sh | 45 | ||||
-rw-r--r-- | LICENSE | 20 | ||||
-rw-r--r-- | Makefile | 32 | ||||
-rw-r--r-- | README.md | 19 | ||||
-rw-r--r-- | luasystem-scm-0.rockspec | 47 | ||||
-rw-r--r-- | spec/time_spec.lua | 13 | ||||
-rw-r--r-- | src/Makefile | 257 | ||||
-rw-r--r-- | src/compat.c | 17 | ||||
-rw-r--r-- | src/compat.h | 11 | ||||
-rw-r--r-- | src/core.c | 19 | ||||
-rw-r--r-- | src/time.c | 89 | ||||
-rw-r--r-- | system/init.lua | 2 |
14 files changed, 600 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65b45dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +**/.*.swp +**/.*.swo +*.o +*.obj +*.dll +*.so diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..efc632b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +language: c + +env: + - LUA='Lua 5.1' + - LUA='Lua 5.2' + - LUA='Lua 5.3' + - LUA='LuaJIT 2.0' + +before_install: + - bash .travis_setup.sh + +install: + - sudo luarocks install busted + - sudo luarocks make + +script: busted spec + +branches: + only: + - master + +notifications: + email: false diff --git a/.travis_setup.sh b/.travis_setup.sh new file mode 100644 index 0000000..f186230 --- /dev/null +++ b/.travis_setup.sh @@ -0,0 +1,45 @@ +# A script for setting up environment for travis-ci testing. +# Sets up Lua and Luarocks. +# LUA must be "Lua 5.1", "Lua 5.2", "Lua 5.3" or "LuaJIT 2.0". + +set -e + +echo 'rocks_servers = { + "http://luarocks.org/manifests/olivine-labs", + "http://rocks.moonscript.org/", + "http://luarocks.org/repositories/rocks", + "http://luarocks.logiceditor.com/rocks", + "http://liblua.so/luarocks/repositories/rocks" +}' >> ~/config.lua + + +if [ "$LUA" == "LuaJIT 2.0" ]; then + wget -O - http://luajit.org/download/LuaJIT-2.0.4.tar.gz | tar xz + cd LuaJIT-2.0.4 + make && sudo make install INSTALL_TSYMNAME=lua; +else + if [ "$LUA" == "Lua 5.1" ]; then + wget -O - http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz + cd lua-5.1.5; + elif [ "$LUA" == "Lua 5.2" ]; then + wget -O - http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz + cd lua-5.2.4; + elif [ "$LUA" == "Lua 5.3" ]; then + wget -O - http://www.lua.org/ftp/lua-5.3.2.tar.gz | tar xz + cd lua-5.3.2; + fi + sudo make linux install; +fi + +cd .. +wget -O - http://luarocks.org/releases/luarocks-2.3.0.tar.gz | tar xz || wget -O - http://keplerproject.github.io/luarocks/releases/luarocks-2.3.0.tar.gz | tar xz +cd luarocks-2.3.0 + +if [ "$LUA" == "LuaJIT 2.0" ]; then + ./configure --with-lua-include=/usr/local/include/luajit-2.0; +else + ./configure; +fi + +make build && sudo make install +cd .. @@ -0,0 +1,20 @@ +MIT License Terms +================= + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4d83c2a --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +# busted_time makefile +# +# see csrc/makefile for description of how to customize the build +# +# Targets: +# install install system independent support +# install-all install for lua51 lua52 lua53 +# print print the build settings + +PLAT?= linux +PLATS= macosx linux win32 mingw freebsd + +all: $(PLAT) + +$(PLATS) none install local clean: + $(MAKE) -C src $@ + +print: + $(MAKE) -C src $@ + +install-all: + $(MAKE) clean + @cd src && $(MAKE) $(PLAT) LUA_VERSION=5.1 + @cd src && $(MAKE) install LUA_VERSION=5.1 + $(MAKE) clean + @cd src && $(MAKE) $(PLAT) LUA_VERSION=5.2 + @cd src && $(MAKE) install LUA_VERSION=5.2 + $(MAKE) clean + @cd src && $(MAKE) $(PLAT) LUA_VERSION=5.3 + @cd src && $(MAKE) install LUA_VERSION=5.3 + +.PHONY: test diff --git a/README.md b/README.md new file mode 100644 index 0000000..240c478 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +LuaSystem +====== + +[![travis-ci status](https://travis-ci.org/o-lim/luasystem.svg?branch=master)](https://travis-ci.org/o-lim/luasystem/builds) + + +luasystem is a platform independent system call library for Lua. +Supports Lua >= 5.1 and luajit >= 2.0.0. + +Currently the following functions are supported: +* gettime +* sleep + +License +------- + +This code and its accompanying README are +[MIT licensed](http://www.opensource.org/licenses/mit-license.php). +See LICENSE for details. diff --git a/luasystem-scm-0.rockspec b/luasystem-scm-0.rockspec new file mode 100644 index 0000000..83f4172 --- /dev/null +++ b/luasystem-scm-0.rockspec @@ -0,0 +1,47 @@ +package = 'luasystem' +version = 'scm-0' +source = { + url = "git://github.com/o-lim/luasystem", + branch = "master" +} +description = { + summary = 'Platform independent system calls for Lua.', + detailed = [[ + Adds a Lua API for making platform independent system calls. + ]], + homepage = 'http://olivinelabs.com/luasystem/', + license = 'MIT <http://opensource.org/licenses/MIT>' +} +dependencies = { + 'lua >= 5.1', +} + +local function make_platform(plat) + local defines = { + unix = { }, + macosx = { }, + win32 = { }, + mingw32 = { "WINVER=0x0501" }, + } + return { + modules = { + ['system.core'] = { + sources = { 'src/core.c', 'src/compat.c', 'src/time.c', }, + defines = defines[plat], + }, + }, + } +end + +build = { + type = 'builtin', + platforms = { + unix = make_platform('unix'), + macosx = make_platform('macosx'), + win32 = make_platform('win32'), + mingw32 = make_platform('mingw32'), + }, + modules = { + ['system.init'] = 'system/init.lua', + }, +} diff --git a/spec/time_spec.lua b/spec/time_spec.lua new file mode 100644 index 0000000..8bee5f7 --- /dev/null +++ b/spec/time_spec.lua @@ -0,0 +1,13 @@ +local system = require 'system.core' + +describe('Test time functions', function() + it('gettime returns current time', function() + assert.is_near(os.time(), system.gettime(), 1.0) + end) + + it('sleep will wait for specified amount of time', function() + local starttime = system.gettime() + system.sleep(0.5) + assert.is_near(0.5, system.gettime() - starttime, 0.1) + end) +end) diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..25f468d --- /dev/null +++ b/src/Makefile @@ -0,0 +1,257 @@ +# luasystem +# +# Definitions in this section can be overriden on the command line or in the +# environment. +# + +# PLAT: linux macosx win32 mingw +# platform to build for +PLAT?=linux + +# LUA_VERSION: 5.1 5.2 5.3 +# lua version to build against +LUA_VERSION?=5.1 + +# MYCFLAGS: to be set by user if needed +MYCFLAGS= + +# MYLDFLAGS: to be set by user if needed +MYLDFLAGS= + +# where lua headers are found for macosx builds +# LUAINC_macosx: +# /opt/local/include +LUAINC_macosx_base?=/opt/local/include +LUAINC_macosx?=$(LUAINC_macosx_base)/lua/$(LUA_VERSION) +# FIXME default should this default to fink or to macports? +# What happens when more than one Lua version is installed? +LUAPREFIX_macosx?=/opt/local +CDIR_macosx?=lib/lua/$(LUA_VERSION) +LDIR_macosx?=share/lua/$(LUA_VERSION) + +# LUAINC_linux: +# /usr/include/lua$(LUA_VERSION) +# /usr/local/include +# /usr/local/include/lua$(LUA_VERSION) +# where lua headers are found for linux builds +LUAINC_linux_base?=/usr/include +LUAINC_linux?=$(LUAINC_linux_base)/lua/$(LUA_VERSION) +LUAPREFIX_linux?=/usr/local +CDIR_linux?=lib/lua/$(LUA_VERSION) +LDIR_linux?=share/lua/$(LUA_VERSION) + +# LUAINC_freebsd: +# /usr/local/include/lua$(LUA_VERSION) +# where lua headers are found for linux builds +LUAINC_freebsd_base?=/usr/local/include/ +LUAINC_freebsd?=$(LUAINC_freebsd_base)/lua$(LUA_VERSION) +LUAPREFIX_freebsd?=/usr/local/ +CDIR_freebsd?=lib/lua/$(LUA_VERSION) +LDIR_freebsd?=share/lua/$(LUA_VERSION) + +# where lua headers are found for mingw builds +# LUAINC_mingw: +# /opt/local/include +LUAINC_mingw_base?=/usr/include +LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUA_VERSION) +LUALIB_mingw_base?=/usr/bin +LUALIB_mingw?=$(LUALIB_mingw_base)/lua/$(LUA_VERSION)/lua$(subst .,,$(LUA_VERSION)).dll +LUAPREFIX_mingw?=/usr +CDIR_mingw?=lua/$(LUA_VERSION) +LDIR_mingw?=lua/$(LUA_VERSION)/lua + + +# LUAINC_win32: +# LUALIB_win32: +# where lua headers and libraries are found for win32 builds +LUAPREFIX_win32?= +LUAINC_win32?=$(LUAPREFIX_win32)/include/lua/$(LUA_VERSION) +PLATFORM_win32?=Release +CDIR_win32?=bin/lua/$(LUA_VERSION)/$(PLATFORM_win32) +LDIR_win32?=bin/lua/$(LUA_VERSION)/$(PLATFORM_win32)/lua +LUALIB_win32?=$(LUAPREFIX_win32)/lib/lua/$(LUA_VERSION)/$(PLATFORM_win32) +LUALIBNAME_win32?=lua$(subst .,,$(LUA_VERSION)).lib + + +# prefix: /usr/local /usr /opt/local /sw +# the top of the default install tree +prefix?=$(LUAPREFIX_$(PLAT)) + +CDIR?=$(CDIR_$(PLAT)) +LDIR?=$(LDIR_$(PLAT)) + +# DESTDIR: (no default) +# used by package managers to install into a temporary destination +DESTDIR= + +#------ +# Definitions below can be overridden on the make command line, but +# shouldn't have to be. + + +#------ +# Install directories +# + +INSTALL_DIR=install -d +INSTALL_DATA=install -m644 +INSTALL_EXEC=install +INSTALL_TOP=$(DESTDIR)$(prefix) + +INSTALL_TOP_LDIR=$(INSTALL_TOP)/$(LDIR) +INSTALL_TOP_CDIR=$(INSTALL_TOP)/$(CDIR) + +INSTALL_LDIR=$(INSTALL_TOP_LDIR)/system +INSTALL_CDIR=$(INSTALL_TOP_CDIR)/system + +#------ +# Supported platforms +# +PLATS= macosx linux win32 mingw + +#------ +# Compiler and linker settings +# for Mac OS X +SO_macosx=so +O_macosx=o +CC_macosx=gcc +DEF_macosx= +CFLAGS_macosx= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o +LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc + +#------ +# Compiler and linker settings +# for Linux +SO_linux=so +O_linux=o +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 +LD_linux=gcc + +#------ +# Compiler and linker settings +# for FreeBSD +SO_freebsd=so +O_freebsd=o +CC_freebsd=gcc +DEF_freebsd= +CFLAGS_freebsd= -I$(LUAINC) $(DEF) -Wall -Wshadow -Wextra \ + -Wimplicit -O2 -ggdb3 -fpic -fvisibility=hidden +LDFLAGS_freebsd=-O -shared -fpic -o +LD_freebsd=gcc + +#------ +# Compiler and linker settings +# for MingW +SO_mingw=dll +O_mingw=o +CC_mingw=gcc +DEF_mingw=-DWINVER=0x0501 +CFLAGS_mingw= -I$(LUAINC) $(DEF) -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -o +LD_mingw=gcc + + +#------ +# Compiler and linker settings +# for Win32 +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" +CFLAGS_win32=//I "$(LUAINC)" $(DEF) //O2 //Ot //MD //W3 //nologo +LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \ + //MANIFEST //MANIFESTFILE:"intermediate.manifest" \ + //MANIFESTUAC:"level='asInvoker' uiAccess='false'" \ + //SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \ + //MACHINE:X86 /LIBPATH:"$(shell cmd //c echo $(LUALIB))" \ + $(LUALIBNAME_win32) //OUT: +LD_win32=cl + +.SUFFIXES: .obj + +.c.obj: + $(CC) $(CFLAGS) //Fo"$@" //c $< + +#------ +# Output file names +# +SO=$(SO_$(PLAT)) +O=$(O_$(PLAT)) +SOLIB=core.$(SO) + +#------ +# Settings selected for platform +# +CC=$(CC_$(PLAT)) +DEF=$(DEF_$(PLAT)) +CFLAGS=$(MYCFLAGS) $(CFLAGS_$(PLAT)) +LDFLAGS=$(MYLDFLAGS) $(LDFLAGS_$(PLAT)) +LD=$(LD_$(PLAT)) +LUAINC= $(LUAINC_$(PLAT)) +LUALIB= $(LUALIB_$(PLAT)) + +#------ +# Objects +# +OBJS=core.$(O) compat.$(O) time.$(O) + +#------ +# Targets +# +default: $(PLAT) + +freebsd: + $(MAKE) all PLAT=freebsd + +macosx: + $(MAKE) all PLAT=macosx + +win32: + $(MAKE) all PLAT=win32 + +linux: + $(MAKE) all PLAT=linux + +mingw: + $(MAKE) all PLAT=mingw + +none: + @echo "Please run" + @echo " make PLATFORM" + @echo "where PLATFORM is one of these:" + @echo " $(PLATS)" + +all: $(SOLIB) + +$(SOLIB): $(OBJS) + $(LD) $(OBJS) $(LDFLAGS)$@ + +install: all + $(INSTALL_DIR) $(INSTALL_TOP_LDIR) + $(INSTALL_DIR) $(INSTALL_CDIR) + $(INSTALL_EXEC) $(SOLIB) $(INSTALL_CDIR)/$(SOLIB) + +local: + $(MAKE) install INSTALL_TOP_CDIR=.. INSTALL_TOP_LDIR=.. + +clean: + rm -f $(SOLIB) $(OBJS) ../system/core.so + +print: + @echo PLAT=$(PLAT) + @echo LUA_VERSION=$(LUA_VERSION) + @echo prefix=$(prefix) + @echo LUAINC_$(PLAT)=$(LUAINC_$(PLAT)) + @echo LUALIB_$(PLAT)=$(LUALIB_$(PLAT)) + @echo INSTALL_TOP_CDIR=$(INSTALL_TOP_CDIR) + @echo INSTALL_TOP_LDIR=$(INSTALL_TOP_LDIR) + +.PHONY: all $(PLATS) default clean none diff --git a/src/compat.c b/src/compat.c new file mode 100644 index 0000000..d763c56 --- /dev/null +++ b/src/compat.c @@ -0,0 +1,17 @@ +#include <lua.h> +#include <lauxlib.h> + +#if LUA_VERSION_NUM == 501 +void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkstack(L, nup+1, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + lua_pushstring(L, l->name); + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -(nup+1)); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_settable(L, -(nup + 3)); + } + lua_pop(L, nup); /* remove upvalues */ +} +#endif diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..f523fd9 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,11 @@ +#ifndef COMPAT_H +#define COMPAT_H + +#include <lua.h> +#include <lauxlib.h> + +#if LUA_VERSION_NUM == 501 +void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup); +#endif + +#endif diff --git a/src/core.c b/src/core.c new file mode 100644 index 0000000..d2acb95 --- /dev/null +++ b/src/core.c @@ -0,0 +1,19 @@ +#include <lua.h> +#include <lauxlib.h> + +#ifdef _WIN32 +#define LUAEXPORT __declspec(dllexport) +#else +#define LUAEXPORT __attribute__((visibility("default"))) +#endif + +void time_open(lua_State *L); + +/*------------------------------------------------------------------------- + * Initializes all library modules. + *-------------------------------------------------------------------------*/ +LUAEXPORT int luaopen_system_core(lua_State *L) { + lua_newtable(L); + time_open(L); + return 1; +} 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 @@ +#include <lua.h> +#include <lauxlib.h> + +#ifdef _WIN32 +#include <windows.h> +#else +#include <time.h> +#include <sys/time.h> +#endif + +#include "compat.h" + +/*------------------------------------------------------------------------- + * Gets time in s, relative to January 1, 1970 (UTC) + * Returns + * time in s. + *-------------------------------------------------------------------------*/ +#ifdef _WIN32 +static double time_gettime(void) { + FILETIME ft; + double t; + GetSystemTimeAsFileTime(&ft); + /* Windows file time (time since January 1, 1601 (UTC)) */ + t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); + /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ + return (t - 11644473600.0); +} +#else +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; +} +#endif + +/*------------------------------------------------------------------------- + * Returns the time the system has been up, in secconds. + *-------------------------------------------------------------------------*/ +static int time_lua_gettime(lua_State *L) +{ + lua_pushnumber(L, time_gettime()); + return 1; +} + +/*------------------------------------------------------------------------- + * Sleep for n seconds. + *-------------------------------------------------------------------------*/ +#ifdef _WIN32 +static int time_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); + if (n < 0.0) n = 0.0; + if (n < DBL_MAX/1000.0) n *= 1000.0; + if (n > INT_MAX) n = INT_MAX; + Sleep((int)n); + return 0; +} +#else +static int time_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); + struct timespec t, r; + if (n < 0.0) n = 0.0; + if (n > INT_MAX) n = INT_MAX; + t.tv_sec = (int) n; + n -= t.tv_sec; + t.tv_nsec = (int) (n * 1000000000); + if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; + while (nanosleep(&t, &r) != 0) { + t.tv_sec = r.tv_sec; + t.tv_nsec = r.tv_nsec; + } + return 0; +} +#endif + +static luaL_Reg func[] = { + { "gettime", time_lua_gettime }, + { "sleep", time_lua_sleep }, + { NULL, NULL } +}; + +/*------------------------------------------------------------------------- + * Initializes module + *-------------------------------------------------------------------------*/ +void time_open(lua_State *L) { + luaL_setfuncs(L, func, 0); +} diff --git a/system/init.lua b/system/init.lua new file mode 100644 index 0000000..77e0c3b --- /dev/null +++ b/system/init.lua @@ -0,0 +1,2 @@ +local system = require 'system.core' +return system |