aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/index.h
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2017-01-12 13:58:26 +0100
committerSverker Eriksson <[email protected]>2017-01-12 13:58:26 +0100
commitaf5169d85fcd545e3c857a219db081a62f33404d (patch)
treea08ad74d060311ada3b11b76fd419a1d01e32415 /erts/emulator/beam/index.h
parent2b41d8f318b7e5ec139d42fd2f01a132699be839 (diff)
downloadotp-af5169d85fcd545e3c857a219db081a62f33404d.tar.gz
otp-af5169d85fcd545e3c857a219db081a62f33404d.tar.bz2
otp-af5169d85fcd545e3c857a219db081a62f33404d.zip
erts: Fix race bug between export fun creation and code loading
Symptom: SEGV crash on ARM in delete_code() -> export_list(). Could probably happen on other machines as well. Problem: Staging export table was iterated in an unsafe way while an entry was added for a new export fun. Solution: Correct write order and some memory barriers.
Diffstat (limited to 'erts/emulator/beam/index.h')
-rw-r--r--erts/emulator/beam/index.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/erts/emulator/beam/index.h b/erts/emulator/beam/index.h
index 0a109d8699..532dec0168 100644
--- a/erts/emulator/beam/index.h
+++ b/erts/emulator/beam/index.h
@@ -65,6 +65,7 @@ void index_erase_latest_from(IndexTable*, Uint ix);
ERTS_GLB_INLINE int index_put(IndexTable*, void*);
ERTS_GLB_INLINE IndexSlot* erts_index_lookup(IndexTable*, Uint);
+ERTS_GLB_INLINE int erts_index_num_entries(IndexTable* t);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
@@ -78,6 +79,19 @@ erts_index_lookup(IndexTable* t, Uint ix)
{
return t->seg_table[ix>>INDEX_PAGE_SHIFT][ix&INDEX_PAGE_MASK];
}
+
+ERTS_GLB_INLINE int erts_index_num_entries(IndexTable* t)
+{
+ int ret = t->entries;
+ /*
+ * Do a read barrier here to allow lock free iteration
+ * on tables where entries are never erased.
+ * index_put_entry() does matching write barrier.
+ */
+ ERTS_SMP_READ_MEMORY_BARRIER;
+ return ret;
+}
+
#endif
#endif