diff options
author | Rickard Green <[email protected]> | 2017-01-31 13:30:20 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2017-02-13 15:43:21 +0100 |
commit | 7e9f0932f9d06edca0c30d4a2b9d57f34677344c (patch) | |
tree | 455b7c4ad302f97495011247df0d2b9856861773 | |
parent | 0affa91e1c61917a60616e8ff16aff759051a36c (diff) | |
download | otp-7e9f0932f9d06edca0c30d4a2b9d57f34677344c.tar.gz otp-7e9f0932f9d06edca0c30d4a2b9d57f34677344c.tar.bz2 otp-7e9f0932f9d06edca0c30d4a2b9d57f34677344c.zip |
Magic indirection
-rw-r--r-- | erts/emulator/beam/erl_alloc.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_alloc.types | 1 | ||||
-rw-r--r-- | erts/emulator/beam/erl_binary.h | 44 |
3 files changed, 47 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index e433de0f35..6708d96d56 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -684,6 +684,8 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) = sizeof(NifExportTrace); fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MREF_NSCHED_ENT)] = sizeof(ErtsNSchedMagicRefTableEntry); + fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MINDIRECTION)] + = ERTS_MAGIC_BIN_UNALIGNED_SIZE(sizeof(ErtsMagicIndirectionWord)); #ifdef HARD_DEBUG hdbg_init(); diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index c253ea82c8..f88985b7f5 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -284,6 +284,7 @@ type MREF_NSCHED_ENT FIXED_SIZE SYSTEM nsched_magic_ref_entry type MREF_ENT STANDARD SYSTEM magic_ref_entry type MREF_TAB_BKTS STANDARD SYSTEM magic_ref_table_buckets type MREF_TAB LONG_LIVED SYSTEM magic_ref_table +type MINDIRECTION FIXED_SIZE SYSTEM magic_indirection +if threads_no_smp # Need thread safe allocs, but std_alloc and fix_alloc are not; diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index c811a002ce..4d9c4d6eac 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -300,6 +300,17 @@ BIF_RETTYPE erts_gc_binary_part(Process *p, Eterm *reg, Eterm live, int range_is BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen); +typedef union { + /* + * These two are almost always of + * the same size, but when fallback + * atomics are used they might + * differ in size. + */ + erts_smp_atomic_t smp_atomic_word; + erts_atomic_t atomic_word; +} ErtsMagicIndirectionWord; + #if defined(__i386__) || !defined(__GNUC__) /* * Doubles aren't required to be 8-byte aligned on intel x86. @@ -329,6 +340,9 @@ ERTS_GLB_INLINE Binary *erts_create_magic_binary_x(Uint size, int unaligned); ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size, void (*destructor)(Binary *)); +ERTS_GLB_INLINE Binary *erts_create_magic_indirection(void (*destructor)(Binary *)); +ERTS_GLB_INLINE erts_smp_atomic_t *erts_smp_binary_to_magic_indirection(Binary *bp); +ERTS_GLB_INLINE erts_atomic_t *erts_binary_to_magic_indirection(Binary *bp); #if ERTS_GLB_INLINE_INCL_FUNC_DEF @@ -496,6 +510,36 @@ erts_create_magic_binary(Uint size, void (*destructor)(Binary *)) ERTS_ALC_T_BINARY, 0); } +ERTS_GLB_INLINE Binary * +erts_create_magic_indirection(void (*destructor)(Binary *)) +{ + return erts_create_magic_binary_x(sizeof(ErtsMagicIndirectionWord), + destructor, + ERTS_ALC_T_MINDIRECTION, + 1); /* Not 64-bit aligned, + but word aligned */ +} + +ERTS_GLB_INLINE erts_smp_atomic_t * +erts_smp_binary_to_magic_indirection(Binary *bp) +{ + ErtsMagicIndirectionWord *mip; + ASSERT(bp->flags & BIN_FLAG_MAGIC); + ASSERT(ERTS_MAGIC_BIN_ATYPE(bp) == ERTS_ALC_T_MINDIRECTION); + mip = ERTS_MAGIC_BIN_UNALIGNED_DATA(bp); + return &mip->smp_atomic_word; +} + +ERTS_GLB_INLINE erts_atomic_t * +erts_binary_to_magic_indirection(Binary *bp) +{ + ErtsMagicIndirectionWord *mip; + ASSERT(bp->flags & BIN_FLAG_MAGIC); + ASSERT(ERTS_MAGIC_BIN_ATYPE(bp) == ERTS_ALC_T_MINDIRECTION); + mip = ERTS_MAGIC_BIN_UNALIGNED_DATA(bp); + return &mip->atomic_word; +} + #endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ #endif /* !ERL_BINARY_H__ */ |