diff options
author | Björn Gustavsson <[email protected]> | 2012-03-06 06:44:40 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2012-06-25 14:31:18 +0200 |
commit | eb94e726d55aa941148da0e564d8f84376fb0738 (patch) | |
tree | b181629f2e050bf60ef24a794ea9bcb7394c21af /erts/emulator/beam | |
parent | 45e610c954a4ae028b4eb67c1545745b6dacab73 (diff) | |
download | otp-eb94e726d55aa941148da0e564d8f84376fb0738.tar.gz otp-eb94e726d55aa941148da0e564d8f84376fb0738.tar.bz2 otp-eb94e726d55aa941148da0e564d8f84376fb0738.zip |
Make the lock check in erts_is_code_ix_locked() stronger
Make sure that the the currently running thread has the lock,
not only that that some thread has the lock.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/code_ix.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/erts/emulator/beam/code_ix.c b/erts/emulator/beam/code_ix.c index ae4cca1e58..8025058ee0 100644 --- a/erts/emulator/beam/code_ix.c +++ b/erts/emulator/beam/code_ix.c @@ -44,6 +44,10 @@ struct code_ix_queue_item { static struct code_ix_queue_item* the_code_ix_queue = NULL; static erts_smp_mtx_t the_code_ix_queue_lock; +#ifdef ERTS_ENABLE_LOCK_CHECK +static erts_tsd_key_t has_code_write_permission; +#endif + void erts_code_ix_init(void) { /* We start emulator by initializing preloaded modules @@ -53,6 +57,9 @@ void erts_code_ix_init(void) erts_smp_atomic32_init_nob(&the_active_code_index, 0); erts_smp_atomic32_init_nob(&the_staging_code_index, 0); erts_smp_mtx_init(&the_code_ix_queue_lock, "code_ix_queue"); +#ifdef ERTS_ENABLE_LOCK_CHECK + erts_tsd_key_create(&has_code_write_permission); +#endif CIX_TRACE("init"); } @@ -112,6 +119,9 @@ int erts_try_seize_code_write_permission(Process* c_p) success = !the_code_ix_lock; if (success) { the_code_ix_lock = 1; +#ifdef ERTS_ENABLE_LOCK_CHECK + erts_tsd_set(has_code_write_permission, (void *) 1); +#endif } else { /* Already locked */ struct code_ix_queue_item* qitem; @@ -128,6 +138,7 @@ int erts_try_seize_code_write_permission(Process* c_p) void erts_release_code_write_permission(void) { + ERTS_SMP_LC_ASSERT(erts_is_code_ix_locked()); erts_smp_mtx_lock(&the_code_ix_queue_lock); while (the_code_ix_queue != NULL) { /* unleash the entire herd */ struct code_ix_queue_item* qitem = the_code_ix_queue; @@ -141,12 +152,15 @@ void erts_release_code_write_permission(void) erts_free(ERTS_ALC_T_CODE_IX_LOCK_Q, qitem); } the_code_ix_lock = 0; +#ifdef ERTS_ENABLE_LOCK_CHECK + erts_tsd_set(has_code_write_permission, (void *) 0); +#endif erts_smp_mtx_unlock(&the_code_ix_queue_lock); } #ifdef ERTS_ENABLE_LOCK_CHECK int erts_is_code_ix_locked(void) { - return the_code_ix_lock; + return the_code_ix_lock && erts_tsd_get(has_code_write_permission); } #endif |