diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/Makefile.in | 1 | ||||
-rw-r--r-- | erts/emulator/beam/beam_catches.h | 4 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 119 | ||||
-rw-r--r-- | erts/emulator/beam/code_ix.c | 110 | ||||
-rw-r--r-- | erts/emulator/beam/code_ix.h | 39 | ||||
-rw-r--r-- | erts/emulator/beam/module.c | 7 | ||||
-rw-r--r-- | erts/emulator/beam/module.h | 41 |
7 files changed, 192 insertions, 129 deletions
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index dad09383cf..942cde3af4 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -705,6 +705,7 @@ EMU_OBJS = \ $(OBJDIR)/beam_load.o $(OBJDIR)/beam_bif_load.o \ $(OBJDIR)/beam_debug.o $(OBJDIR)/beam_bp.o \ $(OBJDIR)/beam_catches.o \ + $(OBJDIR)/code_ix.o \ $(OBJDIR)/beam_ranges.o RUN_OBJS = \ diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h index 4a0e070c69..b2bd2351a5 100644 --- a/erts/emulator/beam/beam_catches.h +++ b/erts/emulator/beam/beam_catches.h @@ -20,6 +20,10 @@ #ifndef __BEAM_CATCHES_H #define __BEAM_CATCHES_H +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "sys.h" #include "code_ix.h" #define BEAM_CATCHES_NIL (-1) diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index e966f423ec..7ac2b9f77e 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -5940,122 +5940,3 @@ static int safe_mul(UWord a, UWord b, UWord* resp) } } - -/*SVERK Do these deserve a file of their own maybe? */ - -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]; - -#if 0 -# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_staging_code_ix()) -#else -# define CIX_TRACE(text) -#endif - -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) -{ - return erts_smp_atomic32_read_nob(&the_active_code_index); -} -ErtsCodeIndex erts_staging_code_ix(void) -{ - return erts_smp_atomic32_read_nob(&the_loader_code_index); -} - -/* Lock code_ix (enqueue and suspend until we get it) -*/ -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_staging_code_ix(void) -{ - beam_catches_start_staging(); - export_start_staging(); - module_start_staging(); - erts_start_staging_ranges(); - CIX_TRACE("start"); -} - - -void erts_commit_staging_code_ix(void) -{ - beam_catches_end_staging(1); - export_end_staging(1); - module_end_staging(1); - erts_end_staging_ranges(1); - { - ErtsCodeIndex ix; - export_write_lock(); - ix = erts_staging_code_ix(); - erts_smp_atomic32_set_nob(&the_active_code_index, ix); - ix = (ix + 1) % ERTS_NUM_CODE_IX; - erts_smp_atomic32_set_nob(&the_loader_code_index, ix); - export_write_unlock(); - } - CIX_TRACE("commit"); -} - -void erts_abort_staging_code_ix(void) -{ - beam_catches_end_staging(0); - export_end_staging(0); - module_end_staging(0); - erts_end_staging_ranges(0); - CIX_TRACE("abort"); -} - -/*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(ErtsCodeIndex code_ix) -{ - return erts_smp_lc_rwmtx_is_rlocked(&the_old_code_rwlocks[code_ix]); -} -#endif - diff --git a/erts/emulator/beam/code_ix.c b/erts/emulator/beam/code_ix.c new file mode 100644 index 0000000000..a8b6599e61 --- /dev/null +++ b/erts/emulator/beam/code_ix.c @@ -0,0 +1,110 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2012. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "code_ix.h" +#include "global.h" +#include "beam_catches.h" + + + +#if 0 +# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_staging_code_ix()) +#else +# define CIX_TRACE(text) +#endif + +erts_smp_atomic32_t the_active_code_index; +erts_smp_atomic32_t the_staging_code_index; + +static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ + +void erts_code_ix_init(void) +{ + /* We start emulator by initializing preloaded modules + * single threaded with active and staging set both to zero. + * Preloading is finished by a commit that will set things straight. + */ + erts_smp_atomic32_init_nob(&the_active_code_index, 0); + erts_smp_atomic32_init_nob(&the_staging_code_index, 0); + erts_smp_mtx_init_x(&sverk_code_ix_lock, "sverk_code_ix_lock", NIL); /*SVERK FIXME */ + CIX_TRACE("init"); +} + +void erts_start_staging_code_ix(void) +{ + beam_catches_start_staging(); + export_start_staging(); + module_start_staging(); + erts_start_staging_ranges(); + CIX_TRACE("start"); +} + + +void erts_commit_staging_code_ix(void) +{ + beam_catches_end_staging(1); + export_end_staging(1); + module_end_staging(1); + erts_end_staging_ranges(1); + { + ErtsCodeIndex ix; + export_write_lock(); + ix = erts_staging_code_ix(); + erts_smp_atomic32_set_nob(&the_active_code_index, ix); + ix = (ix + 1) % ERTS_NUM_CODE_IX; + erts_smp_atomic32_set_nob(&the_staging_code_index, ix); + export_write_unlock(); + } + CIX_TRACE("commit"); +} + +void erts_abort_staging_code_ix(void) +{ + beam_catches_end_staging(0); + export_end_staging(0); + module_end_staging(0); + erts_end_staging_ranges(0); + CIX_TRACE("abort"); +} + + +/* Lock code_ix (enqueue and suspend until we get it) +*/ +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 diff --git a/erts/emulator/beam/code_ix.h b/erts/emulator/beam/code_ix.h index f6926acab5..99fd4ec348 100644 --- a/erts/emulator/beam/code_ix.h +++ b/erts/emulator/beam/code_ix.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2012-2012. All Rights Reserved. + * Copyright Ericsson AB 2012. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -49,6 +49,12 @@ #ifndef __CODE_IX_H__ #define __CODE_IX_H__ +#ifndef __SYS_H__ +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +# include "sys.h" +#endif #define ERTS_NUM_CODE_IX 3 typedef unsigned ErtsCodeIndex; @@ -59,15 +65,17 @@ void erts_code_ix_init(void); /* Return active code index. * Is guaranteed to be valid until the calling BIF returns. - * To get a consistent view of the code only one call to erts_active_code_ix() - * should be made within the same BIF call. + * To get a consistent view of the code, only one call to erts_active_code_ix() + * should be made and the returned ix reused within the same BIF call. */ +ERTS_GLB_INLINE ErtsCodeIndex erts_active_code_ix(void); /* Return staging code ix. * Only used by a process performing code loading/upgrading/deleting/purging. * code_ix must be locked. */ +ERTS_GLB_INLINE ErtsCodeIndex erts_staging_code_ix(void); /* Lock code_ix. @@ -100,14 +108,27 @@ void erts_commit_staging_code_ix(void); */ void erts_abort_staging_code_ix(void); -void erts_rwlock_old_code(ErtsCodeIndex); -void erts_rwunlock_old_code(ErtsCodeIndex); -void erts_rlock_old_code(ErtsCodeIndex); -void erts_runlock_old_code(ErtsCodeIndex); - #ifdef ERTS_ENABLE_LOCK_CHECK -int erts_is_old_code_rlocked(ErtsCodeIndex); int erts_is_code_ix_locked(void); #endif + + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +extern erts_smp_atomic32_t the_active_code_index; +extern erts_smp_atomic32_t the_staging_code_index; + +ERTS_GLB_INLINE ErtsCodeIndex erts_active_code_ix(void) +{ + return erts_smp_atomic32_read_nob(&the_active_code_index); +} +ERTS_GLB_INLINE ErtsCodeIndex erts_staging_code_ix(void) +{ + return erts_smp_atomic32_read_nob(&the_staging_code_index); +} + +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ + #endif /* !__CODE_IX_H__ */ + 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<ERTS_NUM_CODE_IX; i++) { + erts_smp_rwmtx_init_x(&the_old_code_rwlocks[i], "old_code", make_small(i)); + } } Module* @@ -211,3 +217,4 @@ void module_end_staging(int commit) IF_DEBUG(dbg_load_code_ix = -1); } + diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h index d63cf56778..6e123a0ffe 100644 --- a/erts/emulator/beam/module.h +++ b/erts/emulator/beam/module.h @@ -38,7 +38,7 @@ typedef struct erl_module { int module; /* Atom index for module (not tagged). */ struct erl_module_instance curr; - struct erl_module_instance old; + struct erl_module_instance old; /* protected by "old_code" rwlock */ } Module; Module* erts_get_module(Eterm mod, ErtsCodeIndex code_ix); @@ -53,4 +53,43 @@ Module *module_code(int, ErtsCodeIndex); int module_code_size(ErtsCodeIndex); int module_table_sz(void); +ERTS_GLB_INLINE void erts_rwlock_old_code(ErtsCodeIndex); +ERTS_GLB_INLINE void erts_rwunlock_old_code(ErtsCodeIndex); +ERTS_GLB_INLINE void erts_rlock_old_code(ErtsCodeIndex); +ERTS_GLB_INLINE void erts_runlock_old_code(ErtsCodeIndex); +#ifdef ERTS_ENABLE_LOCK_CHECK +int erts_is_old_code_rlocked(ErtsCodeIndex); #endif + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +extern erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; + +ERTS_GLB_INLINE void erts_rwlock_old_code(ErtsCodeIndex code_ix) +{ + erts_smp_rwmtx_rwlock(&the_old_code_rwlocks[code_ix]); +} +ERTS_GLB_INLINE void erts_rwunlock_old_code(ErtsCodeIndex code_ix) +{ + erts_smp_rwmtx_rwunlock(&the_old_code_rwlocks[code_ix]); +} +ERTS_GLB_INLINE void erts_rlock_old_code(ErtsCodeIndex code_ix) +{ + erts_smp_rwmtx_rlock(&the_old_code_rwlocks[code_ix]); +} +ERTS_GLB_INLINE void erts_runlock_old_code(ErtsCodeIndex code_ix) +{ + erts_smp_rwmtx_runlock(&the_old_code_rwlocks[code_ix]); +} + +#ifdef ERTS_ENABLE_LOCK_CHECK +ERTS_GLB_INLINE int erts_is_old_code_rlocked(ErtsCodeIndex code_ix) +{ + return erts_smp_lc_rwmtx_is_rlocked(&the_old_code_rwlocks[code_ix]); +} +#endif + +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ + + +#endif /* !__MODULE_H__ */ |