klisp

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

commit a14163fbe8cd5c129444b53862a09c8754332ae5
parent 25e588efd05fc3153a756c42c08bdfbfa34b8256
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 24 Aug 2012 03:43:14 -0300

Some bugfixes and comments regarding locks in kstate.

Diffstat:
Msrc/kstate.c | 14+++++++++-----
Msrc/kstate.h | 33+++++++++++++++++++++++++--------
2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/kstate.c b/src/kstate.c @@ -148,10 +148,11 @@ static void preinit_state (klisp_State *K, global_State *g) { ks_tbuf(K) = NULL; } +/* LOCK: GIL should be acquired */ static void close_state(klisp_State *K) { global_State *g = G(K); -/* XXX lock? */ + /* collect all objects */ klispC_freeall(K); klisp_assert(g->rootgc == obj2gco(K)); @@ -399,9 +400,9 @@ klisp_State *klisp_newthread(klisp_State *K) return K; } -/* XXX lock? */ klisp_State *klispT_newthread(klisp_State *K) { + klisp_lock(K); klisp_State *K1 = tostate(klispM_malloc(K, state_size(klisp_State))); klispC_link(K, (GCObject *) K1, K_TTHREAD, 0); preinit_state(K1, G(K)); @@ -416,24 +417,26 @@ klisp_State *klispT_newthread(klisp_State *K) ks_tbidx(K1) = 0; /* buffer is empty */ klisp_assert(iswhite((GCObject *) (K1))); + klisp_unlock(K); return K1; } -/* XXX lock? */ void klispT_freethread (klisp_State *K, klisp_State *K1) { + klisp_lock(K); klispM_freemem(K, ks_sbuf(K1), ks_ssize(K1) * sizeof(TValue)); klispM_freemem(K, ks_tbuf(K1), ks_tbsize(K1)); /* userstatefree() */ klispM_freemem(K, fromstate(K1), state_size(klisp_State)); + klisp_unlock(K); } void klisp_close (klisp_State *K) { -/* XXX lock? */ K = G(K)->mainthread; /* only the main thread can be closed */ + klisp_lock(K); /* XXX lua does the following */ #if 0 lua_lock(L); @@ -457,6 +460,7 @@ void klisp_close (klisp_State *K) ** Stacks memory management */ +/* LOCK: All these functions should be called with the GIL already acquired */ /* TODO test this */ void ks_sgrow(klisp_State *K, int32_t new_top) { @@ -498,7 +502,7 @@ void ks_tbgrow(klisp_State *K, int32_t new_top) size_t new_size = old_size * 2; while(new_top > new_size) new_size *= 2; - + ks_tbuf(K) = klispM_realloc_(K, ks_tbuf(K), old_size*sizeof(TValue), new_size*sizeof(TValue)); ks_tbsize(K) = new_size; diff --git a/src/kstate.h b/src/kstate.h @@ -268,6 +268,7 @@ static inline bool ks_sisempty(klisp_State *K); #define ks_sbuf(st_) ((st_)->sbuf) #define ks_selem(st_, i_) ((ks_sbuf(st_))[i_]) +/* LOCK: All these functions should be called with the GIL already acquired */ static inline void ks_spush(klisp_State *K, TValue obj) { ks_selem(K, ks_stop(K)) = obj; @@ -338,6 +339,7 @@ static inline bool ks_tbisempty(klisp_State *K); #define ks_tbuf(st_) ((st_)->ktok_buffer) #define ks_tbelem(st_, i_) ((ks_tbuf(st_))[i_]) +/* LOCK: All these functions should be called with the GIL already acquired */ static inline void ks_tbadd(klisp_State *K, char ch) { if (ks_tbidx(K) == ks_tbsize(K)) @@ -414,6 +416,7 @@ static inline void krooted_vars_clear(klisp_State *K) { K->rooted_vars_top = 0; ** Source code tracking ** MAYBE: add source code tracking to symbols */ +/* LOCK: All these functions should be called with the GIL already acquired */ #if KTRACK_SI static inline TValue kget_source_info(klisp_State *K, TValue obj) { @@ -458,6 +461,7 @@ static inline void klispT_apply_cc(klisp_State *K, TValue val) { /* TODO write barriers */ + klisp_lock(K); /* various assert to check the freeing of gc protection methods */ /* TODO add marks assertions */ klisp_assert(K->rooted_tvs_top == 0); @@ -472,20 +476,26 @@ static inline void klispT_apply_cc(klisp_State *K, TValue val) K->next_xparams = cont->extra; K->curr_cont = cont->parent; K->next_si = ktry_get_si(K, K->next_obj); + klisp_unlock(K); } #define kapply_cc(K_, val_) klispT_apply_cc((K_), (val_)); return static inline TValue klispT_get_cc(klisp_State *K) { - return K->curr_cont; + klisp_lock(K); + TValue res = K->curr_cont; + klisp_unlock(K); + return res; } #define kget_cc(K_) (klispT_get_cc(K_)) static inline void klispT_set_cc(klisp_State *K, TValue new_cont) { + klisp_lock(K); K->curr_cont = new_cont; + klisp_unlock(K); } #define kset_cc(K_, c_) (klispT_set_cc(K_, c_)) @@ -494,7 +504,7 @@ static inline void klispT_tail_call_si(klisp_State *K, TValue top, TValue ptree, TValue env, TValue si) { /* TODO write barriers */ - + klisp_lock(K); /* various assert to check the freeing of gc protection methods */ klisp_assert(K->rooted_tvs_top == 0); klisp_assert(K->rooted_vars_top == 0); @@ -508,6 +518,7 @@ static inline void klispT_tail_call_si(klisp_State *K, TValue top, TValue ptree, K->next_env = env; K->next_xparams = op->extra; K->next_si = si; + klisp_unlock(K); } #define ktail_call_si(K_, op_, p_, e_, si_) \ @@ -517,13 +528,18 @@ static inline void klispT_tail_call_si(klisp_State *K, TValue top, TValue ptree, #define ktail_call(K_, op_, p_, e_) \ { klisp_State *K__ = (K_); \ TValue op__ = (op_); \ - (ktail_call_si(K__, op__, p_, e_, ktry_get_si(K__, op__))); } \ + klisp_lock(K); \ + TValue si__ = ktry_get_si(K__, op__); \ + klisp_unlock(K); \ + (ktail_call_si(K__, op__, p_, e_, si__)); } \ -#define ktail_eval(K_, p_, e_) \ - { klisp_State *K__ = (K_); \ - TValue p__ = (p_); \ - klispT_tail_call_si(K__, G(K__)->eval_op, p__, (e_), \ - ktry_get_si(K__, p__)); \ +#define ktail_eval(K_, p_, e_) \ + { klisp_State *K__ = (K_); \ + TValue p__ = (p_); \ + klisp_lock(K); \ + TValue si__ = ktry_get_si(K__, p__); \ + klisp_unlock(K); \ + klispT_tail_call_si(K__, G(K__)->eval_op, p__, (e_), si__); \ return; } void do_interception(klisp_State *K); @@ -537,6 +553,7 @@ void klisp_close (klisp_State *K); /* XXX: this is ugly but we can't include kpair.h here so... */ /* MAYBE: move car & cdr to kobject.h */ /* TODO: use these where appropriate */ +/* TODO LOCK, thread local */ #define kcurr_input_port(K) (tv2pair(G(K)->kd_in_port_key)->cdr) #define kcurr_output_port(K) (tv2pair(G(K)->kd_out_port_key)->cdr) #define kcurr_error_port(K) (tv2pair(G(K)->kd_error_port_key)->cdr)