diff options
author | Sverker Eriksson <[email protected]> | 2012-01-19 21:16:29 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2012-02-21 12:23:00 +0100 |
commit | dd3036c1a152c66a33b4d298cbbf428c075153b7 (patch) | |
tree | 8c0702574106166c2cbf1bcb2a9ac09bec612837 | |
parent | f81dd5da827e86af3bf6fedadeaaeb5fb3347c32 (diff) | |
download | otp-dd3036c1a152c66a33b4d298cbbf428c075153b7.tar.gz otp-dd3036c1a152c66a33b4d298cbbf428c075153b7.tar.bz2 otp-dd3036c1a152c66a33b4d298cbbf428c075153b7.zip |
First try at non-blocking code loading!
Implemented some code_ix locks
and commented calls to erts_smp_thr_progress_block()
-rw-r--r-- | erts/emulator/beam/beam_bif_load.c | 73 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 33 | ||||
-rw-r--r-- | erts/emulator/beam/code_ix.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_lock_check.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/module.c | 1 |
5 files changed, 75 insertions, 37 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 8fe11746ee..f21598a8b7 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -79,11 +79,11 @@ load_module_2(BIF_ALIST_2) BIF_RET(res); } - /* + /*SVERK * Stop all other processes and finish the loading of the module. - */ + * erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); - erts_smp_thr_progress_block(); + erts_smp_thr_progress_block();*/ erts_lock_code_ix(); erts_start_loader_code_ix(); @@ -105,8 +105,9 @@ load_module_2(BIF_ALIST_2) erts_unlock_code_ix(); + /*SVERK erts_smp_thr_progress_unblock(); - erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);*/ BIF_RET(res); } @@ -118,14 +119,17 @@ BIF_RETTYPE purge_module_1(BIF_ALIST_1) BIF_ERROR(BIF_P, BADARG); } + /*SVERK erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); - erts_export_consolidate(erts_active_code_ix()); + erts_export_consolidate(erts_active_code_ix());*/ + purge_res = purge_module(atom_val(BIF_ARG_1)); + /*SVERK erts_smp_thr_progress_unblock(); - erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);*/ if (purge_res < 0) { BIF_ERROR(BIF_P, BADARG); @@ -158,14 +162,17 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3) { Eterm res; + /*SVERK erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); - erts_export_consolidate(erts_active_code_ix()); + erts_export_consolidate(erts_active_code_ix());*/ erts_lock_code_ix(); erts_start_loader_code_ix(); + erts_export_consolidate(erts_loader_code_ix()); + res = erts_make_stub_module(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); if (res == BIF_ARG_1) { @@ -176,8 +183,9 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3) } erts_unlock_code_ix(); + /*SVERK erts_smp_thr_progress_unblock(); - erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);*/ return res; } @@ -221,13 +229,13 @@ check_process_code_2(BIF_ALIST_2) modp = erts_get_module(BIF_ARG_2, code_ix); if (modp == NULL) { /* Doesn't exist. */ return am_false; - } else { - erts_rlock_old_code(code_ix); - if (modp->old.code == NULL) { /* No old code. */ - erts_runlock_old_code(code_ix); - return am_false; - } } + erts_rlock_old_code(code_ix); + if (modp->old.code == NULL) { /* No old code. */ + erts_runlock_old_code(code_ix); + return am_false; + } + erts_runlock_old_code(code_ix); #ifdef ERTS_SMP rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, @@ -242,7 +250,13 @@ check_process_code_2(BIF_ALIST_2) ERTS_BIF_YIELD2(bif_export[BIF_check_process_code_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } - res = check_process_code(rp, modp); + erts_rlock_old_code(code_ix); + if (modp->old.code != NULL) { /* must check again */ + res = check_process_code(rp, modp); + } + else { + res = am_false; + } erts_runlock_old_code(code_ix); #ifdef ERTS_SMP if (BIF_P != rp) { @@ -270,12 +284,14 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1) if (is_not_atom(BIF_ARG_1)) goto badarg; + /*SVERK erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); - erts_smp_thr_progress_block(); + erts_smp_thr_progress_block();*/ erts_lock_code_ix(); erts_start_loader_code_ix(); code_ix = erts_loader_code_ix(); + erts_export_consolidate(code_ix); { Module *modp = erts_get_module(BIF_ARG_1, code_ix); if (!modp) { @@ -303,8 +319,9 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1) } erts_unlock_code_ix(); + /*SVERK erts_smp_thr_progress_unblock(); - erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);*/ if (res == am_badarg) { badarg: @@ -410,7 +427,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); - /*SVERK What if code_ix is not active any more */ + /*SVERK Use code_ix switch instead */ if (BIF_ARG_2 == am_true) { int i; @@ -496,8 +513,6 @@ check_process_code(Process* rp, Module* modp) #define INSIDE(a) (start <= (a) && (a) < end) - ERTS_SMP_LC_ASSERT(erts_is_old_code_rlocked()); - /* * Pick up limits for the module. */ @@ -787,19 +802,19 @@ decrement_refc(BeamInstr* code) static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp) { -#ifdef ERTS_ENABLE_LOCK_CHECK -#ifdef ERTS_SMP - if (c_p && c_p_locks) - erts_proc_lc_chk_only_proc_main(c_p); - else -#endif - erts_lc_check_exact(NULL, 0); -#endif - /* * Clear breakpoints if any */ if (modp->curr.code != NULL && modp->curr.code[MI_NUM_BREAKPOINTS] > 0) { + ASSERT(!"SVERK What to do here"); +#ifdef ERTS_ENABLE_LOCK_CHECK +#ifdef ERTS_SMP + if (c_p && c_p_locks) + erts_proc_lc_chk_only_proc_main(c_p); + else +#endif + erts_lc_check_exact(NULL, 0); +#endif if (c_p && c_p_locks) erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 6cabc6f558..eaaef472b4 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -753,7 +753,7 @@ erts_finish_loading(LoaderState* stp, Process* c_p, * table which is not protected by any locks. */ - ERTS_SMP_LC_ASSERT(erts_initialized == 0 || + ERTS_SMP_LC_ASSERT(erts_initialized == 0 || erts_is_code_ix_locked() || erts_smp_thr_progress_is_blocking()); /* @@ -5949,6 +5949,9 @@ static int safe_mul(UWord a, UWord b, UWord* resp) static erts_smp_atomic32_t the_active_code_index; static erts_smp_atomic32_t the_loader_code_index; +static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ +static erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; + #ifdef DEBUG # define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_loader_code_ix()) #else @@ -5957,8 +5960,14 @@ static erts_smp_atomic32_t the_loader_code_index; void erts_code_ix_init(void) { + int i; + erts_smp_atomic32_init_nob(&the_active_code_index, 0); erts_smp_atomic32_init_nob(&the_loader_code_index, 0); + erts_smp_mtx_init_x(&sverk_code_ix_lock, "sverk_code_ix_lock", NIL); /*SVERK FIXME */ + for (i=0; i<ERTS_NUM_CODE_IX; i++) { + erts_smp_rwmtx_init_x(&the_old_code_rwlocks[i], "old_code", make_small(i)); + } CIX_TRACE("init"); } ErtsCodeIndex erts_active_code_ix(void) @@ -5974,13 +5983,22 @@ ErtsCodeIndex erts_loader_code_ix(void) */ void erts_lock_code_ix(void) { + erts_smp_mtx_lock(&sverk_code_ix_lock); /*SVERK FIXME */ } /* Unlock code_ix (resume first waiter) */ void erts_unlock_code_ix(void) { + erts_smp_mtx_unlock(&sverk_code_ix_lock); /*SVERK FIXME */ +} + +#ifdef ERTS_ENABLE_LOCK_CHECK +int erts_is_code_ix_locked(void) +{ + return erts_smp_lc_mtx_is_locked(&sverk_code_ix_lock); } +#endif void erts_start_loader_code_ix(void) { @@ -6020,24 +6038,25 @@ void erts_abort_loader_code_ix(void) /*SVERK old_code lock should maybe be part of module.c */ void erts_rwlock_old_code(ErtsCodeIndex code_ix) { + erts_smp_rwmtx_rwlock(&the_old_code_rwlocks[code_ix]); } void erts_rwunlock_old_code(ErtsCodeIndex code_ix) { + erts_smp_rwmtx_rwunlock(&the_old_code_rwlocks[code_ix]); } void erts_rlock_old_code(ErtsCodeIndex code_ix) { + erts_smp_rwmtx_rlock(&the_old_code_rwlocks[code_ix]); } void erts_runlock_old_code(ErtsCodeIndex code_ix) { + erts_smp_rwmtx_runlock(&the_old_code_rwlocks[code_ix]); } #ifdef ERTS_ENABLE_LOCK_CHECK -int erts_is_old_code_rlocked(void) -{ - return 1; -} -int erts_is_code_ix_locked(void) +int erts_is_old_code_rlocked(ErtsCodeIndex code_ix) { - return 1; + return erts_smp_lc_rwmtx_is_rlocked(&the_old_code_rwlocks[code_ix]); } #endif + diff --git a/erts/emulator/beam/code_ix.h b/erts/emulator/beam/code_ix.h index 585ddd3f20..43acd08ebf 100644 --- a/erts/emulator/beam/code_ix.h +++ b/erts/emulator/beam/code_ix.h @@ -48,6 +48,7 @@ void erts_lock_code_ix(void); /* Unlock code_ix (resume first waiter) */ void erts_unlock_code_ix(void); + void erts_start_loader_code_ix(void); void erts_commit_loader_code_ix(void); void erts_abort_loader_code_ix(void); @@ -58,7 +59,7 @@ void erts_rlock_old_code(ErtsCodeIndex); void erts_runlock_old_code(ErtsCodeIndex); #ifdef ERTS_ENABLE_LOCK_CHECK -int erts_is_old_code_rlocked(void); +int erts_is_old_code_rlocked(ErtsCodeIndex); int erts_is_code_ix_locked(void); #endif diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 09e85893c3..062e78b806 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -84,6 +84,8 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "reg_tab", NULL }, { "migration_info_update", NULL }, { "proc_main", "pid" }, + { "sverk_code_ix_lock", NULL }, /*SVERK FIXME */ + { "old_code", "address" }, #ifdef HIPE { "hipe_mfait_lock", NULL }, #endif diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 1c629cd614..ab4f387982 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -127,6 +127,7 @@ erts_put_module(Eterm mod) ASSERT(is_atom(mod)); ERTS_SMP_LC_ASSERT(erts_initialized == 0 + || erts_is_code_ix_locked() || erts_smp_thr_progress_is_blocking()); mod_tab = &module_tables[erts_loader_code_ix()]; |