Module Name: src Committed By: lneto Date: Sat Jul 19 17:13:22 UTC 2014
Modified Files: src/sys/modules/lua: lua.c src/sys/sys: lua.h Log Message: lua(4): added support for running Lua scripts in intr context * using kmem_intr on lua_alloc * using mutex directly on klua_lock * added ipl arg on klua_newstate() * added kluaL_newstate function * fixed synchronization: locking the Lua state on luaioctl To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/modules/lua/lua.c cvs rdiff -u -r1.3 -r1.4 src/sys/sys/lua.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/modules/lua/lua.c diff -u src/sys/modules/lua/lua.c:1.8 src/sys/modules/lua/lua.c:1.9 --- src/sys/modules/lua/lua.c:1.8 Sun Mar 16 05:20:30 2014 +++ src/sys/modules/lua/lua.c Sat Jul 19 17:13:22 2014 @@ -1,6 +1,7 @@ -/* $NetBSD: lua.c,v 1.8 2014/03/16 05:20:30 dholland Exp $ */ +/* $NetBSD: lua.c,v 1.9 2014/07/19 17:13:22 lneto Exp $ */ /* + * Copyright (c) 2014 by Lourival Vieira Neto <ln...@netbsd.org>. * Copyright (c) 2011, 2013 by Marc Balmer <mbal...@netbsd.org>. * All rights reserved. * @@ -45,6 +46,7 @@ #include <sys/queue.h> #include <sys/sysctl.h> #include <sys/vnode.h> +#include <sys/cpu.h> #include <lauxlib.h> @@ -330,8 +332,7 @@ luaioctl(dev_t dev, u_long cmd, void *da return EBUSY; } - K = klua_newstate(lua_alloc, NULL, create->name, - create->desc); + K = kluaL_newstate(create->name, create->desc, IPL_NONE); K->ks_user = true; if (K == NULL) @@ -364,7 +365,9 @@ luaioctl(dev_t dev, u_long cmd, void *da "%s to state %s\n", m->mod_name, s->lua_name); + klua_lock(s->K); m->open(s->K->L); + klua_unlock(s->K); m->refcount++; LIST_INSERT_HEAD( &s->lua_modules, m, @@ -419,6 +422,7 @@ luaioctl(dev_t dev, u_long cmd, void *da ls.off = 0L; ls.size = va.va_size; VOP_UNLOCK(nd.ni_vp); + klua_lock(s->K); error = lua_load(s->K->L, lua_reader, &ls, strrchr(load->path, '/') + 1); vn_close(nd.ni_vp, FREAD, cred); @@ -429,11 +433,13 @@ luaioctl(dev_t dev, u_long cmd, void *da if (lua_verbose) device_printf(sc->sc_dev, "syntax error\n"); + klua_unlock(s->K); return EINVAL; case LUA_ERRMEM: if (lua_verbose) device_printf(sc->sc_dev, "memory error\n"); + klua_unlock(s->K); return ENOMEM; default: if (lua_verbose) @@ -441,6 +447,7 @@ luaioctl(dev_t dev, u_long cmd, void *da "load error %d: %s\n", error, lua_tostring(s->K->L, -1)); + klua_unlock(s->K); return EINVAL; } if (lua_max_instr > 0) @@ -453,8 +460,10 @@ luaioctl(dev_t dev, u_long cmd, void *da "execution error: %s\n", lua_tostring(s->K->L, -1)); } + klua_unlock(s->K); return EINVAL; } + klua_unlock(s->K); return 0; } return ENXIO; @@ -507,20 +516,38 @@ lua_require(lua_State *L) return lua_error(L); } -void * +typedef struct { + size_t size; +} __packed alloc_header_t; + +static void * lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { - void *nptr; + void *nptr = NULL; + + const size_t hdr_size = sizeof(alloc_header_t); + alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size); - if (nsize == 0) { - nptr = NULL; + if (nsize == 0) { /* freeing */ if (ptr != NULL) - kmem_free(ptr, osize); - } else { - nptr = kmem_alloc(nsize, KM_SLEEP); - if (ptr != NULL) { - memcpy(nptr, ptr, osize < nsize ? osize : nsize); - kmem_free(ptr, osize); + kmem_intr_free(hdr, hdr->size); + } else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */ + return ptr; /* don't need to reallocate */ + else { /* creating or expanding */ + km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ? + KM_NOSLEEP : KM_SLEEP; + + size_t alloc_size = nsize + hdr_size; + alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep); + if (nhdr == NULL) /* failed to allocate */ + return NULL; + + nhdr->size = alloc_size; + nptr = (void *) ((char *) nhdr + hdr_size); + + if (ptr != NULL) { /* expanding */ + memcpy(nptr, ptr, osize); + kmem_intr_free(hdr, hdr->size); } } return nptr; @@ -600,7 +627,8 @@ lua_mod_unregister(const char *name) } klua_State * -klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc) +klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc, + int ipl) { klua_State *K; struct lua_state *s; @@ -641,8 +669,7 @@ klua_newstate(lua_Alloc f, void *ud, con } LIST_INSERT_HEAD(&lua_states, s, lua_next); - mutex_init(&K->ks_lock, MUTEX_DEFAULT, IPL_VM); - cv_init(&K->ks_inuse_cv, "luainuse"); + mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl); finish: mutex_enter(&sc->sc_state_lock); @@ -652,6 +679,12 @@ finish: return K; } +inline klua_State * +kluaL_newstate(const char *name, const char *desc, int ipl) +{ + return klua_newstate(lua_alloc, NULL, name, desc, ipl); +} + void klua_close(klua_State *K) { @@ -660,19 +693,10 @@ klua_close(klua_State *K) struct lua_module *m; int error = 0; - /* Notify the Lua state that it is about to be closed */ - if (klua_lock(K)) - return; /* Nothing we can do about */ - lua_getglobal(K->L, "onClose"); if (lua_isfunction(K->L, -1)) lua_pcall(K->L, -1, 0, 0); - /* - * Don't unlock, make sure no one uses the state until it is destroyed - * klua_unlock(K); - */ - sc = device_private(sc_self); mutex_enter(&sc->sc_state_lock); while (sc->sc_state == true) { @@ -696,7 +720,6 @@ klua_close(klua_State *K) } lua_close(K->L); - cv_destroy(&K->ks_inuse_cv); mutex_destroy(&K->ks_lock); kmem_free(K, sizeof(klua_State)); @@ -742,33 +765,15 @@ klua_find(const char *name) return K; } -int +inline void klua_lock(klua_State *K) { - int error; - - error = 0; mutex_enter(&K->ks_lock); - while (K->ks_inuse == true) { - error = cv_wait_sig(&K->ks_inuse_cv, &K->ks_lock); - if (error) - break; - } - if (!error) - K->ks_inuse = true; - mutex_exit(&K->ks_lock); - - if (error) - return error; - return 0; } -void +inline void klua_unlock(klua_State *K) { - mutex_enter(&K->ks_lock); - K->ks_inuse = false; - cv_signal(&K->ks_inuse_cv); mutex_exit(&K->ks_lock); } Index: src/sys/sys/lua.h diff -u src/sys/sys/lua.h:1.3 src/sys/sys/lua.h:1.4 --- src/sys/sys/lua.h:1.3 Tue Oct 29 17:35:40 2013 +++ src/sys/sys/lua.h Sat Jul 19 17:13:22 2014 @@ -1,6 +1,7 @@ -/* $NetBSD: lua.h,v 1.3 2013/10/29 17:35:40 mbalmer Exp $ */ +/* $NetBSD: lua.h,v 1.4 2014/07/19 17:13:22 lneto Exp $ */ /* + * Copyright (c) 2014 by Lourival Vieira Neto <ln...@netbsd.org>. * Copyright (c) 2011, 2013 Marc Balmer <mbal...@netbsd.org>. * All rights reserved. * @@ -85,19 +86,16 @@ extern int lua_mod_unregister(const char typedef struct _klua_State { lua_State *L; kmutex_t ks_lock; - kcondvar_t ks_inuse_cv; - int ks_inuse; bool ks_user; /* state created by user (ioctl) */ } klua_State; -extern int klua_lock(klua_State *); +extern void klua_lock(klua_State *); extern void klua_unlock(klua_State *); extern void klua_close(klua_State *); -extern klua_State *klua_newstate(lua_Alloc, void *, const char *, const char *); - -extern void *lua_alloc(void *, void *, size_t, size_t); - +extern klua_State *klua_newstate(lua_Alloc, void *, const char *, const char *, + int); +extern klua_State *kluaL_newstate(const char *, const char *, int); #endif #endif /* _SYS_LUA_H_ */