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:
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)