aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-01-19 21:16:29 +0100
committerSverker Eriksson <[email protected]>2012-02-21 12:23:00 +0100
commitdd3036c1a152c66a33b4d298cbbf428c075153b7 (patch)
tree8c0702574106166c2cbf1bcb2a9ac09bec612837 /erts/emulator/beam
parentf81dd5da827e86af3bf6fedadeaaeb5fb3347c32 (diff)
downloadotp-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()
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_bif_load.c73
-rw-r--r--erts/emulator/beam/beam_load.c33
-rw-r--r--erts/emulator/beam/code_ix.h3
-rw-r--r--erts/emulator/beam/erl_lock_check.c2
-rw-r--r--erts/emulator/beam/module.c1
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()];