From 9798b72e852e5059b8d8d10cdf12b8c7fc07b406 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Tue, 12 Mar 2013 01:30:56 +0100 Subject: Fix erlang:is_process_alive/1 --- erts/emulator/beam/erl_bif_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 8582a8954b..379d3eecc6 100755 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -3077,7 +3077,7 @@ BIF_RETTYPE is_process_alive_1(BIF_ALIST_1) if (BIF_ARG_1 == BIF_P->common.id) BIF_RET(am_true); - rp = erts_proc_lookup(BIF_ARG_1); + rp = erts_proc_lookup_raw(BIF_ARG_1); if (!rp) { BIF_RET(am_false); } -- cgit v1.2.3 From cec7b1b3529dcc09298e01a243252045a0fb08bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 7 Mar 2013 15:58:10 +0100 Subject: erts: Fix copy error in erlang:delete_element/2 Off-by-one error in element copy. --- erts/emulator/beam/bif.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 9c438679ea..923bc50c40 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2579,7 +2579,7 @@ BIF_RETTYPE delete_element_2(BIF_ALIST_3) Eterm* hp; Uint arity; Eterm res; - Sint ix; + Sint ix, c1, c2; if (is_not_tuple(BIF_ARG_2) || is_not_small(BIF_ARG_1)) { BIF_ERROR(BIF_P, BADARG); @@ -2597,14 +2597,12 @@ BIF_RETTYPE delete_element_2(BIF_ALIST_3) res = make_tuple(hp); *hp = make_arityval(arity - 1); - ix--; - arity -= ix; - - while (ix--) { *++hp = *++ptr; } + c1 = ix - 1; + c2 = arity - ix; + while (c1--) { *++hp = *++ptr; } ++ptr; - - while(arity--) { *++hp = *++ptr; } + while (c2--) { *++hp = *++ptr; } BIF_RET(res); } -- cgit v1.2.3 From 9b25088a6f1494d4ff6cd39653dba155d6639f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 7 Mar 2013 16:06:46 +0100 Subject: erts: Refactor erlang:insert_element/3 for clarity --- erts/emulator/beam/bif.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 923bc50c40..ff237b6a78 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2543,7 +2543,7 @@ BIF_RETTYPE insert_element_3(BIF_ALIST_3) Eterm* hp; Uint arity; Eterm res; - Sint ix; + Sint ix, c1, c2; if (is_not_tuple(BIF_ARG_2) || is_not_small(BIF_ARG_1)) { BIF_ERROR(BIF_P, BADARG); @@ -2561,14 +2561,12 @@ BIF_RETTYPE insert_element_3(BIF_ALIST_3) res = make_tuple(hp); *hp = make_arityval(arity + 1); - ix--; - arity -= ix; - - while (ix--) { *++hp = *++ptr; } + c1 = ix - 1; + c2 = arity - ix + 1; + while (c1--) { *++hp = *++ptr; } *++hp = BIF_ARG_3; - - while(arity--) { *++hp = *++ptr; } + while (c2--) { *++hp = *++ptr; } BIF_RET(res); } -- cgit v1.2.3 From 8d70fd874ae4da853ac79f4349fbf4a985950656 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 27 Mar 2013 18:44:08 +0100 Subject: Be less eager requesting wakeup for cleanup jobs --- erts/doc/src/erl.xml | 14 ++++ erts/emulator/beam/erl_db.c | 7 +- erts/emulator/beam/erl_init.c | 12 +++ erts/emulator/beam/erl_port_task.c | 21 +++-- erts/emulator/beam/erl_process.c | 153 +++++++++++++++++++++++++++------- erts/emulator/beam/erl_process.h | 8 ++ erts/emulator/beam/erl_ptab.c | 9 +- erts/emulator/beam/erl_ptab.h | 2 + erts/emulator/beam/erl_thr_progress.c | 2 +- erts/emulator/beam/erl_thr_progress.h | 2 + erts/emulator/beam/io.c | 7 ++ erts/etc/common/erlexec.c | 1 + 12 files changed, 192 insertions(+), 46 deletions(-) (limited to 'erts') diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index bb81330fec..9f5de8a9ae 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -1009,6 +1009,20 @@ documentation of the +sbt flag.

+ +sws very_eager|eager|medium|lazy|very_lazy + +

+ Set scheduler wake cleanup threshold. Default is medium. + This flag controls how eager schedulers should be requesting + wake up due to certain cleanup operations. When a lazy setting + is used, more outstanding cleanup operations can be left undone + while a scheduler is idling. When an eager setting is used, + schedulers will more frequently be woken, potentially increasing + CPU-utilization. +

+

NOTE: This flag may be removed or changed at any time without prior notice. +

+
+sws default|legacy

diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index d0afc8ed8d..98c2988323 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -264,9 +264,10 @@ static void schedule_free_dbtable(DbTable* tb) * function has returned). */ ASSERT(erts_refc_read(&tb->common.ref, 0) == 0); - erts_schedule_thr_prgr_later_op(free_dbtable, - (void *) tb, - &tb->release.data); + erts_schedule_thr_prgr_later_cleanup_op(free_dbtable, + (void *) tb, + &tb->release.data, + sizeof(DbTable)); } static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock, diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index e7e4030900..86adc5bc99 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -532,6 +532,8 @@ void erts_usage(void) erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); erts_fprintf(stderr, "-sws val set scheduler wakeup strategy, valid values are:\n"); erts_fprintf(stderr, " default|legacy.\n"); + erts_fprintf(stderr, "-swct val set scheduler wake cleanup threshold, valid values are:\n"); + erts_fprintf(stderr, " very_lazy|lazy|medium|eager|very_eager.\n"); erts_fprintf(stderr, "-swt val set scheduler wakeup threshold, valid values are:\n"); erts_fprintf(stderr, " very_low|low|medium|high|very_high.\n"); erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n"); @@ -1413,6 +1415,16 @@ erl_start(int argc, char **argv) erts_usage(); } } + else if (has_prefix("wct", sub_param)) { + arg = get_arg(sub_param+3, argv[i+1], &i); + if (erts_sched_set_wake_cleanup_threshold(arg) != 0) { + erts_fprintf(stderr, "scheduler wake cleanup threshold: %s\n", + arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, + ("scheduler wake cleanup threshold: %s\n", arg)); + } else if (sys_strcmp("wt", sub_param) == 0) { arg = get_arg(sub_param+2, argv[i+1], &i); if (erts_sched_set_wakeup_other_thresold(arg) != 0) { diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index ce045ec94e..23000391ec 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -151,9 +151,10 @@ static ERTS_INLINE void schedule_port_task_free(ErtsPortTask *ptp) { #ifdef ERTS_SMP - erts_schedule_thr_prgr_later_op(call_port_task_free, - (void *) ptp, - &ptp->u.release); + erts_schedule_thr_prgr_later_cleanup_op(call_port_task_free, + (void *) ptp, + &ptp->u.release, + sizeof(ErtsPortTask)); #else port_task_free(ptp); #endif @@ -772,9 +773,10 @@ static void schedule_port_task_handle_list_free(ErtsPortTaskHandleList *pthlp) { #ifdef ERTS_SMP - erts_schedule_thr_prgr_later_op(free_port_task_handle_list, - (void *) pthlp, - &pthlp->u.release); + erts_schedule_thr_prgr_later_cleanup_op(free_port_task_handle_list, + (void *) pthlp, + &pthlp->u.release, + sizeof(ErtsPortTaskHandleList)); #else erts_free(ERTS_ALC_T_PT_HNDL_LIST, pthlp); #endif @@ -1999,9 +2001,10 @@ begin_port_cleanup(Port *pp, ErtsPortTask **execqp, int *processing_busy_q_p) * Schedule cleanup of port structure... */ #ifdef ERTS_SMP - erts_schedule_thr_prgr_later_op(release_port, - (void *) pp, - &pp->common.u.release); + erts_schedule_thr_prgr_later_cleanup_op(release_port, + (void *) pp, + &pp->common.u.release, + sizeof(Port)); #else pp->cleanup = 1; #endif diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 00247b387a..7e0884f55f 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -146,6 +146,14 @@ extern BeamInstr beam_continue_exit[]; int erts_sched_compact_load; Uint erts_no_schedulers; +#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_VERY_LAZY (4*1024*1024) +#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_LAZY (512*1024) +#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_MEDIUM (64*1024) +#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_EAGER (16*1024) +#define ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_VERY_EAGER (1024) + +static UWord thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_MEDIUM; + ErtsPTab erts_proc erts_align_attribute(ERTS_CACHE_LINE_SIZE); int erts_sched_thread_suggested_stack_size = -1; @@ -496,6 +504,7 @@ erts_init_process(int ncpu, int proc_tab_size) #endif (ErtsPTabElementCommon *) &erts_invalid_process.common, proc_tab_size, + sizeof(Process), "process_table"); last_reductions = 0; @@ -908,6 +917,53 @@ unset_aux_work_flags(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flgs) #ifdef ERTS_SMP +static ERTS_INLINE void +haw_chk_later_cleanup_op_wakeup(ErtsAuxWorkData *awdp, ErtsThrPrgrVal val) +{ + if (awdp->later_op.first + && erts_thr_progress_cmp(val, awdp->later_op.thr_prgr) >= 0) { + awdp->later_op.size = thr_prgr_later_cleanup_op_threshold; + } +} + +static ERTS_INLINE void +haw_thr_prgr_wakeup(ErtsAuxWorkData *awdp, ErtsThrPrgrVal val) +{ + int cmp = erts_thr_progress_cmp(val, awdp->latest_wakeup); + if (cmp != 0) { + if (cmp > 0) { + awdp->latest_wakeup = val; + haw_chk_later_cleanup_op_wakeup(awdp, val); + } + erts_thr_progress_wakeup(awdp->esdp, val); + } +} + +static ERTS_INLINE void +haw_thr_prgr_soft_wakeup(ErtsAuxWorkData *awdp, ErtsThrPrgrVal val) +{ + if (erts_thr_progress_cmp(val, awdp->latest_wakeup) > 0) { + awdp->latest_wakeup = val; + haw_chk_later_cleanup_op_wakeup(awdp, val); + erts_thr_progress_wakeup(awdp->esdp, val); + } +} + +static ERTS_INLINE void +haw_thr_prgr_later_cleanup_op_wakeup(ErtsAuxWorkData *awdp, ErtsThrPrgrVal val, UWord size) +{ + if (erts_thr_progress_cmp(val, awdp->latest_wakeup) > 0) { + awdp->later_op.thr_prgr = val; + if (awdp->later_op.size > size) + awdp->later_op.size -= size; + else { + awdp->latest_wakeup = val; + awdp->later_op.size = thr_prgr_later_cleanup_op_threshold; + erts_thr_progress_wakeup(awdp->esdp, val); + } + } +} + static ERTS_INLINE void haw_thr_prgr_current_reset(ErtsAuxWorkData *awdp) { @@ -1066,8 +1122,7 @@ misc_aux_work_clean(ErtsThrQ_t *q, case ERTS_THR_Q_NEED_THR_PRGR: #ifdef ERTS_SMP set_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_MISC_THR_PRGR); - erts_thr_progress_wakeup(awdp->esdp, - erts_thr_q_need_thr_progress(q)); + haw_thr_prgr_soft_wakeup(awdp, erts_thr_q_need_thr_progress(q)); #endif case ERTS_THR_Q_CLEAN: break; @@ -1225,8 +1280,7 @@ handle_async_ready_clean(ErtsAuxWorkData *awdp, return aux_work & ~ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN; #ifdef ERTS_SMP case ERTS_ASYNC_READY_NEED_THR_PRGR: - erts_thr_progress_wakeup(awdp->esdp, - awdp->async_ready.thr_prgr); + haw_thr_prgr_soft_wakeup(awdp, awdp->async_ready.thr_prgr); awdp->async_ready.need_thr_prgr = 1; return aux_work & ~ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN; #endif @@ -1300,7 +1354,7 @@ handle_delayed_dealloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waitin awdp->dd.thr_prgr = wakeup; set_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DD_THR_PRGR); awdp->dd.thr_prgr = wakeup; - erts_thr_progress_wakeup(awdp->esdp, wakeup); + haw_thr_prgr_soft_wakeup(awdp, wakeup); } else if (awdp->dd.completed_callback) { awdp->dd.completed_callback(awdp->dd.completed_arg); @@ -1341,7 +1395,7 @@ handle_delayed_dealloc_thr_prgr(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, i if (wakeup == ERTS_THR_PRGR_INVALID) wakeup = erts_thr_progress_later(awdp->esdp); awdp->dd.thr_prgr = wakeup; - erts_thr_progress_wakeup(awdp->esdp, wakeup); + haw_thr_prgr_soft_wakeup(awdp, wakeup); } else { unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DD_THR_PRGR); @@ -1376,6 +1430,7 @@ handle_thr_prgr_later_op(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int wait } lop->func(lop->data); if (!awdp->later_op.first) { + awdp->later_op.size = thr_prgr_later_cleanup_op_threshold; awdp->later_op.last = NULL; unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP); @@ -1386,6 +1441,29 @@ handle_thr_prgr_later_op(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int wait return aux_work; } +static ERTS_INLINE ErtsThrPrgrVal +enqueue_later_op(ErtsSchedulerData *esdp, + void (*later_func)(void *), + void *later_data, + ErtsThrPrgrLaterOp *lop) +{ + ErtsThrPrgrVal later = erts_thr_progress_later(esdp); + ASSERT(esdp); + + lop->func = later_func; + lop->data = later_data; + lop->later = later; + lop->next = NULL; + if (!esdp->aux_work_data.later_op.last) + esdp->aux_work_data.later_op.first = lop; + else + esdp->aux_work_data.later_op.last->next = lop; + esdp->aux_work_data.later_op.last = lop; + set_aux_work_flags_wakeup_nob(esdp->ssi, + ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP); + return later; +} + #endif /* ERTS_SMP */ void @@ -1396,31 +1474,24 @@ erts_schedule_thr_prgr_later_op(void (*later_func)(void *), #ifndef ERTS_SMP later_func(later_data); #else - ErtsSchedulerData *esdp; - ErtsAuxWorkData *awdp; - int request_wakeup = 1; - - esdp = erts_get_scheduler_data(); - ASSERT(esdp); - awdp = &esdp->aux_work_data; + ErtsSchedulerData *esdp = erts_get_scheduler_data(); + ErtsThrPrgrVal later = enqueue_later_op(esdp, later_func, later_data, lop); + haw_thr_prgr_wakeup(&esdp->aux_work_data, later); +#endif +} - lop->func = later_func; - lop->data = later_data; - lop->later = erts_thr_progress_later(esdp); - lop->next = NULL; - if (!awdp->later_op.last) - awdp->later_op.first = lop; - else { - ErtsThrPrgrLaterOp *last = awdp->later_op.last; - last->next = lop; - if (erts_thr_progress_equal(last->later, lop->later)) - request_wakeup = 0; - } - awdp->later_op.last = lop; - set_aux_work_flags_wakeup_nob(awdp->ssi, - ERTS_SSI_AUX_WORK_THR_PRGR_LATER_OP); - if (request_wakeup) - erts_thr_progress_wakeup(esdp, lop->later); +void +erts_schedule_thr_prgr_later_cleanup_op(void (*later_func)(void *), + void *later_data, + ErtsThrPrgrLaterOp *lop, + UWord size) +{ +#ifndef ERTS_SMP + later_func(later_data); +#else + ErtsSchedulerData *esdp = erts_get_scheduler_data(); + ErtsThrPrgrVal later = enqueue_later_op(esdp, later_func, later_data, lop); + haw_thr_prgr_later_cleanup_op_wakeup(&esdp->aux_work_data, later, size); #endif } @@ -4358,6 +4429,25 @@ erts_sched_set_busy_wait_threshold(char *str) return 0; } + +int +erts_sched_set_wake_cleanup_threshold(char *str) +{ + if (sys_strcmp(str, "very_lazy") == 0) + thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_VERY_LAZY; + else if (sys_strcmp(str, "lazy") == 0) + thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_LAZY; + else if (sys_strcmp(str, "medium") == 0) + thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_MEDIUM; + else if (sys_strcmp(str, "eager") == 0) + thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_EAGER; + else if (sys_strcmp(str, "very_eager") == 0) + thr_prgr_later_cleanup_op_threshold = ERTS_THR_PRGR_LATER_CLEANUP_OP_THRESHOLD_VERY_EAGER; + else + return EINVAL; + return 0; +} + static void init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp, char *dawwp) { @@ -4365,10 +4455,13 @@ init_aux_work_data(ErtsAuxWorkData *awdp, ErtsSchedulerData *esdp, char *dawwp) awdp->esdp = esdp; awdp->ssi = esdp ? esdp->ssi : NULL; #ifdef ERTS_SMP + awdp->latest_wakeup = ERTS_THR_PRGR_VAL_FIRST; awdp->misc.thr_prgr = ERTS_THR_PRGR_VAL_WAITING; awdp->dd.thr_prgr = ERTS_THR_PRGR_VAL_WAITING; awdp->dd.completed_callback = NULL; awdp->dd.completed_arg = NULL; + awdp->later_op.thr_prgr = ERTS_THR_PRGR_VAL_FIRST; + awdp->later_op.size = 0; awdp->later_op.first = NULL; awdp->later_op.last = NULL; #endif diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 6d1032c292..3d3579fa7e 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -430,6 +430,7 @@ typedef struct { ErtsSchedulerSleepInfo *ssi; #ifdef ERTS_SMP ErtsThrPrgrVal current_thr_prgr; + ErtsThrPrgrVal latest_wakeup; #endif struct { int ix; @@ -444,6 +445,8 @@ typedef struct { void (*completed_arg)(void *); } dd; struct { + ErtsThrPrgrVal thr_prgr; + UWord size; ErtsThrPrgrLaterOp *first; ErtsThrPrgrLaterOp *last; } later_op; @@ -1298,10 +1301,15 @@ ERTS_GLB_INLINE int erts_proclist_is_last(ErtsProcList *list, int erts_sched_set_wakeup_other_thresold(char *str); int erts_sched_set_wakeup_other_type(char *str); int erts_sched_set_busy_wait_threshold(char *str); +int erts_sched_set_wake_cleanup_threshold(char *); void erts_schedule_thr_prgr_later_op(void (*)(void *), void *, ErtsThrPrgrLaterOp *); +void erts_schedule_thr_prgr_later_cleanup_op(void (*)(void *), + void *, + ErtsThrPrgrLaterOp *, + UWord); #if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK) int erts_dbg_check_halloc_lock(Process *p); diff --git a/erts/emulator/beam/erl_ptab.c b/erts/emulator/beam/erl_ptab.c index 87beeafa1a..5bbc71c659 100644 --- a/erts/emulator/beam/erl_ptab.c +++ b/erts/emulator/beam/erl_ptab.c @@ -421,6 +421,7 @@ erts_ptab_init_table(ErtsPTab *ptab, void (*release_element)(void *), ErtsPTabElementCommon *invalid_element, int size, + UWord element_size, char *name) { size_t tab_sz; @@ -443,6 +444,7 @@ erts_ptab_init_table(ErtsPTab *ptab, bits = erts_fit_in_bits_int32((Sint32) size - 1); } + ptab->r.o.element_size = element_size; ptab->r.o.max = size; tab_sz = ERTS_ALC_CACHE_LINE_ALIGN_SIZE(size*sizeof(erts_smp_atomic_t)); @@ -670,9 +672,10 @@ erts_ptab_delete_element(ErtsPTab *ptab, } if (ptab->r.o.release_element) - erts_schedule_thr_prgr_later_op(ptab->r.o.release_element, - (void *) ptab_el, - &ptab_el->u.release); + erts_schedule_thr_prgr_later_cleanup_op(ptab->r.o.release_element, + (void *) ptab_el, + &ptab_el->u.release, + ptab->r.o.element_size); } /* diff --git a/erts/emulator/beam/erl_ptab.h b/erts/emulator/beam/erl_ptab.h index 8a130f42a3..7fa1251900 100644 --- a/erts/emulator/beam/erl_ptab.h +++ b/erts/emulator/beam/erl_ptab.h @@ -109,6 +109,7 @@ typedef struct { ErtsPTabElementCommon *invalid_element; Eterm invalid_data; void (*release_element)(void *); + UWord element_size; } ErtsPTabReadOnlyData; typedef struct { @@ -177,6 +178,7 @@ void erts_ptab_init_table(ErtsPTab *ptab, void (*release_element)(void *), ErtsPTabElementCommon *invalid_element, int size, + UWord element_size, char *name); int erts_ptab_new_element(ErtsPTab *ptab, ErtsPTabElementCommon *ptab_el, diff --git a/erts/emulator/beam/erl_thr_progress.c b/erts/emulator/beam/erl_thr_progress.c index 1292cb0678..cf5e3dc012 100644 --- a/erts/emulator/beam/erl_thr_progress.c +++ b/erts/emulator/beam/erl_thr_progress.c @@ -418,7 +418,7 @@ erts_thr_progress_pre_init(void) { intrnl = NULL; erts_tsd_key_create(&erts_thr_prgr_data_key__); - init_nob(&erts_thr_prgr__.current, 0); + init_nob(&erts_thr_prgr__.current, ERTS_THR_PRGR_VAL_FIRST); } void diff --git a/erts/emulator/beam/erl_thr_progress.h b/erts/emulator/beam/erl_thr_progress.h index 1416aa6166..1aeecf2b06 100644 --- a/erts/emulator/beam/erl_thr_progress.h +++ b/erts/emulator/beam/erl_thr_progress.h @@ -108,6 +108,8 @@ struct ErtsThrPrgrLaterOp_ { #ifdef ERTS_SMP +/* ERTS_THR_PRGR_VAL_FIRST should only be used when initializing... */ +#define ERTS_THR_PRGR_VAL_FIRST ((ErtsThrPrgrVal) 0) #define ERTS_THR_PRGR_VAL_WAITING (~((ErtsThrPrgrVal) 0)) #define ERTS_THR_PRGR_INVALID (~((ErtsThrPrgrVal) 0)) diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 8c67f731f4..43918a7141 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -2651,11 +2651,17 @@ void erts_init_io(int port_tab_size, int port_tab_size_ignore_files) { ErlDrvEntry** dp; + UWord common_element_size; erts_smp_rwmtx_opt_t drv_list_rwmtx_opts = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; drv_list_rwmtx_opts.type = ERTS_SMP_RWMTX_TYPE_EXTREMELY_FREQUENT_READ; drv_list_rwmtx_opts.lived = ERTS_SMP_RWMTX_LONG_LIVED; + common_element_size = ERTS_ALC_DATA_ALIGN_SIZE(sizeof(Port)); + common_element_size += ERTS_ALC_DATA_ALIGN_SIZE(sizeof(ErtsPortTaskBusyPortQ)); + common_element_size += 10; /* name */ #ifdef ERTS_SMP + common_element_size += sizeof(erts_mtx_t); + init_xports_list_alloc(); #endif @@ -2684,6 +2690,7 @@ void erts_init_io(int port_tab_size, NULL, (ErtsPTabElementCommon *) &erts_invalid_port.common, port_tab_size, + common_element_size, /* Doesn't need to be excact */ "port_table"); erts_smp_atomic_init_nob(&erts_bytes_out, 0); diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 9d674a7c65..31d9b2e0ad 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -125,6 +125,7 @@ static char *pluss_val_switches[] = { "cl", "ct", "tbt", + "wct", "wt", "ws", "ss", -- cgit v1.2.3 From a04209acfa6b0a691437d35b284268d093d7e2b1 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 3 Apr 2013 14:29:02 +0200 Subject: Fix `+sws' and `+swt' system flags --- erts/emulator/beam/erl_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 86adc5bc99..e6a96d427f 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -1425,7 +1425,7 @@ erl_start(int argc, char **argv) VERBOSE(DEBUG_SYSTEM, ("scheduler wake cleanup threshold: %s\n", arg)); } - else if (sys_strcmp("wt", sub_param) == 0) { + else if (has_prefix("wt", sub_param)) { arg = get_arg(sub_param+2, argv[i+1], &i); if (erts_sched_set_wakeup_other_thresold(arg) != 0) { erts_fprintf(stderr, "scheduler wakeup threshold: %s\n", @@ -1435,7 +1435,7 @@ erl_start(int argc, char **argv) VERBOSE(DEBUG_SYSTEM, ("scheduler wakeup threshold: %s\n", arg)); } - else if (sys_strcmp("ws", sub_param) == 0) { + else if (has_prefix("ws", sub_param)) { arg = get_arg(sub_param+2, argv[i+1], &i); if (erts_sched_set_wakeup_other_type(arg) != 0) { erts_fprintf(stderr, "scheduler wakeup strategy: %s\n", -- cgit v1.2.3 From 1e282b7b0c092f8f4619383741262583ff99b64c Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 4 Apr 2013 17:46:17 +0200 Subject: Make port close not be delayed Drivers are dereferenced when the port is completely gone, in the operation scheduled with erts_schedule_thr_prgr_later_op. If we use erts_schedule_thr_prgr_later_cleanup_op, it may not happen for a long time and the driver can not be unloaded. We can not dereference the driver before the thread_progress_later thing, because references to the driver may exist in other threads, so the unloading of the driver may free locks held by other schedulers and whatnot. --- erts/emulator/beam/erl_port_task.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 23000391ec..0ed08bee01 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -2001,10 +2001,10 @@ begin_port_cleanup(Port *pp, ErtsPortTask **execqp, int *processing_busy_q_p) * Schedule cleanup of port structure... */ #ifdef ERTS_SMP - erts_schedule_thr_prgr_later_cleanup_op(release_port, - (void *) pp, - &pp->common.u.release, - sizeof(Port)); + /* Has to be more or less immediate to release any driver */ + erts_schedule_thr_prgr_later_op(release_port, + (void *) pp, + &pp->common.u.release); #else pp->cleanup = 1; #endif -- cgit v1.2.3 From 7b31cdb80624567568474d79bff07e053457a450 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 4 Apr 2013 17:54:00 +0200 Subject: Prepare release --- erts/doc/src/notes.xml | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ erts/vsn.mk | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 7fc61517a8..c9c46afa4b 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,6 +30,61 @@

This document describes the changes made to the ERTS application.

+
Erts 5.10.1.1 + +
Fixed Bugs and Malfunctions + + +

+ The BIF is_process_alive/1 + could prematurely return false while the process + being inspected was terminating. This bug was introduced + in ERTS-5.10.

+

+ Own Id: OTP-10926

+
+ +

Fix a problem in erlang:delete_element/2 where + the call could corrupt one word of stack if the heap and + stack met during call.

+

+ Own Id: OTP-10932

+
+ +

+ The +sws<value> and + +swt<value> + system flags failed if no white space were passed between + the parameter and value parts of the flags. Upon failure, + the runtime system refused to start.

+

+ Own Id: OTP-11000

+
+
+
+ + +
Improvements and New Features + + +

+ Scheduler threads will now by default be less eager + requesting wakeup due to certain cleanup operations. This + can also be controlled using the +swct command line + argument of erl(1).

+

+ Own Id: OTP-10994

+
+
+
+ +
+
Erts 5.10.1
Fixed Bugs and Malfunctions diff --git a/erts/vsn.mk b/erts/vsn.mk index 4cdc20b550..07ca2ec1b3 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -17,7 +17,7 @@ # %CopyrightEnd% # -VSN = 5.10.1 +VSN = 5.10.1.1 SYSTEM_VSN = R16B # Port number 4365 in 4.2 -- cgit v1.2.3