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_ */

Reply via email to