From 1c86a620d74f4f9383c4956dafd3e2486300dc0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 17 Jun 2015 17:33:29 +0200 Subject: erts: Remove HALFWORD_HEAP definition --- erts/emulator/beam/global.h | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index ec9296d034..1d2d75bc1e 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -310,9 +310,6 @@ typedef union { typedef struct proc_bin { Eterm thing_word; /* Subtag REFC_BINARY_SUBTAG. */ Uint size; /* Binary size in bytes. */ -#if HALFWORD_HEAP - void* dummy_ptr_padding__; -#endif struct erl_off_heap_header *next; Binary *val; /* Pointer to Binary structure. */ byte *bytes; /* Pointer to the actual data bytes. */ @@ -959,28 +956,14 @@ void erl_error(char*, va_list); /* copy.c */ Eterm copy_object(Eterm, Process*); -#if HALFWORD_HEAP -Uint size_object_rel(Eterm, Eterm*); -# define size_object(A) size_object_rel(A,NULL) - -Eterm copy_struct_rel(Eterm, Uint, Eterm**, ErlOffHeap*, Eterm* src_base, Eterm* dst_base); -# define copy_struct(OBJ,SZ,HPP,OH) copy_struct_rel(OBJ,SZ,HPP,OH, NULL,NULL) - -Eterm copy_shallow_rel(Eterm*, Uint, Eterm**, ErlOffHeap*, Eterm* src_base); -# define copy_shallow(A,B,C,D) copy_shallow_rel(A,B,C,D,NULL) - -#else /* !HALFWORD_HEAP */ - Uint size_object(Eterm); -# define size_object_rel(A,B) size_object(A) +#define size_object_rel(A,B) size_object(A) Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); -# define copy_struct_rel(OBJ,SZ,HPP,OH, SB,DB) copy_struct(OBJ,SZ,HPP,OH) +#define copy_struct_rel(OBJ,SZ,HPP,OH, SB,DB) copy_struct(OBJ,SZ,HPP,OH) Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); -# define copy_shallow_rel(A,B,C,D, BASE) copy_shallow(A,B,C,D) - -#endif +#define copy_shallow_rel(A,B,C,D, BASE) copy_shallow(A,B,C,D) void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, @@ -1180,7 +1163,7 @@ void bin_write(int, void*, byte*, size_t); int intlist_to_buf(Eterm, char*, int); /* most callers pass plain char*'s */ struct Sint_buf { -#if defined(ARCH_64) && !HALFWORD_HEAP +#if defined(ARCH_64) char s[22]; #else char s[12]; -- cgit v1.2.3 From 256c60d885b6fe0e8a715fa9bfdd371ad14c8857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 18 Jun 2015 16:01:10 +0200 Subject: erts: Remove halfword object manipulation * Remove macros size_object_rel, copy_struct_rel and copy_shallow_rel --- erts/emulator/beam/global.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 1d2d75bc1e..3559f0cd13 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -955,16 +955,9 @@ void erl_error(char*, va_list); /* copy.c */ Eterm copy_object(Eterm, Process*); - Uint size_object(Eterm); -#define size_object_rel(A,B) size_object(A) - Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); -#define copy_struct_rel(OBJ,SZ,HPP,OH, SB,DB) copy_struct(OBJ,SZ,HPP,OH) - Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); -#define copy_shallow_rel(A,B,C,D, BASE) copy_shallow(A,B,C,D) - void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, Eterm* refs, unsigned nrefs); -- cgit v1.2.3 From d6712b1c54de471beb1784bb329ea217767f70ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 18 Jun 2015 17:03:48 +0200 Subject: erts: Reinstate copy_object over-allocation optimization --- erts/emulator/beam/global.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3559f0cd13..870afb414f 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -954,7 +954,9 @@ __decl_noreturn void __noreturn erl_exit_flush_async(int n, char*, ...); void erl_error(char*, va_list); /* copy.c */ -Eterm copy_object(Eterm, Process*); +Eterm copy_object_x(Eterm, Process*, Uint); +#define copy_object(Term, Proc) copy_object_x(Term,Proc,0) + Uint size_object(Eterm); Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); -- cgit v1.2.3 From 3bda47f2f26dd417fbd65d5f46b2ab8411a2a41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 1 Jul 2015 15:09:58 +0200 Subject: erts: Remove halfword !HEAP_ON_C_STACK --- erts/emulator/beam/global.h | 67 +++++---------------------------------------- 1 file changed, 7 insertions(+), 60 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 870afb414f..b4d02dd1dd 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1444,69 +1444,16 @@ erts_alloc_message_heap(Uint size, #endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ -#if !HEAP_ON_C_STACK -# if defined(DEBUG) -# define DeclareTmpHeap(VariableName,Size,Process) \ - Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,Process) -# define DeclareTypedTmpHeap(Type,VariableName,Process) \ - Type *VariableName = (Type *) erts_debug_allocate_tmp_heap(sizeof(Type)/sizeof(Eterm),Process) -# define DeclareTmpHeapNoproc(VariableName,Size) \ - Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,NULL) -# define UseTmpHeap(Size,Proc) \ - do { \ - erts_debug_use_tmp_heap((Size),(Proc)); \ - } while (0) -# define UnUseTmpHeap(Size,Proc) \ - do { \ - erts_debug_unuse_tmp_heap((Size),(Proc)); \ - } while (0) -# define UseTmpHeapNoproc(Size) \ - do { \ - erts_debug_use_tmp_heap(Size,NULL); \ - } while (0) -# define UnUseTmpHeapNoproc(Size) \ - do { \ - erts_debug_unuse_tmp_heap(Size,NULL); \ - } while (0) -# else -# define DeclareTmpHeap(VariableName,Size,Process) \ - Eterm *VariableName = (ERTS_PROC_GET_SCHDATA(Process)->tmp_heap)+(ERTS_PROC_GET_SCHDATA(Process)->num_tmp_heap_used) -# define DeclareTypedTmpHeap(Type,VariableName,Process) \ - Type *VariableName = (Type *) (ERTS_PROC_GET_SCHDATA(Process)->tmp_heap)+(ERTS_PROC_GET_SCHDATA(Process)->num_tmp_heap_used) -# define DeclareTmpHeapNoproc(VariableName,Size) \ - Eterm *VariableName = (erts_get_scheduler_data()->tmp_heap)+(erts_get_scheduler_data()->num_tmp_heap_used) -# define UseTmpHeap(Size,Proc) \ - do { \ - ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used += (Size); \ - } while (0) -# define UnUseTmpHeap(Size,Proc) \ - do { \ - ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used -= (Size); \ - } while (0) -# define UseTmpHeapNoproc(Size) \ - do { \ - erts_get_scheduler_data()->num_tmp_heap_used += (Size); \ - } while (0) -# define UnUseTmpHeapNoproc(Size) \ - do { \ - erts_get_scheduler_data()->num_tmp_heap_used -= (Size); \ - } while (0) - - -# endif - -#else -# define DeclareTmpHeap(VariableName,Size,Process) \ +#define DeclareTmpHeap(VariableName,Size,Process) \ Eterm VariableName[Size] -# define DeclareTypedTmpHeap(Type,VariableName,Process) \ +#define DeclareTypedTmpHeap(Type,VariableName,Process) \ Type VariableName[1] -# define DeclareTmpHeapNoproc(VariableName,Size) \ +#define DeclareTmpHeapNoproc(VariableName,Size) \ Eterm VariableName[Size] -# define UseTmpHeap(Size,Proc) /* Nothing */ -# define UnUseTmpHeap(Size,Proc) /* Nothing */ -# define UseTmpHeapNoproc(Size) /* Nothing */ -# define UnUseTmpHeapNoproc(Size) /* Nothing */ -#endif /* HEAP_ON_C_STACK */ +#define UseTmpHeap(Size,Proc) /* Nothing */ +#define UnUseTmpHeap(Size,Proc) /* Nothing */ +#define UseTmpHeapNoproc(Size) /* Nothing */ +#define UnUseTmpHeapNoproc(Size) /* Nothing */ ERTS_GLB_INLINE void dtrace_pid_str(Eterm pid, char *process_buf); ERTS_GLB_INLINE void dtrace_proc_str(Process *process, char *process_buf); -- cgit v1.2.3 From b21b604137c5cb5f5039a40994e429871e5b707b Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 26 Aug 2015 19:47:10 +0200 Subject: Introduce literal tag --- erts/emulator/beam/global.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index b4d02dd1dd..052994b972 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -961,8 +961,8 @@ Uint size_object(Eterm); Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); -void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, - Eterm* refs, unsigned nrefs); +void erts_move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, + Eterm* refs, unsigned nrefs, int literals); /* Utilities */ extern void erts_delete_nodes_monitors(Process *, ErtsProcLocks); @@ -1274,6 +1274,27 @@ int erts_print_system_version(int to, void *arg, Process *c_p); int erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg); +ERTS_GLB_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF + +ERTS_GLB_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr) +{ + ASSERT(is_boxed(tptr) || is_list(tptr)); + ASSERT(ptr == ptr_val(tptr)); + +#if defined(ERTS_HAVE_IS_IN_LITERAL_RANGE) + return erts_is_in_literal_range(ptr); +#elif defined(TAG_LITERAL_PTR) + return is_literal_ptr(tptr); +#else +# error Not able to detect literals... +#endif + +} + +#endif + /* ** Call_trace uses this API for the parameter matching functions */ -- cgit v1.2.3 From 3ac08f9b668613a4292436979eacc61863c2ab94 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 16 Sep 2015 15:02:50 +0200 Subject: Fragmented young heap generation and off_heap_message_queue option * The youngest generation of the heap can now consist of multiple blocks. Heap fragments and message fragments are added to the youngest generation when needed without triggering a GC. After a GC the youngest generation is contained in one single block. * The off_heap_message_queue process flag has been added. When enabled all message data in the queue is kept off heap. When a message is selected from the queue, the message fragment (or heap fragment) containing the actual message is attached to the youngest generation. Messages stored off heap is not part of GC. --- erts/emulator/beam/global.h | 123 ++------------------------------------------ 1 file changed, 3 insertions(+), 120 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 052994b972..594c0ccf94 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1274,11 +1274,11 @@ int erts_print_system_version(int to, void *arg, Process *c_p); int erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg); -ERTS_GLB_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr); +ERTS_GLB_FORCE_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr); #if ERTS_GLB_INLINE_INCL_FUNC_DEF -ERTS_GLB_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr) +ERTS_GLB_FORCE_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr) { ASSERT(is_boxed(tptr) || is_list(tptr)); ASSERT(ptr == ptr_val(tptr)); @@ -1347,124 +1347,6 @@ extern erts_driver_t fd_driver; int erts_beam_jump_table(void); -/* Should maybe be placed in erl_message.h, but then we get an include mess. */ -ERTS_GLB_INLINE Eterm * -erts_alloc_message_heap_state(Uint size, - ErlHeapFragment **bpp, - ErlOffHeap **ohpp, - Process *receiver, - ErtsProcLocks *receiver_locks, - erts_aint32_t *statep); - -ERTS_GLB_INLINE Eterm * -erts_alloc_message_heap(Uint size, - ErlHeapFragment **bpp, - ErlOffHeap **ohpp, - Process *receiver, - ErtsProcLocks *receiver_locks); - -#if ERTS_GLB_INLINE_INCL_FUNC_DEF - -/* - * NOTE: erts_alloc_message_heap() releases msg q and status - * lock on receiver without ensuring that other locks are - * held. User is responsible to ensure that the receiver - * pointer cannot become invalid until after message has - * been passed. This is normal done either by increasing - * reference count on process (preferred) or by holding - * main or link lock over the whole message passing - * operation. - */ - -ERTS_GLB_INLINE Eterm * -erts_alloc_message_heap_state(Uint size, - ErlHeapFragment **bpp, - ErlOffHeap **ohpp, - Process *receiver, - ErtsProcLocks *receiver_locks, - erts_aint32_t *statep) -{ - Eterm *hp; - erts_aint32_t state; -#ifdef ERTS_SMP - int locked_main = 0; - state = erts_smp_atomic32_read_acqb(&receiver->state); - if (statep) - *statep = state; - if (state & (ERTS_PSFLG_EXITING - | ERTS_PSFLG_PENDING_EXIT)) - goto allocate_in_mbuf; -#endif - - if (size > (Uint) INT_MAX) - erl_exit(ERTS_ABORT_EXIT, "HUGE size (%beu)\n", size); - - if ( -#if defined(ERTS_SMP) - *receiver_locks & ERTS_PROC_LOCK_MAIN -#else - 1 -#endif - ) { -#ifdef ERTS_SMP - try_allocate_on_heap: -#endif - state = erts_smp_atomic32_read_nob(&receiver->state); - if (statep) - *statep = state; - if ((state & (ERTS_PSFLG_EXITING - | ERTS_PSFLG_PENDING_EXIT)) - || (receiver->flags & F_DISABLE_GC) - || HEAP_LIMIT(receiver) - HEAP_TOP(receiver) <= size) { - /* - * The heap is either potentially in an inconsistent - * state, or not large enough. - */ -#ifdef ERTS_SMP - if (locked_main) { - *receiver_locks &= ~ERTS_PROC_LOCK_MAIN; - erts_smp_proc_unlock(receiver, ERTS_PROC_LOCK_MAIN); - } -#endif - goto allocate_in_mbuf; - } - hp = HEAP_TOP(receiver); - HEAP_TOP(receiver) = hp + size; - *bpp = NULL; - *ohpp = &MSO(receiver); - } -#ifdef ERTS_SMP - else if (erts_smp_proc_trylock(receiver, ERTS_PROC_LOCK_MAIN) == 0) { - locked_main = 1; - *receiver_locks |= ERTS_PROC_LOCK_MAIN; - goto try_allocate_on_heap; - } -#endif - else { - ErlHeapFragment *bp; - allocate_in_mbuf: - bp = new_message_buffer(size); - hp = bp->mem; - *bpp = bp; - *ohpp = &bp->off_heap; - } - - return hp; -} - -ERTS_GLB_INLINE Eterm * -erts_alloc_message_heap(Uint size, - ErlHeapFragment **bpp, - ErlOffHeap **ohpp, - Process *receiver, - ErtsProcLocks *receiver_locks) -{ - return erts_alloc_message_heap_state(size, bpp, ohpp, receiver, - receiver_locks, NULL); -} - -#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ - #define DeclareTmpHeap(VariableName,Size,Process) \ Eterm VariableName[Size] #define DeclareTypedTmpHeap(Type,VariableName,Process) \ @@ -1522,6 +1404,7 @@ dtrace_fun_decode(Process *process, erts_snprintf(mfa_buf, DTRACE_TERM_BUF_SIZE, "%T:%T/%d", module, function, arity); } + #endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ #endif /* !__GLOBAL_H__ */ -- cgit v1.2.3 From dad527f55b51d60e75a0d19aa0f4f42c1065777f Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Fri, 8 Jun 2012 22:21:02 +0300 Subject: An implementation of lightweight unbounded queues --- erts/emulator/beam/global.h | 84 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 594c0ccf94..20f100b427 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -380,7 +380,7 @@ extern int bif_reductions; /* reductions + fcalls (when doing call_bif) */ extern int stackdump_on_exit; /* - * Here is an implementation of a lightweiht stack. + * Here is an implementation of a lightweight stack. * * Use it like this: * @@ -845,6 +845,88 @@ do {\ } while(0) +/* + * An implementation of lightweight unbounded queues, + * using a circular dynamic array. + * It does not include support for change_allocator. + * + * Use it like this: + * + * DECLARE_EQUEUE(Queue) (At the start of a block) + * ... + * EQUEUE_PUT(Queue, Term) + * ... + * if (EQUEUE_ISEMPTY(Queue)) { + * Queue is empty + * } else { + * Term = EQUEUE_GET(Stack); + * Process popped Term here + * } + * ... + * DESTROY_EQUEUE(Queue) + */ + +typedef struct { + Eterm* start; + Eterm* front; + Eterm* back; + int possibly_empty; + Eterm* end; + ErtsAlcType_t alloc_type; +}ErtsEQueue; + +#define DEF_EQUEUE_SIZE (16) + +void erl_grow_equeue(ErtsEQueue*, Eterm* def_queue); +#define EQUE_CONCAT(a,b) a##b +#define EQUE_DEF_QUEUE(q) EQUE_CONCAT(q,_default_equeue) + +#define DECLARE_EQUEUE(q) \ + UWord EQUE_DEF_QUEUE(q)[DEF_EQUEUE_SIZE]; \ + ErtsEQueue q = { \ + EQUE_DEF_QUEUE(q), /* start */ \ + EQUE_DEF_QUEUE(q), /* front */ \ + EQUE_DEF_QUEUE(q), /* back */ \ + 1, /* possibly_empty */ \ + EQUE_DEF_QUEUE(q) + DEF_EQUEUE_SIZE, /* end */ \ + ERTS_ALC_T_ESTACK /* alloc_type */ \ + } + +#define DESTROY_EQUEUE(q) \ +do { \ + if (q.start != EQUE_DEF_QUEUE(q)) { \ + erts_free(q.alloc_type, q.start); \ + } \ +} while(0) + +#define EQUEUE_PUT_UNCHECKED(q, x) \ +do { \ + q.possibly_empty = 0; \ + *(q.back) = (x); \ + if (++(q.back) == q.end) { \ + q.back = q.start; \ + } \ +} while(0) + +#define EQUEUE_PUT(q, x) \ +do { \ + if (q.back == q.front && !q.possibly_empty) { \ + erl_grow_equeue(&q, EQUE_DEF_QUEUE(q)); \ + } \ + EQUEUE_PUT_UNCHECKED(q, x); \ +} while(0) + +#define EQUEUE_ISEMPTY(q) (q.back == q.front && q.possibly_empty) + +#define EQUEUE_GET(q) ({ \ + q.possibly_empty = 1; \ + UWord x = *(q.front); \ + if (++(q.front) == q.end) { \ + q.front = q.start; \ + } \ + x; \ +}) + /* binary.c */ void erts_emasculate_writable_binary(ProcBin* pb); -- cgit v1.2.3 From d5711cb70be9ad2e5c78839e8a368900ba248a4a Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Fri, 8 Jun 2012 23:13:50 +0300 Subject: Add all the main machinery Add functions size_shared, copy_shared_calculate and copy_shared_perform. Add the infrastructure for making these communicate with each other. Add debug information to other places in the VM, to watch interaction with the sharing-preserving copy. CAUTION: If you define the SHCOPY_DEBUG macro (after SHCOPY is actually used in the VM) and make the whole OTP, there will be a lot of debugging messages during make (it will also be enabled in erlc). You have been warned... --- erts/emulator/beam/global.h | 56 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 20f100b427..d99f6548f9 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -919,8 +919,9 @@ do { \ #define EQUEUE_ISEMPTY(q) (q.back == q.front && q.possibly_empty) #define EQUEUE_GET(q) ({ \ + UWord x; \ q.possibly_empty = 1; \ - UWord x = *(q.front); \ + x = *(q.front); \ if (++(q.front) == q.end) { \ q.front = q.start; \ } \ @@ -1035,11 +1036,64 @@ __decl_noreturn void __noreturn erl_exit(int n, char*, ...); __decl_noreturn void __noreturn erl_exit_flush_async(int n, char*, ...); void erl_error(char*, va_list); +/* This controls whether sharing-preserving copy is used by Erlang */ + +#define SHCOPY_SEND +#define SHCOPY_SPAWN + +#if defined(SHCOPY_SEND) \ + || defined(SHCOPY_SPAWN) +#define SHCOPY +/* Use this with care, it is *very* verbose! */ +#undef SHCOPY_DEBUG +#endif + +#define VERBOSE_DEBUG(...) do { \ + erts_fprintf(stderr, __VA_ARGS__); \ + } while(0) + +#define ERTS_SHCOPY_FLG_MASK (((unsigned) 3) << 0) +#define ERTS_SHCOPY_FLG_NONE (((unsigned) 1) << 0) +#define ERTS_SHCOPY_FLG_TMP_BUF (((unsigned) 1) << 1) + +/* The persistent state while the sharing-preserving copier works */ + +typedef struct shcopy_info { + Eterm queue_default[DEF_EQUEUE_SIZE]; + Eterm* queue_start; + Eterm* queue_end; + ErtsAlcType_t queue_alloc_type; + UWord bitstore_default[DEF_WSTACK_SIZE]; + UWord* bitstore_start; + ErtsAlcType_t bitstore_alloc_type; + Eterm shtable_default[DEF_ESTACK_SIZE]; + Eterm* shtable_start; + ErtsAlcType_t shtable_alloc_type; +} shcopy_info; + +#define DESTROY_INFO(info) \ +do { \ + if (info.queue_start != info.queue_default) { \ + erts_free(info.queue_alloc_type, info.queue_start); \ + } \ + if (info.bitstore_start != info.bitstore_default) { \ + erts_free(info.bitstore_alloc_type, info.bitstore_start); \ + } \ + if (info.shtable_start != info.shtable_default) { \ + erts_free(info.shtable_alloc_type, info.shtable_start); \ + } \ +} while(0) + /* copy.c */ Eterm copy_object_x(Eterm, Process*, Uint); #define copy_object(Term, Proc) copy_object_x(Term,Proc,0) Uint size_object(Eterm); +Uint copy_shared_calculate(Eterm, shcopy_info*, unsigned); +Eterm copy_shared_perform(Eterm, Uint, shcopy_info*, Eterm**, ErlOffHeap*, unsigned); + +Uint size_shared(Eterm); + Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); -- cgit v1.2.3 From cfe998988c942bed0fbf026c00a2531fdf5aba7c Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Sat, 9 Jun 2012 00:19:28 +0300 Subject: Add the BIF size_shared/1 and debug cleanup --- erts/emulator/beam/global.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index d99f6548f9..c2056dafaa 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1048,9 +1048,13 @@ void erl_error(char*, va_list); #undef SHCOPY_DEBUG #endif +#ifdef SHCOPY_DEBUG #define VERBOSE_DEBUG(...) do { \ erts_fprintf(stderr, __VA_ARGS__); \ } while(0) +#else +#define VERBOSE_DEBUG(...) +#endif #define ERTS_SHCOPY_FLG_MASK (((unsigned) 3) << 0) #define ERTS_SHCOPY_FLG_NONE (((unsigned) 1) << 0) -- cgit v1.2.3 From f3ae60838a5e8c83cfdd3000e25562dfcbbd438d Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Sat, 9 Jun 2012 01:12:50 +0300 Subject: Enable shcopy for sending messages --- erts/emulator/beam/global.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index c2056dafaa..a5e6ff6f1c 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1075,6 +1075,13 @@ typedef struct shcopy_info { ErtsAlcType_t shtable_alloc_type; } shcopy_info; +#define INITIALIZE_INFO(info) \ +do { \ + info.queue_start = info.queue_default; \ + info.bitstore_start = info.bitstore_default; \ + info.shtable_start = info.shtable_default; \ +} while(0) + #define DESTROY_INFO(info) \ do { \ if (info.queue_start != info.queue_default) { \ -- cgit v1.2.3 From 8d02ad60c88aa060ff83ff3179bc8c0ab66868ee Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Fri, 14 Mar 2014 11:32:46 +0200 Subject: Add machinery to enable SHCOPY dynamically This commit is just for debugging purposes, will probably be reverted. It comes with a the erts_debug:copy_shared/1 BIF. If SHCOPY_DISABLE is defined, SHCOPY starts disabled and is dynamically enabled the first time that the BIF is called. --- erts/emulator/beam/global.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index a5e6ff6f1c..3e1f3664bc 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1044,6 +1044,8 @@ void erl_error(char*, va_list); #if defined(SHCOPY_SEND) \ || defined(SHCOPY_SPAWN) #define SHCOPY +/* Use this if you want sharing-preserving copy to be initially disabled */ +#undef SHCOPY_DISABLE /* Use this with care, it is *very* verbose! */ #undef SHCOPY_DEBUG #endif -- cgit v1.2.3 From 277e8e77384ed6628009243e63d62f0555d10c69 Mon Sep 17 00:00:00 2001 From: "Nikolaos S. Papaspyrou" Date: Mon, 11 Jun 2012 15:17:01 +0300 Subject: Add -debug +vc flag for debuging SHCOPY This is very verbose, you have been warned. It should work with the copy-spy.py script, which may be a bit outdated. --- erts/emulator/beam/global.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3e1f3664bc..303b9ee51b 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1046,16 +1046,6 @@ void erl_error(char*, va_list); #define SHCOPY /* Use this if you want sharing-preserving copy to be initially disabled */ #undef SHCOPY_DISABLE -/* Use this with care, it is *very* verbose! */ -#undef SHCOPY_DEBUG -#endif - -#ifdef SHCOPY_DEBUG -#define VERBOSE_DEBUG(...) do { \ - erts_fprintf(stderr, __VA_ARGS__); \ - } while(0) -#else -#define VERBOSE_DEBUG(...) #endif #define ERTS_SHCOPY_FLG_MASK (((unsigned) 3) << 0) -- cgit v1.2.3 From eebdde01b149ea45966c7412bc2a062136457b54 Mon Sep 17 00:00:00 2001 From: Yiannis Tsiouris Date: Tue, 22 Jan 2013 18:16:33 +0200 Subject: Add --enable-sharing-preserving configure flag --- erts/emulator/beam/global.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 303b9ee51b..3c59df5f41 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1038,12 +1038,9 @@ void erl_error(char*, va_list); /* This controls whether sharing-preserving copy is used by Erlang */ +#ifdef SHCOPY #define SHCOPY_SEND #define SHCOPY_SPAWN - -#if defined(SHCOPY_SEND) \ - || defined(SHCOPY_SPAWN) -#define SHCOPY /* Use this if you want sharing-preserving copy to be initially disabled */ #undef SHCOPY_DISABLE #endif -- cgit v1.2.3 From 748c73f1687b2375d4c607487f40036ba990c4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 17 Sep 2015 16:17:10 +0200 Subject: Refactor copy sharing --- erts/emulator/beam/global.h | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3c59df5f41..bdee20969d 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1045,13 +1045,13 @@ void erl_error(char*, va_list); #undef SHCOPY_DISABLE #endif -#define ERTS_SHCOPY_FLG_MASK (((unsigned) 3) << 0) -#define ERTS_SHCOPY_FLG_NONE (((unsigned) 1) << 0) -#define ERTS_SHCOPY_FLG_TMP_BUF (((unsigned) 1) << 1) +#define ERTS_SHCOPY_FLG_MASK (((Uint32) 3) << 0) +#define ERTS_SHCOPY_FLG_NONE (((Uint32) 1) << 0) +#define ERTS_SHCOPY_FLG_TMPBUF (((Uint32) 1) << 1) /* forces INHEAP to true */ /* The persistent state while the sharing-preserving copier works */ -typedef struct shcopy_info { +typedef struct { Eterm queue_default[DEF_EQUEUE_SIZE]; Eterm* queue_start; Eterm* queue_end; @@ -1062,26 +1062,26 @@ typedef struct shcopy_info { Eterm shtable_default[DEF_ESTACK_SIZE]; Eterm* shtable_start; ErtsAlcType_t shtable_alloc_type; -} shcopy_info; +} erts_shcopy_t; -#define INITIALIZE_INFO(info) \ -do { \ - info.queue_start = info.queue_default; \ - info.bitstore_start = info.bitstore_default; \ - info.shtable_start = info.shtable_default; \ +#define INITIALIZE_SHCOPY(info) \ +do { \ + info.queue_start = info.queue_default; \ + info.bitstore_start = info.bitstore_default; \ + info.shtable_start = info.shtable_default; \ } while(0) -#define DESTROY_INFO(info) \ -do { \ - if (info.queue_start != info.queue_default) { \ - erts_free(info.queue_alloc_type, info.queue_start); \ - } \ - if (info.bitstore_start != info.bitstore_default) { \ - erts_free(info.bitstore_alloc_type, info.bitstore_start); \ - } \ - if (info.shtable_start != info.shtable_default) { \ - erts_free(info.shtable_alloc_type, info.shtable_start); \ - } \ +#define DESTROY_SHCOPY(info) \ +do { \ + if (info.queue_start != info.queue_default) { \ + erts_free(info.queue_alloc_type, info.queue_start); \ + } \ + if (info.bitstore_start != info.bitstore_default) { \ + erts_free(info.bitstore_alloc_type, info.bitstore_start); \ + } \ + if (info.shtable_start != info.shtable_default) { \ + erts_free(info.shtable_alloc_type, info.shtable_start); \ + } \ } while(0) /* copy.c */ @@ -1089,8 +1089,8 @@ Eterm copy_object_x(Eterm, Process*, Uint); #define copy_object(Term, Proc) copy_object_x(Term,Proc,0) Uint size_object(Eterm); -Uint copy_shared_calculate(Eterm, shcopy_info*, unsigned); -Eterm copy_shared_perform(Eterm, Uint, shcopy_info*, Eterm**, ErlOffHeap*, unsigned); +Uint copy_shared_calculate(Eterm, erts_shcopy_t*, Uint32); +Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*, Uint32); Uint size_shared(Eterm); -- cgit v1.2.3 From 5d2d888f368ba8ca0098d8bd9936ca9d67df7d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 17 Sep 2015 19:30:08 +0200 Subject: Copy literals in copy sharing --- erts/emulator/beam/global.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index bdee20969d..f106b941ef 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1062,6 +1062,7 @@ typedef struct { Eterm shtable_default[DEF_ESTACK_SIZE]; Eterm* shtable_start; ErtsAlcType_t shtable_alloc_type; + Uint literal_size; } erts_shcopy_t; #define INITIALIZE_SHCOPY(info) \ @@ -1069,6 +1070,7 @@ do { \ info.queue_start = info.queue_default; \ info.bitstore_start = info.bitstore_default; \ info.shtable_start = info.shtable_default; \ + info.literal_size = 0; \ } while(0) #define DESTROY_SHCOPY(info) \ @@ -1094,7 +1096,9 @@ Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*, Uin Uint size_shared(Eterm); -Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*); +Eterm copy_struct_x(Eterm, Uint, Eterm**, ErlOffHeap*, Uint* bsz); +#define copy_struct(Obj,Sz,HPP,OH) \ + copy_struct_x(Obj,Sz,HPP,OH,NULL) Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*); void erts_move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first, -- cgit v1.2.3 From 1391715d8bbba315e1509e60e6245159a009bd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 25 Sep 2015 17:03:02 +0200 Subject: Use copy literal range check in message passing and purging --- erts/emulator/beam/global.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index f106b941ef..71d072fa7e 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -982,6 +982,12 @@ Eterm erl_is_function(Process* p, Eterm arg1, Eterm arg2); /* beam_bif_load.c */ Eterm erts_check_process_code(Process *c_p, Eterm module, int allow_gc, int *redsp); +typedef struct { + Eterm *ptr; + Uint sz; +} copy_literals_t; + +extern copy_literals_t erts_clrange; /* beam_load.c */ typedef struct { @@ -1063,6 +1069,8 @@ typedef struct { Eterm* shtable_start; ErtsAlcType_t shtable_alloc_type; Uint literal_size; + Eterm *range_ptr; + Uint range_sz; } erts_shcopy_t; #define INITIALIZE_SHCOPY(info) \ @@ -1071,6 +1079,8 @@ do { \ info.bitstore_start = info.bitstore_default; \ info.shtable_start = info.shtable_default; \ info.literal_size = 0; \ + info.range_ptr = erts_clrange.ptr; \ + info.range_sz = erts_clrange.sz; \ } while(0) #define DESTROY_SHCOPY(info) \ -- cgit v1.2.3 From 0d5ee7a4ad7bc41b7cca878990926fb5ba57f6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 1 Oct 2015 12:19:50 +0200 Subject: Do not use GCC extensions in copy --- erts/emulator/beam/global.h | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 71d072fa7e..e9f7901a51 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -873,7 +873,7 @@ typedef struct { int possibly_empty; Eterm* end; ErtsAlcType_t alloc_type; -}ErtsEQueue; +} ErtsEQueue; #define DEF_EQUEUE_SIZE (16) @@ -918,15 +918,20 @@ do { \ #define EQUEUE_ISEMPTY(q) (q.back == q.front && q.possibly_empty) -#define EQUEUE_GET(q) ({ \ - UWord x; \ - q.possibly_empty = 1; \ - x = *(q.front); \ - if (++(q.front) == q.end) { \ - q.front = q.start; \ - } \ - x; \ -}) +ERTS_GLB_INLINE Eterm erts_equeue_get(ErtsEQueue *q); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF +ERTS_GLB_INLINE Eterm erts_equeue_get(ErtsEQueue *q) { + Eterm x; + q->possibly_empty = 1; + x = *(q->front); + if (++(q->front) == q->end) { + q->front = q->start; + } + return x; +} +#endif +#define EQUEUE_GET(q) erts_equeue_get(&(q)); /* binary.c */ -- cgit v1.2.3 From 5d764f988ab09326d24e39a172083b09ab364c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 18 Nov 2015 17:58:14 +0100 Subject: Refactor sharing preserved copy flags The TMPBUF option is no longer needed due to is_literal test and NONE was only used for initial debugging. So we remove the entire option. --- erts/emulator/beam/global.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index e9f7901a51..98c275a20c 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1052,14 +1052,8 @@ void erl_error(char*, va_list); #ifdef SHCOPY #define SHCOPY_SEND #define SHCOPY_SPAWN -/* Use this if you want sharing-preserving copy to be initially disabled */ -#undef SHCOPY_DISABLE #endif -#define ERTS_SHCOPY_FLG_MASK (((Uint32) 3) << 0) -#define ERTS_SHCOPY_FLG_NONE (((Uint32) 1) << 0) -#define ERTS_SHCOPY_FLG_TMPBUF (((Uint32) 1) << 1) /* forces INHEAP to true */ - /* The persistent state while the sharing-preserving copier works */ typedef struct { @@ -1106,8 +1100,8 @@ Eterm copy_object_x(Eterm, Process*, Uint); #define copy_object(Term, Proc) copy_object_x(Term,Proc,0) Uint size_object(Eterm); -Uint copy_shared_calculate(Eterm, erts_shcopy_t*, Uint32); -Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*, Uint32); +Uint copy_shared_calculate(Eterm, erts_shcopy_t*); +Eterm copy_shared_perform(Eterm, Uint, erts_shcopy_t*, Eterm**, ErlOffHeap*); Uint size_shared(Eterm); -- cgit v1.2.3 From 14c7fefd51be035a44bfe42127fb4b9df92d760b Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Mon, 6 Jul 2015 17:13:52 +0200 Subject: erts: Create forker process for spawn driver Instead of forking from the beam process, we create a separate process in which all forks are done. This has several advantages: 1) performance: * don't have to close all fd's in the world * fork only has to copy stuff from a small process * work is done in a completely seperate process * a 3x performance increase has been measured, can be made even greater (10x) if we cache the environment in child setup 2) stability * the exec is done in another process than beam, which means that if the file that we exec to is on an nfs that is not available right now we will not block a scheduler until the nfs returns. 3) simplicity * don't have to deal with SIGCHLD in the erts Unfortunately, this solution also implies some badness. 1) There will always be a seperate process running together with beam on unix. This could be confusing and undesirable. 2) We have to transfer the entire environment to child_setup for each command. OTP-13088 --- erts/emulator/beam/global.h | 1 + 1 file changed, 1 insertion(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index b4d02dd1dd..4352d5758b 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1322,6 +1322,7 @@ extern void erts_match_prog_foreach_offheap(Binary *b, extern erts_driver_t vanilla_driver; extern erts_driver_t spawn_driver; +extern erts_driver_t forker_driver; extern erts_driver_t fd_driver; int erts_beam_jump_table(void); -- cgit v1.2.3 From 79efde2d8503e5055ef9e8afa5d8d63208710b1f Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 16 Dec 2015 20:03:32 +0100 Subject: erts: Make copy_literals more fail safe * Same process must do enable-disable. * System process will force it and never get 'aborted' --- erts/emulator/beam/global.h | 1 + 1 file changed, 1 insertion(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 0bf5988244..bbf684d49d 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -990,6 +990,7 @@ Eterm erts_check_process_code(Process *c_p, Eterm module, int allow_gc, int *red typedef struct { Eterm *ptr; Uint sz; + Eterm pid; } copy_literals_t; extern copy_literals_t erts_clrange; -- cgit v1.2.3 From 4c763443365591e170308a1c5f11a4586734ca4e Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 12 Jan 2016 16:57:59 +0100 Subject: erts: Optimize erlang:check_process_code by ignoring literals. erts_internal:check_process_code will be called again anyway (with option {copy_literals, true}) before the module is actually purged. No need to check literals twice. --- erts/emulator/beam/global.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index bbf684d49d..3f5925765d 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -985,7 +985,10 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg); Eterm erl_is_function(Process* p, Eterm arg1, Eterm arg2); /* beam_bif_load.c */ -Eterm erts_check_process_code(Process *c_p, Eterm module, int allow_gc, int *redsp); +#define ERTS_CPC_ALLOW_GC (1 << 0) +#define ERTS_CPC_COPY_LITERALS (1 << 1) +#define ERTS_CPC_ALL (ERTS_CPC_ALLOW_GC | ERTS_CPC_COPY_LITERALS) +Eterm erts_check_process_code(Process *c_p, Eterm module, Uint flags, int *redsp); typedef struct { Eterm *ptr; -- cgit v1.2.3 From 66a80a7ab735a22249ffbbb7c88eccebba906194 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 21 Jan 2016 19:53:59 +0100 Subject: erts: Add checks for thread safe allocation Assert thread unsafe allocator is only created on non-smp and only called by the main thread. Removed test of unsafe allocator in custom thread. --- erts/emulator/beam/global.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3f5925765d..ad9fdfc878 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1168,6 +1168,9 @@ extern ErtsModifiedTimings erts_modified_timings[]; extern int erts_no_line_info; extern Eterm erts_error_logger_warnings; extern int erts_initialized; +#if defined(USE_THREADS) && !defined(ERTS_SMP) +extern erts_tid_t erts_main_thread; +#endif extern int erts_compat_rel; extern int erts_use_sender_punish; void erts_short_init(void); -- cgit v1.2.3 From 664ed2a6fd2b324bb6b56db3d3eca853cfda8f61 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 12 Sep 2014 16:38:00 +0200 Subject: erts: Add microstate accounting Microstate accounting is a way to track which state the different threads within ERTS are in. The main usage area is to pin point performance bottlenecks by checking which states the threads are in and then from there figuring out why and where to optimize. Since checking whether microstate accounting is on or off is relatively expensive if done in a short loop only a few of the states are enabled by default and more states can be enabled through configure. I've done some benchmarking and the overhead with it turned off is not noticible and with it on it is a fraction of a percent. If you enable the extra states, depending on the benchmark, the ovehead when turned off is about 1% and when turned on somewhere inbetween 5-15%. OTP-12345 --- erts/emulator/beam/global.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3f5925765d..e8a7573e86 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1448,6 +1448,8 @@ ERTS_GLB_FORCE_INLINE int erts_is_literal(Eterm tptr, Eterm *ptr) #endif +Eterm erts_msacc_request(Process *c_p, int action, Eterm *threads); + /* ** Call_trace uses this API for the parameter matching functions */ -- cgit v1.2.3 From 14680fcc3fb9d0357fe33a94525d08896afed1c5 Mon Sep 17 00:00:00 2001 From: Richard Carlsson Date: Thu, 3 Dec 2015 14:33:53 +0100 Subject: erts: Use Sint instead of int for list lengths This avoids potential integer arithmetic overflow for very large lists. --- erts/emulator/beam/global.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'erts/emulator/beam/global.h') diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index e8a7573e86..628f36a35e 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1308,7 +1308,7 @@ int erts_utf8_to_latin1(byte* dest, const byte* source, int slen); #define ERTS_UTF8_OK_MAX_CHARS 4 void bin_write(int, void*, byte*, size_t); -int intlist_to_buf(Eterm, char*, int); /* most callers pass plain char*'s */ +Sint intlist_to_buf(Eterm, char*, Sint); /* most callers pass plain char*'s */ struct Sint_buf { #if defined(ARCH_64) @@ -1381,7 +1381,7 @@ ErlDrvSizeT erts_iolist_to_buf(Eterm, char*, ErlDrvSizeT); ErlDrvSizeT erts_iolist_to_buf_yielding(ErtsIOList2BufState *); int erts_iolist_size_yielding(ErtsIOListState *state); int erts_iolist_size(Eterm, ErlDrvSizeT *); -int is_string(Eterm); +Sint is_string(Eterm); void erl_at_exit(void (*) (void*), void*); Eterm collect_memory(Process *); void dump_memory_to_fd(int); -- cgit v1.2.3