Add a simple spinlock around __jit_debug_descriptor manipulation.

This commit is contained in:
Peter Cawley 2016-05-01 18:24:13 +01:00
parent 7b26e9c998
commit b4d83eda17

View File

@ -725,6 +725,22 @@ static void gdbjit_buildobj(GDBJITctx *ctx)
#undef SECTALIGN #undef SECTALIGN
/* -- Thread safety ------------------------------------------------------- */
static int gdbjit_lock;
static void gdbjit_lock_acquire()
{
while (__sync_lock_test_and_set(&gdbjit_lock, 1)) {
/* Just spin; futexes or pthreads aren't worth the portability cost. */
}
}
static void gdbjit_lock_release()
{
__sync_lock_release(&gdbjit_lock);
}
/* -- Interface to GDB JIT API -------------------------------------------- */ /* -- Interface to GDB JIT API -------------------------------------------- */
/* Add new entry to GDB JIT symbol chain. */ /* Add new entry to GDB JIT symbol chain. */
@ -738,6 +754,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx)
ctx->T->gdbjit_entry = (void *)eo; ctx->T->gdbjit_entry = (void *)eo;
/* Link new entry to chain and register it. */ /* Link new entry to chain and register it. */
eo->entry.prev_entry = NULL; eo->entry.prev_entry = NULL;
gdbjit_lock_acquire();
eo->entry.next_entry = __jit_debug_descriptor.first_entry; eo->entry.next_entry = __jit_debug_descriptor.first_entry;
if (eo->entry.next_entry) if (eo->entry.next_entry)
eo->entry.next_entry->prev_entry = &eo->entry; eo->entry.next_entry->prev_entry = &eo->entry;
@ -747,6 +764,7 @@ static void gdbjit_newentry(lua_State *L, GDBJITctx *ctx)
__jit_debug_descriptor.relevant_entry = &eo->entry; __jit_debug_descriptor.relevant_entry = &eo->entry;
__jit_debug_descriptor.action_flag = GDBJIT_REGISTER; __jit_debug_descriptor.action_flag = GDBJIT_REGISTER;
__jit_debug_register_code(); __jit_debug_register_code();
gdbjit_lock_release();
} }
/* Add debug info for newly compiled trace and notify GDB. */ /* Add debug info for newly compiled trace and notify GDB. */
@ -778,6 +796,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T)
{ {
GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry; GDBJITentryobj *eo = (GDBJITentryobj *)T->gdbjit_entry;
if (eo) { if (eo) {
gdbjit_lock_acquire();
if (eo->entry.prev_entry) if (eo->entry.prev_entry)
eo->entry.prev_entry->next_entry = eo->entry.next_entry; eo->entry.prev_entry->next_entry = eo->entry.next_entry;
else else
@ -787,6 +806,7 @@ void lj_gdbjit_deltrace(jit_State *J, GCtrace *T)
__jit_debug_descriptor.relevant_entry = &eo->entry; __jit_debug_descriptor.relevant_entry = &eo->entry;
__jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER; __jit_debug_descriptor.action_flag = GDBJIT_UNREGISTER;
__jit_debug_register_code(); __jit_debug_register_code();
gdbjit_lock_release();
lj_mem_free(J2G(J), eo, eo->sz); lj_mem_free(J2G(J), eo, eo->sz);
} }
} }