From 166032bddf9a14f3ea6252724532039a1113612d Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 11 Jan 2012 21:01:49 +0100 Subject: erts: Refactor Module struct --- erts/emulator/beam/module.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index b93b1ad09a..39baabdf54 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -61,13 +61,13 @@ static Module* module_alloc(Module* tmpl) Module* obj = (Module*) erts_alloc(ERTS_ALC_T_MODULE, sizeof(Module)); obj->module = tmpl->module; - obj->code = 0; - obj->old_code = 0; - obj->code_length = 0; - obj->old_code_length = 0; + obj->curr.code = 0; + obj->old.code = 0; + obj->curr.code_length = 0; + obj->old.code_length = 0; obj->slot.index = -1; - obj->nif = NULL; - obj->old_nif = NULL; + obj->curr.nif = NULL; + obj->old.nif = NULL; return obj; } -- cgit v1.2.3 From aac03c5e9ccf9f6066e291a7c87dd58c1181c227 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 19 Jan 2012 12:10:20 +0100 Subject: erts: Multiple module tables using code_ix --- erts/emulator/beam/module.c | 109 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 15 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 39baabdf54..1c629cd614 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -26,10 +26,16 @@ #include "global.h" #include "module.h" +#ifdef DEBUG +# define IF_DEBUG(x) x +#else +# define IF_DEBUG(x) +#endif + #define MODULE_SIZE 50 #define MODULE_LIMIT (64*1024) -static IndexTable module_table; +static IndexTable module_tables[ERTS_NUM_CODE_IX]; /* * SMP note: We don't need to look accesses to the module table because @@ -40,7 +46,7 @@ static IndexTable module_table; void module_info(int to, void *to_arg) { - index_info(to, to_arg, &module_table); + index_info(to, to_arg, &module_tables[erts_active_code_ix()]); } @@ -71,33 +77,44 @@ static Module* module_alloc(Module* tmpl) return obj; } +static void module_free(Module* mod) +{ + erts_free(ERTS_ALC_T_MODULE, mod); +} void init_module_table(void) { HashFunctions f; + int i; f.hash = (H_FUN) module_hash; f.cmp = (HCMP_FUN) module_cmp; f.alloc = (HALLOC_FUN) module_alloc; - f.free = 0; + f.free = (HFREE_FUN) module_free; - erts_index_init(ERTS_ALC_T_MODULE_TABLE, &module_table, "module_code", - MODULE_SIZE, MODULE_LIMIT, f); + for (i = 0; i < ERTS_NUM_CODE_IX; i++) { + erts_index_init(ERTS_ALC_T_MODULE_TABLE, &module_tables[i], "module_code", + MODULE_SIZE, MODULE_LIMIT, f); + } } Module* -erts_get_module(Eterm mod) +erts_get_module(Eterm mod, ErtsCodeIndex code_ix) { Module e; int index; + IndexTable* mod_tab; ASSERT(is_atom(mod)); + + mod_tab = &module_tables[code_ix]; + e.module = atom_val(mod); - index = index_get(&module_table, (void*) &e); + index = index_get(mod_tab, (void*) &e); if (index == -1) { return NULL; } else { - return (Module*) erts_index_lookup(&module_table, index); + return (Module*) erts_index_lookup(mod_tab, index); } } @@ -106,26 +123,88 @@ erts_put_module(Eterm mod) { Module e; int index; + IndexTable* mod_tab; ASSERT(is_atom(mod)); ERTS_SMP_LC_ASSERT(erts_initialized == 0 || erts_smp_thr_progress_is_blocking()); + + mod_tab = &module_tables[erts_loader_code_ix()]; e.module = atom_val(mod); - index = index_put(&module_table, (void*) &e); - return (Module*) erts_index_lookup(&module_table, index); + index = index_put(mod_tab, (void*) &e); + return (Module*) erts_index_lookup(mod_tab, index); } -Module *module_code(int i) +Module *module_code(int i, ErtsCodeIndex code_ix) { - return (Module*) erts_index_lookup(&module_table, i); + return (Module*) erts_index_lookup(&module_tables[code_ix], i); } -int module_code_size(void) +int module_code_size(ErtsCodeIndex code_ix) { - return module_table.entries; + return module_tables[code_ix].entries; } int module_table_sz(void) { - return index_table_sz(&module_table); + return index_table_sz(&module_tables[erts_active_code_ix()]); +} + +#ifdef DEBUG +static ErtsCodeIndex dbg_load_code_ix = 0; +#endif + +static int entries_at_start_load = 0; + +void module_start_load(void) +{ + IndexTable* src = &module_tables[erts_active_code_ix()]; + IndexTable* dst = &module_tables[erts_loader_code_ix()]; + Module* src_mod; + Module* dst_mod; + int i; + + ASSERT(dbg_load_code_ix == -1); + ASSERT(dst->entries <= src->entries); + + /* + * Make sure our existing modules are up-to-date + */ + for (i = 0; i < dst->entries; i++) { + src_mod = (Module*) erts_index_lookup(src, i); + dst_mod = (Module*) erts_index_lookup(dst, i); + ASSERT(src_mod->module == dst_mod->module); + + dst_mod->curr = src_mod->curr; + dst_mod->old = src_mod->old; + } + + /* + * Copy all new modules from active table + */ + for (i = dst->entries; i < src->entries; i++) { + src_mod = (Module*) erts_index_lookup(src, i); + dst_mod = (Module*) erts_index_lookup(dst, index_put(dst, src_mod)); + ASSERT(dst_mod != src_mod); + + dst_mod->curr = src_mod->curr; + dst_mod->old = src_mod->old; + } + entries_at_start_load = dst->entries; + + IF_DEBUG(dbg_load_code_ix = erts_loader_code_ix()); +} + +void module_end_load(int commit) +{ + ASSERT(dbg_load_code_ix == erts_loader_code_ix()); + + if (!commit) { /* abort */ + IndexTable* tab = &module_tables[erts_loader_code_ix()]; + + ASSERT(entries_at_start_load <= tab->entries); + index_erase_latest_from(tab, entries_at_start_load); + } + + IF_DEBUG(dbg_load_code_ix = -1); } -- cgit v1.2.3 From dd3036c1a152c66a33b4d298cbbf428c075153b7 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 19 Jan 2012 21:16:29 +0100 Subject: First try at non-blocking code loading! Implemented some code_ix locks and commented calls to erts_smp_thr_progress_block() --- erts/emulator/beam/module.c | 1 + 1 file changed, 1 insertion(+) (limited to 'erts/emulator/beam/module.c') 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()]; -- cgit v1.2.3 From 48e662a63e80c4f358be1ba062615ff56e09f331 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 23 Jan 2012 16:46:53 +0100 Subject: erts: Refactor new function index_put_entry() Same as index_put() but returns pointer to entry instead of index integer. --- erts/emulator/beam/module.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index ab4f387982..f326aecebf 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -122,7 +122,6 @@ Module* erts_put_module(Eterm mod) { Module e; - int index; IndexTable* mod_tab; ASSERT(is_atom(mod)); @@ -132,8 +131,7 @@ erts_put_module(Eterm mod) mod_tab = &module_tables[erts_loader_code_ix()]; e.module = atom_val(mod); - index = index_put(mod_tab, (void*) &e); - return (Module*) erts_index_lookup(mod_tab, index); + return (Module*) index_put_entry(mod_tab, (void*) &e); } Module *module_code(int i, ErtsCodeIndex code_ix) @@ -185,7 +183,7 @@ void module_start_load(void) */ for (i = dst->entries; i < src->entries; i++) { src_mod = (Module*) erts_index_lookup(src, i); - dst_mod = (Module*) erts_index_lookup(dst, index_put(dst, src_mod)); + dst_mod = (Module*) index_put_entry(dst, src_mod); ASSERT(dst_mod != src_mod); dst_mod->curr = src_mod->curr; -- cgit v1.2.3 From a23f25a3014dbad01d2016dc4e6d6df9d59ba64c Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 24 Jan 2012 15:42:02 +0100 Subject: erts: Rename "loader" code_ix as "staging" code_ix Staging is a better and more general name as does not necessary need to involve code loading (can be deletion, tracing, etc). --- erts/emulator/beam/module.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index f326aecebf..b0a3bd1fab 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -129,7 +129,7 @@ erts_put_module(Eterm mod) || erts_is_code_ix_locked() || erts_smp_thr_progress_is_blocking()); - mod_tab = &module_tables[erts_loader_code_ix()]; + mod_tab = &module_tables[erts_staging_code_ix()]; e.module = atom_val(mod); return (Module*) index_put_entry(mod_tab, (void*) &e); } @@ -155,10 +155,10 @@ static ErtsCodeIndex dbg_load_code_ix = 0; static int entries_at_start_load = 0; -void module_start_load(void) +void module_start_staging(void) { IndexTable* src = &module_tables[erts_active_code_ix()]; - IndexTable* dst = &module_tables[erts_loader_code_ix()]; + IndexTable* dst = &module_tables[erts_staging_code_ix()]; Module* src_mod; Module* dst_mod; int i; @@ -191,15 +191,15 @@ void module_start_load(void) } entries_at_start_load = dst->entries; - IF_DEBUG(dbg_load_code_ix = erts_loader_code_ix()); + IF_DEBUG(dbg_load_code_ix = erts_staging_code_ix()); } -void module_end_load(int commit) +void module_end_staging(int commit) { - ASSERT(dbg_load_code_ix == erts_loader_code_ix()); + ASSERT(dbg_load_code_ix == erts_staging_code_ix()); if (!commit) { /* abort */ - IndexTable* tab = &module_tables[erts_loader_code_ix()]; + IndexTable* tab = &module_tables[erts_staging_code_ix()]; ASSERT(entries_at_start_load <= tab->entries); index_erase_latest_from(tab, entries_at_start_load); -- cgit v1.2.3 From e60c9cd4356a91c10657b5de86af8279ccd6eb79 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 26 Jan 2012 16:25:26 +0100 Subject: erts: Move number-of-breakpoint counter from code to Module struct The is a refactoring in preparation to add a counter in Module struct for export entry tracing. It is nicer if the two are kept together. --- erts/emulator/beam/module.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index b0a3bd1fab..4174f59446 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -74,6 +74,8 @@ static Module* module_alloc(Module* tmpl) obj->slot.index = -1; obj->curr.nif = NULL; obj->old.nif = NULL; + obj->curr.num_breakpoints = 0; + obj->old.num_breakpoints = 0; return obj; } -- cgit v1.2.3 From cd366260e689d97845c56f30ef960853099465ab Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 26 Jan 2012 19:34:22 +0100 Subject: erts: Keep count of number of global traced functions per module --- erts/emulator/beam/module.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 4174f59446..26c73fff1a 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -76,6 +76,8 @@ static Module* module_alloc(Module* tmpl) obj->old.nif = NULL; obj->curr.num_breakpoints = 0; obj->old.num_breakpoints = 0; + obj->curr.num_traced_exports = 0; + obj->old.num_traced_exports = 0; return obj; } -- cgit v1.2.3 From 7cb4725bcf18f3158e60750ea658e51ab4586e31 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 31 Jan 2012 14:24:40 +0100 Subject: erts: Refactor code_ix Move implementation from beam_load into new file code_ix.c and module.c and make some function inline. --- erts/emulator/beam/module.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 26c73fff1a..d3fd3f118d 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -37,6 +37,8 @@ static IndexTable module_tables[ERTS_NUM_CODE_IX]; +erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; + /* * SMP note: We don't need to look accesses to the module table because * there is one only scheduler thread when we update it. @@ -100,6 +102,10 @@ void init_module_table(void) erts_index_init(ERTS_ALC_T_MODULE_TABLE, &module_tables[i], "module_code", MODULE_SIZE, MODULE_LIMIT, f); } + + for (i=0; i Date: Fri, 3 Feb 2012 18:13:37 +0100 Subject: erts: Refactor more renaming as "staging" --- erts/emulator/beam/module.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index d3fd3f118d..6d5f1528b4 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -163,7 +163,7 @@ int module_table_sz(void) static ErtsCodeIndex dbg_load_code_ix = 0; #endif -static int entries_at_start_load = 0; +static int entries_at_start_staging = 0; void module_start_staging(void) { @@ -199,8 +199,8 @@ void module_start_staging(void) dst_mod->curr = src_mod->curr; dst_mod->old = src_mod->old; } - entries_at_start_load = dst->entries; + entries_at_start_staging = dst->entries; IF_DEBUG(dbg_load_code_ix = erts_staging_code_ix()); } @@ -211,8 +211,8 @@ void module_end_staging(int commit) if (!commit) { /* abort */ IndexTable* tab = &module_tables[erts_staging_code_ix()]; - ASSERT(entries_at_start_load <= tab->entries); - index_erase_latest_from(tab, entries_at_start_load); + ASSERT(entries_at_start_staging <= tab->entries); + index_erase_latest_from(tab, entries_at_start_staging); } IF_DEBUG(dbg_load_code_ix = -1); -- cgit v1.2.3 From c2f62a3813c5c2bd2bb691df816d5fc2fb17206a Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 7 Feb 2012 16:19:43 +0100 Subject: erts: Fix memory query for non-blocking module table --- erts/emulator/beam/module.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 6d5f1528b4..1dab24e96a 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -39,9 +39,12 @@ static IndexTable module_tables[ERTS_NUM_CODE_IX]; erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; -/* - * SMP note: We don't need to look accesses to the module table because - * there is one only scheduler thread when we update it. +static erts_smp_atomic_t tot_module_bytes; + +/* SMP note: Active module table lookup and current module instance can be + * read without any locks. Old module instances are protected by + * "the_old_code_rwlocks" as purging is done on active module table. + * Staging table is protected by the "code_ix lock". */ #include "erl_smp.h" @@ -67,6 +70,7 @@ static int module_cmp(Module* tmpl, Module* obj) static Module* module_alloc(Module* tmpl) { Module* obj = (Module*) erts_alloc(ERTS_ALC_T_MODULE, sizeof(Module)); + erts_smp_atomic_add_nob(&tot_module_bytes, sizeof(Module)); obj->module = tmpl->module; obj->curr.code = 0; @@ -86,6 +90,7 @@ static Module* module_alloc(Module* tmpl) static void module_free(Module* mod) { erts_free(ERTS_ALC_T_MODULE, mod); + erts_smp_atomic_add_nob(&tot_module_bytes, -sizeof(Module)); } void init_module_table(void) @@ -106,6 +111,7 @@ void init_module_table(void) for (i=0; ientries <= src->entries); @@ -191,6 +203,7 @@ void module_start_staging(void) /* * Copy all new modules from active table */ + oldsz = index_table_sz(dst); for (i = dst->entries; i < src->entries; i++) { src_mod = (Module*) erts_index_lookup(src, i); dst_mod = (Module*) index_put_entry(dst, src_mod); @@ -199,6 +212,8 @@ void module_start_staging(void) dst_mod->curr = src_mod->curr; dst_mod->old = src_mod->old; } + newsz = index_table_sz(dst); + erts_smp_atomic_add_nob(&tot_module_bytes, (newsz - oldsz)); entries_at_start_staging = dst->entries; IF_DEBUG(dbg_load_code_ix = erts_staging_code_ix()); @@ -210,9 +225,13 @@ void module_end_staging(int commit) if (!commit) { /* abort */ IndexTable* tab = &module_tables[erts_staging_code_ix()]; + int oldsz, newsz; ASSERT(entries_at_start_staging <= tab->entries); + oldsz = index_table_sz(tab); index_erase_latest_from(tab, entries_at_start_staging); + newsz = index_table_sz(tab); + erts_smp_atomic_add_nob(&tot_module_bytes, (newsz - oldsz)); } IF_DEBUG(dbg_load_code_ix = -1); -- cgit v1.2.3 From 17c62a8d1158e2c13be403e62d81140c705a8444 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 21 Feb 2012 20:43:23 +0100 Subject: erts: Switch order between code_ix lock and thread blocking Make for simpler code when we just can block threads and continue without having to release code_ix lock and repeat code lookups to avoid race. --- erts/emulator/beam/module.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'erts/emulator/beam/module.c') diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 1dab24e96a..1ef71cda79 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -144,8 +144,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()); + || erts_is_code_ix_locked()); mod_tab = &module_tables[erts_staging_code_ix()]; e.module = atom_val(mod); -- cgit v1.2.3