aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_bif_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/beam_bif_load.c')
-rw-r--r--erts/emulator/beam/beam_bif_load.c182
1 files changed, 113 insertions, 69 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 346b64033b..458e4794bd 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -134,16 +134,22 @@ BIF_RETTYPE purge_module_1(BIF_ALIST_1)
BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
{
Module* modp;
+ Eterm res;
+ ErtsCodeIndex code_ix;
if (is_not_atom(BIF_ARG_1)) {
BIF_ERROR(BIF_P, BADARG);
}
- if ((modp = erts_get_module(BIF_ARG_1)) == NULL) {
+ code_ix = erts_active_code_ix();
+ if ((modp = erts_get_module(BIF_ARG_1, code_ix)) == NULL) {
return am_undefined;
}
- return ((modp->curr.code && is_native(modp->curr.code)) ||
+ erts_rlock_old_code(code_ix);
+ res = ((modp->curr.code && is_native(modp->curr.code)) ||
(modp->old.code != 0 && is_native(modp->old.code))) ?
am_true : am_false;
+ erts_runlock_old_code(code_ix);
+ return res;
}
BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3)
@@ -164,18 +170,23 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3)
BIF_RETTYPE
check_old_code_1(BIF_ALIST_1)
{
+ ErtsCodeIndex code_ix;
Module* modp;
+ Eterm res = am_false;
if (is_not_atom(BIF_ARG_1)) {
BIF_ERROR(BIF_P, BADARG);
}
- modp = erts_get_module(BIF_ARG_1);
- if (modp == NULL) { /* Doesn't exist. */
- BIF_RET(am_false);
- } else if (modp->old.code == NULL) { /* No old code. */
- BIF_RET(am_false);
+ code_ix = erts_active_code_ix();
+ modp = erts_get_module(BIF_ARG_1, code_ix);
+ if (modp != NULL) {
+ erts_rlock_old_code(code_ix);
+ if (modp->old.code != NULL) {
+ res = am_true;
+ }
+ erts_runlock_old_code(code_ix);
}
- BIF_RET(am_true);
+ BIF_RET(res);
}
Eterm
@@ -189,13 +200,19 @@ check_process_code_2(BIF_ALIST_2)
}
if (is_internal_pid(BIF_ARG_1)) {
Eterm res;
+ ErtsCodeIndex code_ix;
if (internal_pid_index(BIF_ARG_1) >= erts_max_processes)
goto error;
- modp = erts_get_module(BIF_ARG_2);
+ code_ix = erts_active_code_ix();
+ modp = erts_get_module(BIF_ARG_2, code_ix);
if (modp == NULL) { /* Doesn't exist. */
return am_false;
- } else if (modp->old.code == NULL) { /* No old code. */
- 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;
+ }
}
#ifdef ERTS_SMP
@@ -212,6 +229,7 @@ check_process_code_2(BIF_ALIST_2)
BIF_ARG_1, BIF_ARG_2);
}
res = check_process_code(rp, modp);
+ erts_runlock_old_code(code_ix);
#ifdef ERTS_SMP
if (BIF_P != rp) {
erts_resume(rp, ERTS_PROC_LOCK_MAIN);
@@ -232,6 +250,7 @@ check_process_code_2(BIF_ALIST_2)
BIF_RETTYPE delete_module_1(BIF_ALIST_1)
{
+ ErtsCodeIndex code_ix;
int res;
if (is_not_atom(BIF_ARG_1))
@@ -240,8 +259,9 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1)
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
erts_smp_thr_progress_block();
+ code_ix = erts_active_code_ix();
{
- Module *modp = erts_get_module(BIF_ARG_1);
+ Module *modp = erts_get_module(BIF_ARG_1, code_ix);
if (!modp) {
res = am_undefined;
}
@@ -272,16 +292,20 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1)
BIF_RETTYPE module_loaded_1(BIF_ALIST_1)
{
Module* modp;
+ ErtsCodeIndex code_ix;
+ Eterm res = am_false;
if (is_not_atom(BIF_ARG_1)) {
BIF_ERROR(BIF_P, BADARG);
}
- if ((modp = erts_get_module(BIF_ARG_1)) == NULL ||
- modp->curr.code == NULL ||
- modp->curr.code[MI_ON_LOAD_FUNCTION_PTR] != 0) {
- BIF_RET(am_false);
+ code_ix = erts_active_code_ix();
+ if ((modp = erts_get_module(BIF_ARG_1, code_ix)) != NULL) {
+ if (modp->curr.code != NULL
+ && modp->curr.code[MI_ON_LOAD_FUNCTION_PTR] == 0) {
+ res = am_true;
+ }
}
- BIF_RET(am_true);
+ BIF_RET(res);
}
BIF_RETTYPE pre_loaded_0(BIF_ALIST_0)
@@ -291,27 +315,28 @@ BIF_RETTYPE pre_loaded_0(BIF_ALIST_0)
BIF_RETTYPE loaded_0(BIF_ALIST_0)
{
+ ErtsCodeIndex code_ix = erts_active_code_ix();
+ Module* modp;
Eterm previous = NIL;
Eterm* hp;
int i;
int j = 0;
-
- for (i = 0; i < module_code_size(); i++) {
- if (module_code(i) != NULL &&
- ((module_code(i)->curr.code_length != 0) ||
- (module_code(i)->old.code_length != 0))) {
+
+ for (i = 0; i < module_code_size(code_ix); i++) {
+ if ((modp = module_code(i, code_ix)) != NULL &&
+ ((modp->curr.code_length != 0) ||
+ (modp->old.code_length != 0))) {
j++;
}
}
if (j > 0) {
hp = HAlloc(BIF_P, j*2);
- for (i = 0; i < module_code_size(); i++) {
- if (module_code(i) != NULL &&
- ((module_code(i)->curr.code_length != 0) ||
- (module_code(i)->old.code_length != 0))) {
- previous = CONS(hp, make_atom(module_code(i)->module),
- previous);
+ for (i = 0; i < module_code_size(code_ix); i++) {
+ if ((modp=module_code(i,code_ix)) != NULL &&
+ ((modp->curr.code_length != 0) ||
+ (modp->old.code_length != 0))) {
+ previous = CONS(hp, make_atom(modp->module), previous);
hp += 2;
}
}
@@ -321,25 +346,30 @@ BIF_RETTYPE loaded_0(BIF_ALIST_0)
BIF_RETTYPE call_on_load_function_1(BIF_ALIST_1)
{
- Module* modp = erts_get_module(BIF_ARG_1);
- Eterm on_load;
+ ErtsCodeIndex code_ix = erts_active_code_ix(); /*SVERK ?? on_load ?? */
+ Module* modp = erts_get_module(BIF_ARG_1, code_ix);
+ Eterm on_load = 0;
- if (!modp || modp->curr.code == 0) {
- error:
- BIF_ERROR(BIF_P, BADARG);
+ if (modp) {
+ if (modp->curr.code) {
+ on_load = modp->curr.code[MI_ON_LOAD_FUNCTION_PTR];
+ }
}
- if ((on_load = modp->curr.code[MI_ON_LOAD_FUNCTION_PTR]) == 0) {
- goto error;
+ if (on_load) {
+ BIF_TRAP_CODE_PTR_0(BIF_P, on_load);
+ }
+ else {
+ BIF_ERROR(BIF_P, BADARG);
}
- BIF_TRAP_CODE_PTR_0(BIF_P, on_load);
}
BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
{
ErtsCodeIndex code_ix;
- Module* modp = erts_get_module(BIF_ARG_1);
+ Module* modp;
Eterm on_load;
code_ix = erts_active_code_ix();
+ modp = erts_get_module(BIF_ARG_1, code_ix);
if (!modp || modp->curr.code == 0) {
error:
@@ -439,6 +469,8 @@ 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.
*/
@@ -645,50 +677,62 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
static int
purge_module(int module)
{
+ ErtsCodeIndex code_ix;
BeamInstr* code;
BeamInstr* end;
Module* modp;
+ int ret;
+
+ erts_lock_code_ix();
+ code_ix = erts_active_code_ix();
/*
* Correct module?
*/
- if ((modp = erts_get_module(make_atom(module))) == NULL) {
- return -2;
+ if ((modp = erts_get_module(make_atom(module), code_ix)) == NULL) {
+ ret = -2;
}
+ else {
+ erts_rwlock_old_code(code_ix);
- /*
- * Any code to purge?
- */
- if (modp->old.code == 0) {
- return -1;
- }
+ /*
+ * Any code to purge?
+ */
+ if (modp->old.code == 0) {
+ ret = -1;
+ }
+ else {
+ /*
+ * Unload any NIF library
+ */
+ if (modp->old.nif != NULL) {
+ erts_unload_nif(modp->old.nif);
+ modp->old.nif = NULL;
+ }
- /*
- * Unload any NIF library
- */
- if (modp->old.nif != NULL) {
- erts_unload_nif(modp->old.nif);
- modp->old.nif = NULL;
+ /*
+ * Remove the old code.
+ */
+ ASSERT(erts_total_code_size >= modp->old.code_length);
+ erts_total_code_size -= modp->old.code_length;
+ code = modp->old.code;
+ end = (BeamInstr *)((char *)code + modp->old.code_length);
+ erts_cleanup_funs_on_purge(code, end);
+ beam_catches_delmod(modp->old.catches, code, modp->old.code_length,
+ code_ix);
+ decrement_refc(code);
+ erts_free(ERTS_ALC_T_CODE, (void *) code);
+ modp->old.code = NULL;
+ modp->old.code_length = 0;
+ modp->old.catches = BEAM_CATCHES_NIL;
+ remove_from_address_table(code);
+ ret = 0;
+ }
+ erts_rwunlock_old_code(code_ix);
}
-
- /*
- * Remove the old code.
- */
- ASSERT(erts_total_code_size >= modp->old.code_length);
- erts_total_code_size -= modp->old.code_length;
- code = modp->old.code;
- end = (BeamInstr *)((char *)code + modp->old.code_length);
- erts_cleanup_funs_on_purge(code, end);
- beam_catches_delmod(modp->old.catches, code, modp->old.code_length,
- erts_active_code_ix());
- decrement_refc(code);
- erts_free(ERTS_ALC_T_CODE, (void *) code);
- modp->old.code = NULL;
- modp->old.code_length = 0;
- modp->old.catches = BEAM_CATCHES_NIL;
- remove_from_address_table(code);
- return 0;
+ erts_unlock_code_ix();
+ return ret;
}
static void