aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-01-31 14:24:40 +0100
committerSverker Eriksson <[email protected]>2012-02-21 12:23:05 +0100
commit7cb4725bcf18f3158e60750ea658e51ab4586e31 (patch)
treecf54f04beb607f84ce5353d48ac9000d337e6820 /erts/emulator/beam
parent6b97a90f2314b66f4f41b14a986a9c1f1ebebf13 (diff)
downloadotp-7cb4725bcf18f3158e60750ea658e51ab4586e31.tar.gz
otp-7cb4725bcf18f3158e60750ea658e51ab4586e31.tar.bz2
otp-7cb4725bcf18f3158e60750ea658e51ab4586e31.zip
erts: Refactor code_ix
Move implementation from beam_load into new file code_ix.c and module.c and make some function inline.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_catches.h4
-rw-r--r--erts/emulator/beam/beam_load.c119
-rw-r--r--erts/emulator/beam/code_ix.c110
-rw-r--r--erts/emulator/beam/code_ix.h39
-rw-r--r--erts/emulator/beam/module.c7
-rw-r--r--erts/emulator/beam/module.h41
6 files changed, 191 insertions, 129 deletions
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__ */