klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit e5d2c04761eb5ceeab645971d55e26efd8f8c0e0
parent 9ad9c4bd442cca8f5bce81653f785480287f30e6
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 22 Aug 2012 02:44:32 -0300

Modified the GIL to be reentrant (still uses a simple mutex, the number of times the lock was acquired is kept in the klisp_State struct).

Diffstat:
Msrc/klimits.h | 24++++++++++++++++++++++--
Msrc/kstate.c | 3++-
Msrc/kstate.h | 5++++-
3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/klimits.h b/src/klimits.h @@ -89,8 +89,28 @@ /* XXX for now ignore the return values */ #ifndef klisp_lock #include <pthread.h> -#define klisp_lock(K) ((void) (pthread_mutex_lock(&G(K)->gil))) -#define klisp_unlock(K) ((void) (pthread_mutex_unlock(&G(K)->gil))) +#define klisp_lock(K) ({ \ + if (K->gil_count == 0) { \ + K->gil_count = 1; \ + UNUSED(pthread_mutex_lock(&G(K)->gil)); \ + } else { \ + ++K->gil_count; \ + }}) + +#define klisp_unlock(K) ({ \ + if (K->gil_count <= 1) { \ + K->gil_count = 0; \ + UNUSED(pthread_mutex_unlock(&G(K)->gil)); \ + } else { \ + --K->gil_count; \ + }}) + +#define klisp_unlock_all(K) ({ \ + if (K->gil_count > 0) { \ + K->gil_count = 1; \ + klisp_unlock(K); \ + }}) + #endif /* These were the original defines */ diff --git a/src/kstate.c b/src/kstate.c @@ -98,7 +98,8 @@ static void f_klispopen (klisp_State *K, void *ud) { static void preinit_state (klisp_State *K, global_State *g) { G(K) = g; - + + K->gil_count = 0; K->curr_cont = KNIL; K->next_obj = KINERT; K->next_func = NULL; diff --git a/src/kstate.h b/src/kstate.h @@ -131,7 +131,9 @@ typedef struct global_State { /* The main thread */ klisp_State *mainthread; /* The GIL (Global Interpreter Lock) */ - /* (at least for now) we'll use a non recursive mutex */ + /* This is a regular mutex, but we use it to emulate a recursive one. + The number of times the lock was acquired is maintained in the + locking thread in gil_count */ pthread_mutex_t gil; } global_State; @@ -139,6 +141,7 @@ struct klisp_State { CommonHeader; /* This represents a thread object */ global_State *k_G; /* Current state of execution */ + int32_t gil_count; /* the number of times the GIL was acquired */ TValue curr_cont; /* the current continuation of this thread */ /* ** If next_env is NIL, then the next_func is from a continuation