diff options
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/break.c | 6 | ||||
-rw-r--r-- | erts/emulator/beam/dist.c | 57 | ||||
-rw-r--r-- | erts/emulator/beam/dist.h | 1 | ||||
-rw-r--r-- | erts/emulator/beam/erl_alloc_util.c | 16 | ||||
-rw-r--r-- | erts/emulator/beam/erl_bif_info.c | 41 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db.c | 6 | ||||
-rw-r--r-- | erts/emulator/beam/erl_hl_timer.c | 39 | ||||
-rw-r--r-- | erts/emulator/beam/erl_hl_timer.h | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_monitor_link.c | 128 | ||||
-rw-r--r-- | erts/emulator/beam/erl_monitor_link.h | 230 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_node_tables.c | 22 | ||||
-rw-r--r-- | erts/emulator/beam/erl_proc_sig_queue.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/erl_proc_sig_queue.h | 6 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 10 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.h | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process_dump.c | 10 | ||||
-rw-r--r-- | erts/emulator/beam/erl_rbtree.h | 280 | ||||
-rw-r--r-- | erts/emulator/beam/erl_time_sup.c | 6 | ||||
-rw-r--r-- | erts/emulator/beam/io.c | 12 |
20 files changed, 506 insertions, 394 deletions
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index 273b598562..27bf2187c2 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -129,7 +129,7 @@ typedef struct { void *to_arg; } PrintMonitorContext; -static void doit_print_link(ErtsLink *lnk, void *vpcontext) +static int doit_print_link(ErtsLink *lnk, void *vpcontext, Sint reds) { PrintMonitorContext *pcontext = vpcontext; fmtfn_t to = pcontext->to; @@ -141,10 +141,11 @@ static void doit_print_link(ErtsLink *lnk, void *vpcontext) } else { erts_print(to, to_arg, ", %T", lnk->other.item); } + return 1; } -static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext) +static int doit_print_monitor(ErtsMonitor *mon, void *vpcontext, Sint reds) { ErtsMonitorData *mdp; PrintMonitorContext *pcontext = vpcontext; @@ -196,6 +197,7 @@ static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext) /* ignore other monitors... */ break; } + return 1; } /* Display info about an individual Erlang process */ diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 15642e1669..21f994fd3e 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -185,20 +185,22 @@ get_suspended_on_de(DistEntry *dep, erts_aint32_t unset_qflgs) } } -#define ERTS_MON_LNK_FIRE_LIMIT 100 +#define ERTS_MON_LNK_FIRE_REDS 40 -static void monitor_connection_down(ErtsMonitor *mon, void *unused) +static int monitor_connection_down(ErtsMonitor *mon, void *unused, Sint reds) { if (erts_monitor_is_origin(mon)) erts_proc_sig_send_demonitor(mon); else erts_proc_sig_send_monitor_down(mon, am_noconnection); + return ERTS_MON_LNK_FIRE_REDS; } -static void link_connection_down(ErtsLink *lnk, void *vdist) +static int link_connection_down(ErtsLink *lnk, void *vdist, Sint reds) { erts_proc_sig_send_link_exit(NULL, THE_NON_VALUE, lnk, am_noconnection, NIL); + return ERTS_MON_LNK_FIRE_REDS; } typedef enum { @@ -226,35 +228,35 @@ con_monitor_link_cleanup(void *vcmlcp) ErtsConMonLnkCleanup *cmlcp = vcmlcp; ErtsMonLnkDist *dist = cmlcp->dist; ErtsSchedulerData *esdp; - int yield; + int reds = CONTEXT_REDS; switch (cmlcp->state) { case ERTS_CML_CLEANUP_STATE_LINKS: - yield = erts_link_list_foreach_delete_yielding(&dist->links, - link_connection_down, - NULL, &cmlcp->yield_state, - ERTS_MON_LNK_FIRE_LIMIT); - if (yield) + reds = erts_link_list_foreach_delete_yielding(&dist->links, + link_connection_down, + NULL, &cmlcp->yield_state, + reds); + if (reds <= 0) break; ASSERT(!cmlcp->yield_state); cmlcp->state = ERTS_CML_CLEANUP_STATE_MONITORS; case ERTS_CML_CLEANUP_STATE_MONITORS: - yield = erts_monitor_list_foreach_delete_yielding(&dist->monitors, - monitor_connection_down, - NULL, &cmlcp->yield_state, - ERTS_MON_LNK_FIRE_LIMIT); - if (yield) + reds = erts_monitor_list_foreach_delete_yielding(&dist->monitors, + monitor_connection_down, + NULL, &cmlcp->yield_state, + reds); + if (reds <= 0) break; ASSERT(!cmlcp->yield_state); cmlcp->state = ERTS_CML_CLEANUP_STATE_ONAME_MONITORS; case ERTS_CML_CLEANUP_STATE_ONAME_MONITORS: - yield = erts_monitor_tree_foreach_delete_yielding(&dist->orig_name_monitors, - monitor_connection_down, - NULL, &cmlcp->yield_state, - ERTS_MON_LNK_FIRE_LIMIT/2); - if (yield) + reds = erts_monitor_tree_foreach_delete_yielding(&dist->orig_name_monitors, + monitor_connection_down, + NULL, &cmlcp->yield_state, + reds); + if (reds <= 0) break; cmlcp->dist = NULL; @@ -1188,7 +1190,6 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote) #elif defined(VALGRIND) #include <valgrind/valgrind.h> #include <valgrind/memcheck.h> - # define PURIFY_MSG(msg) \ VALGRIND_PRINTF("%s, line %d: %s", __FILE__, __LINE__, msg) #else @@ -2891,7 +2892,7 @@ struct print_to_data { void *arg; }; -static void doit_print_monitor_info(ErtsMonitor *mon, void *vptdp) +static int doit_print_monitor_info(ErtsMonitor *mon, void *vptdp, Sint reds) { fmtfn_t to = ((struct print_to_data *) vptdp)->to; void *arg = ((struct print_to_data *) vptdp)->arg; @@ -2914,6 +2915,7 @@ static void doit_print_monitor_info(ErtsMonitor *mon, void *vptdp) else erts_print(to, arg, "%T\n", mdep->md.origin.other.item); } + return 1; } static void print_monitor_info(fmtfn_t to, void *arg, DistEntry *dep) @@ -2929,12 +2931,13 @@ static void print_monitor_info(fmtfn_t to, void *arg, DistEntry *dep) } } -static void doit_print_link_info(ErtsLink *lnk, void *vptdp) +static int doit_print_link_info(ErtsLink *lnk, void *vptdp, Sint reds) { struct print_to_data *ptdp = vptdp; ErtsLink *lnk2 = erts_link_to_other(lnk, NULL); erts_print(ptdp->to, ptdp->arg, "Remote link: %T %T\n", lnk2->other.item, lnk->other.item); + return 1; } static void print_link_info(fmtfn_t to, void *arg, DistEntry *dep) @@ -4150,8 +4153,8 @@ typedef struct { Uint i; } ErtsNodesMonitorContext; -static void -save_nodes_monitor(ErtsMonitor *mon, void *vctxt) +static int +save_nodes_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) { ErtsNodesMonitorContext *ctxt = vctxt; ErtsMonitorData *mdp = erts_monitor_to_data(mon); @@ -4163,6 +4166,7 @@ save_nodes_monitor(ErtsMonitor *mon, void *vctxt) ctxt->nmdp[ctxt->i].options = mdp->origin.other.item; ctxt->i++; + return 1; } static void @@ -4295,8 +4299,8 @@ typedef struct { } ErtsNodesMonitorInfoContext; -static void -nodes_monitor_info(ErtsMonitor *mon, void *vctxt) +static int +nodes_monitor_info(ErtsMonitor *mon, void *vctxt, Sint reds) { ErtsMonitorDataExtended *mdep; ErtsNodesMonitorInfoContext *ctxt = vctxt; @@ -4343,6 +4347,7 @@ nodes_monitor_info(ErtsMonitor *mon, void *vctxt) ctxt->hpp = hpp; ctxt->szp = szp; ctxt->res = res; + return 1; } Eterm diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index 845fab229a..a8ccd1eaec 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -404,5 +404,4 @@ extern Uint erts_dist_cache_size(void); extern Sint erts_abort_connection_rwunlock(DistEntry *dep); - #endif diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c index d238d38d27..8d4464969a 100644 --- a/erts/emulator/beam/erl_alloc_util.c +++ b/erts/emulator/beam/erl_alloc_util.c @@ -7503,7 +7503,7 @@ static int gather_ahist_scan(Allctr_t *allocator, return blocks_scanned; } -static void gather_ahist_append_result(hist_tree_t *node, void *arg) +static int gather_ahist_append_result(hist_tree_t *node, void *arg, Sint reds) { gather_ahist_t *state = (gather_ahist_t*)arg; @@ -7537,6 +7537,7 @@ static void gather_ahist_append_result(hist_tree_t *node, void *arg) /* Plain free is intentional. */ free(node); + return 1; } static void gather_ahist_send(gather_ahist_t *state) @@ -7595,11 +7596,11 @@ static int gather_ahist_finish(void *arg) state->building_result = 1; } - if (hist_tree_rbt_foreach_destroy_yielding(&state->hist_tree, - &gather_ahist_append_result, - state, - &state->hist_tree_yield, - BLOCKSCAN_REDUCTIONS)) { + if (!hist_tree_rbt_foreach_destroy_yielding(&state->hist_tree, + &gather_ahist_append_result, + state, + &state->hist_tree_yield, + BLOCKSCAN_REDUCTIONS)) { return 1; } @@ -7608,10 +7609,11 @@ static int gather_ahist_finish(void *arg) return 0; } -static void gather_ahist_destroy_result(hist_tree_t *node, void *arg) +static int gather_ahist_destroy_result(hist_tree_t *node, void *arg, Sint reds) { (void)arg; free(node); + return 1; } static void gather_ahist_abort(void *arg) diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 6f4e34e1a8..74708b2caa 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -227,7 +227,7 @@ bld_magic_ref_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh) }). */ -static void do_calc_mon_size(ErtsMonitor *mon, void *vpsz) +static int do_calc_mon_size(ErtsMonitor *mon, void *vpsz, Sint reds) { ErtsMonitorData *mdp = erts_monitor_to_data(mon); Uint *psz = vpsz; @@ -238,7 +238,8 @@ static void do_calc_mon_size(ErtsMonitor *mon, void *vpsz) else *psz += is_immed(mon->other.item) ? 0 : NC_HEAP_SIZE(mon->other.item); - *psz += 9; /* CONS + 6-tuple */ + *psz += 9; /* CONS + 6-tuple */ + return 1; } typedef struct { @@ -248,7 +249,7 @@ typedef struct { Eterm tag; } MonListContext; -static void do_make_one_mon_element(ErtsMonitor *mon, void * vpmlc) +static int do_make_one_mon_element(ErtsMonitor *mon, void * vpmlc, Sint reds) { ErtsMonitorData *mdp = erts_monitor_to_data(mon); MonListContext *pmlc = vpmlc; @@ -319,6 +320,7 @@ static void do_make_one_mon_element(ErtsMonitor *mon, void * vpmlc) pmlc->hp += 7; pmlc->res = CONS(pmlc->hp, tup, pmlc->res); pmlc->hp += 2; + return 1; } static Eterm @@ -328,7 +330,7 @@ make_monitor_list(Process *p, int tree, ErtsMonitor *root, Eterm tail) Uint sz = 0; MonListContext mlc; void (*foreach)(ErtsMonitor *, - void (*)(ErtsMonitor *, void *), + ErtsMonitorFunc, void *); foreach = tree ? erts_monitor_tree_foreach : erts_monitor_list_foreach; @@ -354,7 +356,7 @@ make_monitor_list(Process *p, int tree, ErtsMonitor *root, Eterm tail) }). */ -static void calc_lnk_size(ErtsLink *lnk, void *vpsz) +static int calc_lnk_size(ErtsLink *lnk, void *vpsz, Sint reds) { Uint *psz = vpsz; Uint sz = 0; @@ -364,7 +366,8 @@ static void calc_lnk_size(ErtsLink *lnk, void *vpsz) *psz += sz; *psz += is_immed(lnk->other.item) ? 0 : size_object(lnk->other.item); - *psz += 7; /* CONS + 4-tuple */ + *psz += 7; /* CONS + 4-tuple */ + return 1; } typedef struct { @@ -374,7 +377,7 @@ typedef struct { Eterm tag; } LnkListContext; -static void make_one_lnk_element(ErtsLink *lnk, void * vpllc) +static int make_one_lnk_element(ErtsLink *lnk, void * vpllc, Sint reds) { LnkListContext *pllc = vpllc; Eterm tup, t, pid, id; @@ -411,6 +414,7 @@ static void make_one_lnk_element(ErtsLink *lnk, void * vpllc) pllc->hp += 5; pllc->res = CONS(pllc->hp, tup, pllc->res); pllc->hp += 2; + return 1; } static Eterm @@ -420,7 +424,7 @@ make_link_list(Process *p, int tree, ErtsLink *root, Eterm tail) Uint sz = 0; LnkListContext llc; void (*foreach)(ErtsLink *, - void (*)(ErtsLink *, void *), + ErtsLinkFunc, void *); foreach = tree ? erts_link_tree_foreach : erts_link_list_foreach; @@ -519,16 +523,17 @@ do { \ } \ } while (0) -static void collect_one_link(ErtsLink *lnk, void *vmicp) +static int collect_one_link(ErtsLink *lnk, void *vmicp, Sint reds) { MonitorInfoCollection *micp = vmicp; EXTEND_MONITOR_INFOS(micp); micp->mi[micp->mi_i].entity.term = lnk->other.item; micp->sz += 2 + NC_HEAP_SIZE(lnk->other.item); micp->mi_i++; + return 1; } -static void collect_one_origin_monitor(ErtsMonitor *mon, void *vmicp) +static int collect_one_origin_monitor(ErtsMonitor *mon, void *vmicp, Sint reds) { if (erts_monitor_is_origin(mon)) { MonitorInfoCollection *micp = vmicp; @@ -573,9 +578,10 @@ static void collect_one_origin_monitor(ErtsMonitor *mon, void *vmicp) break; } } + return 1; } -static void collect_one_target_monitor(ErtsMonitor *mon, void *vmicp) +static int collect_one_target_monitor(ErtsMonitor *mon, void *vmicp, Sint reds) { MonitorInfoCollection *micp = vmicp; @@ -612,8 +618,8 @@ static void collect_one_target_monitor(ErtsMonitor *mon, void *vmicp) default: break; } - } + return 1; } typedef struct { @@ -653,8 +659,8 @@ do { \ } \ } while (0) -static void -collect_one_suspend_monitor(ErtsMonitor *mon, void *vsmicp) +static int +collect_one_suspend_monitor(ErtsMonitor *mon, void *vsmicp, Sint reds) { if (mon->type == ERTS_MON_TYPE_SUSPEND) { Sint count; @@ -678,6 +684,7 @@ collect_one_suspend_monitor(ErtsMonitor *mon, void *vsmicp) smicp->smi_i++; } + return 1; } /* @@ -3144,14 +3151,16 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_ERROR(BIF_P, BADARG); } -static void monitor_size(ErtsMonitor *mon, void *vsz) +static int monitor_size(ErtsMonitor *mon, void *vsz, Sint reds) { *((Uint *) vsz) = erts_monitor_size(mon); + return 1; } -static void link_size(ErtsMonitor *lnk, void *vsz) +static int link_size(ErtsMonitor *lnk, void *vsz, Sint reds) { *((Uint *) vsz) = erts_link_size(lnk); + return 1; } /**********************************************************************/ diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index df6f42edd3..0d570517ec 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -3912,7 +3912,7 @@ struct free_fixations_ctx SWord cnt; }; -static void free_fixations_op(DbFixation* fix, void* vctx) +static int free_fixations_op(DbFixation* fix, void* vctx, Sint reds) { struct free_fixations_ctx* ctx = (struct free_fixations_ctx*) vctx; erts_aint_t diff; @@ -3949,6 +3949,7 @@ static void free_fixations_op(DbFixation* fix, void* vctx) ERTS_ETS_MISC_MEM_ADD(-sizeof(DbFixation)); } ctx->cnt++; + return 1; } int erts_db_execute_free_fixation(Process* p, DbFixation* fix) @@ -4093,7 +4094,7 @@ struct fixing_procs_info_ctx Eterm list; }; -static void fixing_procs_info_op(DbFixation* fix, void* vctx) +static int fixing_procs_info_op(DbFixation* fix, void* vctx, Sint reds) { struct fixing_procs_info_ctx* ctx = (struct fixing_procs_info_ctx*) vctx; Eterm* hp; @@ -4103,6 +4104,7 @@ static void fixing_procs_info_op(DbFixation* fix, void* vctx) tpl = TUPLE2(hp, fix->procs.p->common.id, make_small(fix->counter)); hp += 3; ctx->list = CONS(hp, tpl, ctx->list); + return 1; } static Eterm table_info(Process* p, DbTable* tb, Eterm What) diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c index 75ad6de2c9..b0eb0e85c0 100644 --- a/erts/emulator/beam/erl_hl_timer.c +++ b/erts/emulator/beam/erl_hl_timer.c @@ -2263,9 +2263,10 @@ parse_bif_timer_options(Eterm option_list, int *async, return 1; } -static void -exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) +static int +exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp, Sint reds) { +#define ERTS_BTM_CANCEL_REDS 80 ErtsSchedulerData *esdp = (ErtsSchedulerData *) vesdp; Uint32 sid, roflgs; erts_aint_t state; @@ -2290,7 +2291,7 @@ exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) if (sid != (Uint32) esdp->no) { queue_canceled_timer(esdp, sid, (ErtsTimer *) tmr); - return; + return ERTS_BTM_CANCEL_REDS; } if (tmr->btm.tree.parent != ERTS_HLT_PFIELD_NOT_IN_TABLE) { @@ -2306,14 +2307,9 @@ exit_cancel_bif_timer(ErtsBifTimer *tmr, void *vesdp) hl_timer_dec_refc(&tmr->type.hlt, roflgs); else tw_timer_dec_refc(&tmr->type.twt); + return ERTS_BTM_CANCEL_REDS; } -#ifdef ERTS_HLT_DEBUG -# define ERTS_BTM_MAX_DESTROY_LIMIT 2 -#else -# define ERTS_BTM_MAX_DESTROY_LIMIT 50 -#endif - typedef struct { ErtsBifTimers *bif_timers; union { @@ -2321,10 +2317,9 @@ typedef struct { } u; } ErtsBifTimerYieldState; -int erts_cancel_bif_timers(Process *p, ErtsBifTimers **btm, void **vyspp) +int erts_cancel_bif_timers(Process *p, ErtsBifTimers **btm, void **vyspp, int reds) { ErtsSchedulerData *esdp = erts_proc_sched_data(p); - ErtsBifTimerYieldState ys = {*btm, {ERTS_RBT_YIELD_STAT_INITER}}; ErtsBifTimerYieldState *ysp; int res; @@ -2337,9 +2332,9 @@ int erts_cancel_bif_timers(Process *p, ErtsBifTimers **btm, void **vyspp) exit_cancel_bif_timer, (void *) esdp, &ysp->u.proc_btm_yield_state, - ERTS_BTM_MAX_DESTROY_LIMIT); + reds); - if (res == 0) { + if (res > 0) { if (ysp != &ys) erts_free(ERTS_ALC_T_BTM_YIELD_STATE, ysp); *vyspp = NULL; @@ -2819,8 +2814,8 @@ btm_print(ErtsBifTimer *tmr, void *vbtmp, ErtsMonotonicTime tpos, int is_hlt) (Sint64) left); } -static void -btm_tree_print(ErtsBifTimer *tmr, void *vbtmp) +static int +btm_tree_print(ErtsBifTimer *tmr, void *vbtmp, Sint reds) { int is_hlt = !!(tmr->type.head.roflgs & ERTS_TMR_ROFLG_HLT); ErtsMonotonicTime tpos; @@ -2829,6 +2824,7 @@ btm_tree_print(ErtsBifTimer *tmr, void *vbtmp) else tpos = erts_tweel_read_timeout(&tmr->type.twt.u.tw_tmr); btm_print(tmr, vbtmp, tpos, is_hlt); + return 1; } void @@ -2860,8 +2856,8 @@ typedef struct { void *arg; } ErtsBTMForeachDebug; -static void -debug_btm_foreach(ErtsBifTimer *tmr, void *vbtmfd) +static int +debug_btm_foreach(ErtsBifTimer *tmr, void *vbtmfd, Sint reds) { if (erts_atomic32_read_nob(&tmr->btm.state) == ERTS_TMR_STATE_ACTIVE) { ErtsBTMForeachDebug *btmfd = (ErtsBTMForeachDebug *) vbtmfd; @@ -2870,6 +2866,7 @@ debug_btm_foreach(ErtsBifTimer *tmr, void *vbtmfd) : tmr->type.head.receiver.proc->common.id); (*btmfd->func)(id, tmr->btm.message, tmr->btm.bp, btmfd->arg); } + return 1; } void @@ -2918,8 +2915,8 @@ debug_callback_timer_foreach_list(ErtsHLTimer *tmr, void *vdfct) tmr->head.u.arg); } -static void -debug_callback_timer_foreach(ErtsHLTimer *tmr, void *vdfct) +static int +debug_callback_timer_foreach(ErtsHLTimer *tmr, void *vdfct, Sint reds) { ErtsDebugForeachCallbackTimer *dfct = (ErtsDebugForeachCallbackTimer *) vdfct; @@ -2934,6 +2931,7 @@ debug_callback_timer_foreach(ErtsHLTimer *tmr, void *vdfct) (*dfct->func)(dfct->arg, tmr->timeout, tmr->head.u.arg); + return 1; } static void @@ -2981,7 +2979,8 @@ erts_debug_callback_timer_foreach(void (*tclbk)(void *), if (srv->yield.root) debug_callback_timer_foreach(srv->yield.root, - (void *) &dfct); + (void *) &dfct, + -1); time_rbt_foreach(srv->time_tree, debug_callback_timer_foreach, diff --git a/erts/emulator/beam/erl_hl_timer.h b/erts/emulator/beam/erl_hl_timer.h index e6f5e8b67d..29c873868b 100644 --- a/erts/emulator/beam/erl_hl_timer.h +++ b/erts/emulator/beam/erl_hl_timer.h @@ -56,7 +56,7 @@ void erts_cancel_proc_timer(Process *); void erts_set_port_timer(Port *, Sint64); void erts_cancel_port_timer(Port *); Sint64 erts_read_port_timer(Port *); -int erts_cancel_bif_timers(Process *, ErtsBifTimers **, void **); +int erts_cancel_bif_timers(Process *, ErtsBifTimers **, void **, int); int erts_detach_accessor_bif_timers(Process *, ErtsBifTimers *, void **); ErtsHLTimerService *erts_create_timer_service(void); void erts_hl_timer_init(void); diff --git a/erts/emulator/beam/erl_monitor_link.c b/erts/emulator/beam/erl_monitor_link.c index 48d9bd4ca5..3dabd79190 100644 --- a/erts/emulator/beam/erl_monitor_link.c +++ b/erts/emulator/beam/erl_monitor_link.c @@ -335,7 +335,7 @@ ml_rbt_delete(ErtsMonLnkNode **root, ErtsMonLnkNode *ml) static void ml_rbt_foreach(ErtsMonLnkNode *root, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg) { mon_lnk_rbt_foreach(root, func, arg); @@ -348,7 +348,7 @@ typedef struct { static int ml_rbt_foreach_yielding(ErtsMonLnkNode *root, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg, void **vyspp, Sint limit) @@ -362,7 +362,7 @@ ml_rbt_foreach_yielding(ErtsMonLnkNode *root, ysp = &ys; res = mon_lnk_rbt_foreach_yielding(ysp->root, func, arg, &ysp->rbt_ystate, limit); - if (res == 0) { + if (res > 0) { if (ysp != &ys) erts_free(ERTS_ALC_T_ML_YIELD_STATE, ysp); *vyspp = NULL; @@ -383,22 +383,22 @@ ml_rbt_foreach_yielding(ErtsMonLnkNode *root, } typedef struct { - void (*func)(ErtsMonLnkNode *, void *); + ErtsMonLnkNodeFunc func; void *arg; } ErtsMonLnkForeachDeleteContext; -static void -rbt_wrap_foreach_delete(ErtsMonLnkNode *ml, void *vctxt) +static int +rbt_wrap_foreach_delete(ErtsMonLnkNode *ml, void *vctxt, Sint reds) { ErtsMonLnkForeachDeleteContext *ctxt = vctxt; ERTS_ML_ASSERT(ml->flags & ERTS_ML_FLG_IN_TABLE); ml->flags &= ~ERTS_ML_FLG_IN_TABLE; - ctxt->func(ml, ctxt->arg); + return ctxt->func(ml, ctxt->arg, reds); } static void ml_rbt_foreach_delete(ErtsMonLnkNode **root, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg) { ErtsMonLnkForeachDeleteContext ctxt; @@ -411,7 +411,7 @@ ml_rbt_foreach_delete(ErtsMonLnkNode **root, static int ml_rbt_foreach_delete_yielding(ErtsMonLnkNode **root, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg, void **vyspp, Sint limit) @@ -433,7 +433,7 @@ ml_rbt_foreach_delete_yielding(ErtsMonLnkNode **root, (void *) &ctxt, &ysp->rbt_ystate, limit); - if (res == 0) { + if (res > 0) { if (ysp != &ys) erts_free(ERTS_ALC_T_ML_YIELD_STATE, ysp); *vyspp = NULL; @@ -459,12 +459,11 @@ ml_rbt_foreach_delete_yielding(ErtsMonLnkNode **root, static int ml_dl_list_foreach_yielding(ErtsMonLnkNode *list, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg, void **vyspp, - Sint limit) + Sint reds) { - Sint cnt = 0; ErtsMonLnkNode *ml = (ErtsMonLnkNode *) *vyspp; ERTS_ML_ASSERT(!ml || list); @@ -475,28 +474,26 @@ ml_dl_list_foreach_yielding(ErtsMonLnkNode *list, if (ml) { do { ERTS_ML_ASSERT(ml->flags & ERTS_ML_FLG_IN_TABLE); - func(ml, arg); + reds -= func(ml, arg, reds); ml = ml->node.list.next; - cnt++; - } while (ml != list && cnt < limit); + } while (ml != list && reds > 0); if (ml != list) { *vyspp = (void *) ml; - return 1; /* yield */ + return 0; /* yield */ } } *vyspp = NULL; - return 0; /* done */ + return reds <= 0 ? 1 : reds; /* done */ } static int ml_dl_list_foreach_delete_yielding(ErtsMonLnkNode **list, - void (*func)(ErtsMonLnkNode *, void *), + ErtsMonLnkNodeFunc func, void *arg, void **vyspp, - Sint limit) + Sint reds) { - Sint cnt = 0; ErtsMonLnkNode *first = *list; ErtsMonLnkNode *ml = (ErtsMonLnkNode *) *vyspp; @@ -510,19 +507,18 @@ ml_dl_list_foreach_delete_yielding(ErtsMonLnkNode **list, ErtsMonLnkNode *next = ml->node.list.next; ERTS_ML_ASSERT(ml->flags & ERTS_ML_FLG_IN_TABLE); ml->flags &= ~ERTS_ML_FLG_IN_TABLE; - func(ml, arg); + reds -= func(ml, arg, reds); ml = next; - cnt++; - } while (ml != first && cnt < limit); + } while (ml != first && reds > 0); if (ml != first) { *vyspp = (void *) ml; - return 1; /* yield */ + return 0; /* yield */ } } *vyspp = NULL; *list = NULL; - return 0; /* done */ + return reds <= 0 ? 1 : reds; /* done */ } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ @@ -666,91 +662,91 @@ erts_monitor_tree_delete(ErtsMonitor **root, ErtsMonitor *mon) void erts_monitor_tree_foreach(ErtsMonitor *root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg) { ml_rbt_foreach((ErtsMonLnkNode *) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg); } int erts_monitor_tree_foreach_yielding(ErtsMonitor *root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, Sint limit) { return ml_rbt_foreach_yielding((ErtsMonLnkNode *) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (int (*)(ErtsMonLnkNode*, void*, Sint)) func, arg, vyspp, limit); } void erts_monitor_tree_foreach_delete(ErtsMonitor **root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg) { ml_rbt_foreach_delete((ErtsMonLnkNode **) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (int (*)(ErtsMonLnkNode*, void*, Sint)) func, arg); } int erts_monitor_tree_foreach_delete_yielding(ErtsMonitor **root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, Sint limit) { return ml_rbt_foreach_delete_yielding((ErtsMonLnkNode **) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (int (*)(ErtsMonLnkNode*, void*, Sint)) func, arg, vyspp, limit); } void erts_monitor_list_foreach(ErtsMonitor *list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg) { void *ystate = NULL; - while (ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, - (void (*)(ErtsMonLnkNode *, void *)) func, - arg, &ystate, (Sint) INT_MAX)); + while (!ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, + (int (*)(ErtsMonLnkNode *, void *, Sint)) func, + arg, &ystate, (Sint) INT_MAX)); } int erts_monitor_list_foreach_yielding(ErtsMonitor *list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, Sint limit) { return ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, - (void (*)(ErtsMonLnkNode *, void *)) func, + (int (*)(ErtsMonLnkNode *, void *, Sint)) func, arg, vyspp, limit); } void erts_monitor_list_foreach_delete(ErtsMonitor **list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg) { void *ystate = NULL; - while (ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, - (void (*)(ErtsMonLnkNode*, void*)) func, - arg, &ystate, (Sint) INT_MAX)); + while (!ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, + (int (*)(ErtsMonLnkNode*, void*, Sint)) func, + arg, &ystate, (Sint) INT_MAX)); } int erts_monitor_list_foreach_delete_yielding(ErtsMonitor **list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, Sint limit) { return ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, - (void (*)(ErtsMonLnkNode*, void*)) func, + (int (*)(ErtsMonLnkNode*, void*, Sint)) func, arg, vyspp, limit); } @@ -1074,92 +1070,92 @@ erts_link_tree_delete(ErtsLink **root, ErtsLink *lnk) void erts_link_tree_foreach(ErtsLink *root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg) { ml_rbt_foreach((ErtsMonLnkNode *) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg); } int erts_link_tree_foreach_yielding(ErtsLink *root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, Sint limit) { return ml_rbt_foreach_yielding((ErtsMonLnkNode *) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg, vyspp, limit); } void erts_link_tree_foreach_delete(ErtsLink **root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg) { ml_rbt_foreach_delete((ErtsMonLnkNode **) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg); } int erts_link_tree_foreach_delete_yielding(ErtsLink **root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, Sint limit) { return ml_rbt_foreach_delete_yielding((ErtsMonLnkNode **) root, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg, vyspp, limit); } void erts_link_list_foreach(ErtsLink *list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg) { void *ystate = NULL; - while (ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, - (void (*)(ErtsMonLnkNode *, void *)) func, - arg, &ystate, (Sint) INT_MAX)); + while (!ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, + (ErtsMonLnkNodeFunc) func, + arg, &ystate, (Sint) INT_MAX)); } int erts_link_list_foreach_yielding(ErtsLink *list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, Sint limit) { return ml_dl_list_foreach_yielding((ErtsMonLnkNode *) list, - (void (*)(ErtsMonLnkNode *, void *)) func, + (ErtsMonLnkNodeFunc) func, arg, vyspp, limit); } void erts_link_list_foreach_delete(ErtsLink **list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg) { void *ystate = NULL; - while (ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, - (void (*)(ErtsMonLnkNode*, void*)) func, - arg, &ystate, (Sint) INT_MAX)); + while (!ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, + (ErtsMonLnkNodeFunc) func, + arg, &ystate, (Sint) INT_MAX)); } int erts_link_list_foreach_delete_yielding(ErtsLink **list, - void (*func)(ErtsLink *, void *), + int (*func)(ErtsLink *, void *, Sint), void *arg, void **vyspp, Sint limit) { return ml_dl_list_foreach_delete_yielding((ErtsMonLnkNode **) list, - (void (*)(ErtsMonLnkNode*, void*)) func, + (ErtsMonLnkNodeFunc) func, arg, vyspp, limit); } diff --git a/erts/emulator/beam/erl_monitor_link.h b/erts/emulator/beam/erl_monitor_link.h index ed7bf7d54a..eff861fce8 100644 --- a/erts/emulator/beam/erl_monitor_link.h +++ b/erts/emulator/beam/erl_monitor_link.h @@ -439,6 +439,7 @@ (ERTS_ML_FLG_EXTENDED|ERTS_ML_FLG_NAME) typedef struct ErtsMonLnkNode__ ErtsMonLnkNode; +typedef int (*ErtsMonLnkNodeFunc)(ErtsMonLnkNode *, void *, Sint); typedef struct { UWord parent; /* Parent ptr and flags... */ @@ -622,6 +623,7 @@ erts_ml_dl_list_last__(ErtsMonLnkNode *list) typedef struct ErtsMonLnkNode__ ErtsMonitor; +typedef int (*ErtsMonitorFunc)(ErtsMonitor *, void *, Sint); typedef struct { ErtsMonitor origin; @@ -653,6 +655,7 @@ struct ErtsMonitorDataExtended__ { typedef struct ErtsMonitorSuspend__ ErtsMonitorSuspend; + struct ErtsMonitorSuspend__ { ErtsMonitorData md; /* origin = suspender; target = suspendee */ ErtsMonitorSuspend *next; @@ -685,7 +688,7 @@ ErtsMonitor *erts_monitor_tree_lookup(ErtsMonitor *root, Eterm key); * * @brief Lookup or insert a monitor in a monitor tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is not part of any tree or list * If the above is not true, bad things will happen. * @@ -711,7 +714,7 @@ ErtsMonitor *erts_monotor_tree_lookup_insert(ErtsMonitor **root, * If it is not found, creates a monitor and returns a pointer to the * origin monitor. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - no target monitors with the key 'target' exists in the tree. * If the above is not true, bad things will happen. * @@ -738,7 +741,7 @@ ErtsMonitor *erts_monitor_tree_lookup_create(ErtsMonitor **root, int *created, * * @brief Insert a monitor in a monitor tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - no monitors with the same key that 'mon' exist in the tree * - 'mon' is not part of any list of tree * If the above are not true, bad things will happen. @@ -754,7 +757,7 @@ void erts_monitor_tree_insert(ErtsMonitor **root, ErtsMonitor *mon); * * @brief Replace a monitor in a monitor tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'old' monitor and 'new' monitor have exactly the same key * - 'old' monitor is part of the tree * - 'new' monitor is not part of any tree or list @@ -774,7 +777,7 @@ void erts_monitor_tree_replace(ErtsMonitor **root, ErtsMonitor *old, * * @brief Delete a monitor from a monitor tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is part of the tree * If the above is not true, bad things will happen. * @@ -789,7 +792,7 @@ void erts_monitor_tree_delete(ErtsMonitor **root, ErtsMonitor *mon); * * @brief Call a function for each monitor in a monitor tree * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor * in the tree referred to by 'root'. * @@ -802,7 +805,7 @@ void erts_monitor_tree_delete(ErtsMonitor **root, ErtsMonitor *mon); * */ void erts_monitor_tree_foreach(ErtsMonitor *root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg); /** @@ -810,9 +813,10 @@ void erts_monitor_tree_foreach(ErtsMonitor *root, * @brief Call a function for each monitor in a monitor tree. Yield * if lots of monitors exist. * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -835,27 +839,28 @@ void erts_monitor_tree_foreach(ErtsMonitor *root, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of monitors to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all monitors has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all monitors + * have been processed, and zero when more work + * is needed. * */ int erts_monitor_tree_foreach_yielding(ErtsMonitor *root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /** * * @brief Delete all monitors from a monitor tree and call a function for * each monitor * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * @param[in,out] root Pointer to pointer to root of monitor tree * @@ -866,7 +871,7 @@ int erts_monitor_tree_foreach_yielding(ErtsMonitor *root, * */ void erts_monitor_tree_foreach_delete(ErtsMonitor **root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg); /** @@ -874,9 +879,10 @@ void erts_monitor_tree_foreach_delete(ErtsMonitor **root, * @brief Delete all monitors from a monitor tree and call a function for * each monitor * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -899,18 +905,18 @@ void erts_monitor_tree_foreach_delete(ErtsMonitor **root, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of monitors to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all monitors has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all monitors + * have been processed, and zero when more work + * is needed. * */ int erts_monitor_tree_foreach_delete_yielding(ErtsMonitor **root, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /* * --- Monitor list operations -- @@ -920,7 +926,7 @@ int erts_monitor_tree_foreach_delete_yielding(ErtsMonitor **root, * * @brief Insert a monitor in a monitor list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is not part of any list or tree * If the above is not true, bad things will happen. * @@ -935,7 +941,7 @@ ERTS_GLB_INLINE void erts_monitor_list_insert(ErtsMonitor **list, ErtsMonitor *m * * @brief Delete a monitor from a monitor list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is part of the list * If the above is not true, bad things will happen. * @@ -980,7 +986,7 @@ ERTS_GLB_INLINE ErtsMonitor *erts_monitor_list_last(ErtsMonitor *list); * * @brief Call a function for each monitor in a monitor list * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor * in the tree referred to by 'list'. * @@ -993,7 +999,7 @@ ERTS_GLB_INLINE ErtsMonitor *erts_monitor_list_last(ErtsMonitor *list); * */ void erts_monitor_list_foreach(ErtsMonitor *list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg); /** @@ -1001,9 +1007,10 @@ void erts_monitor_list_foreach(ErtsMonitor *list, * @brief Call a function for each monitor in a monitor list. Yield * if lots of monitors exist. * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1026,25 +1033,25 @@ void erts_monitor_list_foreach(ErtsMonitor *list, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of monitors to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all monitors has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all monitors + * have been processed, and zero when more work + * is needed. * */ int erts_monitor_list_foreach_yielding(ErtsMonitor *list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /** * * @brief Delete all monitors from a monitor list and call a function for * each monitor * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor * in the tree referred to by 'root'. * @@ -1057,7 +1064,7 @@ int erts_monitor_list_foreach_yielding(ErtsMonitor *list, * */ void erts_monitor_list_foreach_delete(ErtsMonitor **list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg); /** @@ -1065,9 +1072,10 @@ void erts_monitor_list_foreach_delete(ErtsMonitor **list, * @brief Delete all monitors from a monitor list and call a function for * each monitor * - * The funcion 'func' will be called with a pointer to a monitor + * The function 'func' will be called with a pointer to a monitor * as first argument and 'arg' as second argument for each monitor - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1090,18 +1098,18 @@ void erts_monitor_list_foreach_delete(ErtsMonitor **list, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of monitors to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all monitors has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all monitors + * have been processed, and zero when more work + * is needed. * */ int erts_monitor_list_foreach_delete_yielding(ErtsMonitor **list, - void (*func)(ErtsMonitor *, void *), + ErtsMonitorFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /* * --- Misc monitor operations --- @@ -1113,7 +1121,7 @@ int erts_monitor_list_foreach_delete_yielding(ErtsMonitor **list, * * Can create all types of monitors * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'ref' is an internal ordinary reference if type is ERTS_MON_TYPE_PROC, * ERTS_MON_TYPE_PORT, ERTS_MON_TYPE_TIME_OFFSET, or ERTS_MON_TYPE_RESOURCE * - 'ref' is NIL if type is ERTS_MON_TYPE_NODE, ERTS_MON_TYPE_NODES, or @@ -1199,7 +1207,7 @@ ERTS_GLB_INLINE int erts_monitor_is_in_table(ErtsMonitor *mon); * When both the origin and the target part of the monitor have * been released the monitor structure will be deallocated. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is not part of any list or tree * - 'mon' is not referred to by any other structures * If the above are not true, bad things will happen. @@ -1216,7 +1224,7 @@ ERTS_GLB_INLINE void erts_monitor_release(ErtsMonitor *mon); * Release both the origin and target parts of the monitor * simultaneously and deallocate the structure. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - Neither the origin part nor the target part of the monitor * are not part of any list or tree * - Neither the origin part nor the target part of the monitor @@ -1232,7 +1240,7 @@ ERTS_GLB_INLINE void erts_monitor_release_both(ErtsMonitorData *mdp); * * @brief Insert monitor in dist monitor tree or list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor is not part of any list or tree * If the above is not true, bad things will happen. * @@ -1253,7 +1261,7 @@ ERTS_GLB_INLINE int erts_monitor_dist_insert(ErtsMonitor *mon, ErtsMonLnkDist *d * * @brief Delete monitor from dist monitor tree or list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' monitor earler has been inserted into 'dist' * If the above is not true, bad things will happen. * @@ -1291,7 +1299,7 @@ erts_monitor_set_dead_dist(ErtsMonitor *mon, Eterm nodename); * whole size of the monitor data structure is returned; otherwise, * half of the size is returned. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'mon' has not been released * If the above is not true, bad things will happen. * @@ -1507,6 +1515,8 @@ ERTS_GLB_INLINE ErtsMonitorSuspend *erts_monitor_suspend(ErtsMonitor *mon) typedef struct ErtsMonLnkNode__ ErtsLink; +typedef int (*ErtsLinkFunc)(ErtsLink *, void *, Sint); + typedef struct { ErtsLink a; ErtsLink b; @@ -1544,7 +1554,7 @@ ErtsLink *erts_link_tree_lookup(ErtsLink *root, Eterm item); * * @brief Lookup or insert a link in a link tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is not part of any tree or list * If the above is not true, bad things will happen. * @@ -1590,7 +1600,7 @@ ErtsLink *erts_link_tree_lookup_create(ErtsLink **root, int *created, * * @brief Insert a link in a link tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - no links with the same key that 'lnk' exist in the tree * - 'lnk' is not part of any list of tree * If the above are not true, bad things will happen. @@ -1606,7 +1616,7 @@ void erts_link_tree_insert(ErtsLink **root, ErtsLink *lnk); * * @brief Replace a link in a link tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'old' link and 'new' link have exactly the same key * - 'old' link is part of the tree * - 'new' link is not part of any tree or list @@ -1630,7 +1640,7 @@ void erts_link_tree_replace(ErtsLink **root, ErtsLink *old, ErtsLink *new); * the tree and 'lnk' has a lower address than the link in the * tree, the existing link in the tree is replaced by 'lnk'. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is not part of any tree or list * If the above are not true, bad things will happen. * @@ -1649,7 +1659,7 @@ ERTS_GLB_INLINE ErtsLink *erts_link_tree_insert_addr_replace(ErtsLink **root, * * @brief Delete a link from a link tree * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is part of the tree * If the above is not true, bad things will happen. * @@ -1668,7 +1678,7 @@ void erts_link_tree_delete(ErtsLink **root, ErtsLink *lnk); * If link 'lnk' is not in the tree, another link with the same * key as 'lnk' is deleted from the tree if such a link exist. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - if 'lnk' link is part of a tree or list, it is part of this tree * If the above is not true, bad things will happen. * @@ -1687,7 +1697,7 @@ ERTS_GLB_INLINE ErtsLink *erts_link_tree_key_delete(ErtsLink **root, ErtsLink *l * * @brief Call a function for each link in a link tree * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link * in the tree referred to by 'root'. * @@ -1700,7 +1710,7 @@ ERTS_GLB_INLINE ErtsLink *erts_link_tree_key_delete(ErtsLink **root, ErtsLink *l * */ void erts_link_tree_foreach(ErtsLink *root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc, void *arg); /** @@ -1708,9 +1718,10 @@ void erts_link_tree_foreach(ErtsLink *root, * @brief Call a function for each link in a link tree. Yield if lots * of links exist. * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1733,25 +1744,25 @@ void erts_link_tree_foreach(ErtsLink *root, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of links to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all links has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all links + * have been processed, and zero when more work + * is needed. * */ int erts_link_tree_foreach_yielding(ErtsLink *root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /** * * @brief Delete all links from a link tree and call a function for * each link * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link * in the tree referred to by 'root'. * @@ -1764,7 +1775,7 @@ int erts_link_tree_foreach_yielding(ErtsLink *root, * */ void erts_link_tree_foreach_delete(ErtsLink **root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg); /** @@ -1772,9 +1783,10 @@ void erts_link_tree_foreach_delete(ErtsLink **root, * @brief Delete all links from a link tree and call a function for * each link * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1797,18 +1809,18 @@ void erts_link_tree_foreach_delete(ErtsLink **root, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of links to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all links has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all links + * have been processed, and zero when more work + * is needed. * */ int erts_link_tree_foreach_delete_yielding(ErtsLink **root, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /* * --- Link list operations --- @@ -1818,7 +1830,7 @@ int erts_link_tree_foreach_delete_yielding(ErtsLink **root, * * @brief Insert a link in a link list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is not part of any list or tree * If the above is not true, bad things will happen. * @@ -1833,7 +1845,7 @@ ERTS_GLB_INLINE void erts_link_list_insert(ErtsLink **list, ErtsLink *lnk); * * @brief Delete a link from a link list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is part of the list * If the above is not true, bad things will happen. * @@ -1878,7 +1890,7 @@ ERTS_GLB_INLINE ErtsLink *erts_link_list_last(ErtsLink *list); * * @brief Call a function for each link in a link list * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link * in the tree referred to by 'list'. * @@ -1891,7 +1903,7 @@ ERTS_GLB_INLINE ErtsLink *erts_link_list_last(ErtsLink *list); * */ void erts_link_list_foreach(ErtsLink *list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg); /** @@ -1899,9 +1911,10 @@ void erts_link_list_foreach(ErtsLink *list, * @brief Call a function for each link in a link list. Yield * if lots of links exist. * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1924,25 +1937,25 @@ void erts_link_list_foreach(ErtsLink *list, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of links to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all links has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all links + * have been processed, and zero when more work + * is needed. * */ int erts_link_list_foreach_yielding(ErtsLink *list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /** * * @brief Delete all links from a link list and call a function for * each link * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link * in the tree referred to by 'root'. * @@ -1955,7 +1968,7 @@ int erts_link_list_foreach_yielding(ErtsLink *list, * */ void erts_link_list_foreach_delete(ErtsLink **list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg); /** @@ -1963,9 +1976,10 @@ void erts_link_list_foreach_delete(ErtsLink **list, * @brief Delete all links from a link list and call a function for * each link * - * The funcion 'func' will be called with a pointer to a link + * The function 'func' will be called with a pointer to a link * as first argument and 'arg' as second argument for each link - * in the tree referred to by 'root'. + * in the tree referred to by 'root'. It should return the number of + * reductions the operator took to perform. * * It is assumed that: * - *yspp equals NULL on first call @@ -1988,18 +2002,18 @@ void erts_link_list_foreach_delete(ErtsLink **list, * *yspp should be NULL. When done *yspp * will be NULL. * - * @param[in] limit Maximum amount of links to process - * before yielding. + * @param[in] reds Reductions available to execute before yielding. * - * @returns A non-zero value when all links has been - * processed, and zero when more work is needed. + * @returns The unconsumed reductions when all links + * have been processed, and zero when more work + * is needed. * */ int erts_link_list_foreach_delete_yielding(ErtsLink **list, - void (*func)(ErtsLink *, void *), + ErtsLinkFunc func, void *arg, void **vyspp, - Sint limit); + Sint reds); /* * --- Misc link operations --- @@ -2011,7 +2025,7 @@ int erts_link_list_foreach_delete_yielding(ErtsLink **list, * * Can create all types of links * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'ref' is an internal ordinary reference if type is ERTS_MON_TYPE_PROC, * ERTS_MON_TYPE_PORT, ERTS_MON_TYPE_TIME_OFFSET, or ERTS_MON_TYPE_RESOURCE * - 'ref' is NIL if type is ERTS_MON_TYPE_NODE or ERTS_MON_TYPE_NODES @@ -2081,7 +2095,7 @@ ERTS_GLB_INLINE int erts_link_is_in_table(ErtsLink *lnk); * When both link halves part of the link have been released the link * structure will be deallocated. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is not part of any list or tree * - 'lnk' is not referred to by any other structures * If the above are not true, bad things will happen. @@ -2098,7 +2112,7 @@ ERTS_GLB_INLINE void erts_link_release(ErtsLink *lnk); * Release both halves of a link simultaneously and deallocate * the structure. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - Neither of the parts of the link are part of any list or tree * - Neither of the parts of the link or the link data structure * are referred to by any other structures @@ -2113,7 +2127,7 @@ ERTS_GLB_INLINE void erts_link_release_both(ErtsLinkData *ldp); * * @brief Insert link in dist link list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link is not part of any list or tree * If the above is not true, bad things will happen. * @@ -2134,7 +2148,7 @@ ERTS_GLB_INLINE int erts_link_dist_insert(ErtsLink *lnk, ErtsMonLnkDist *dist); * * @brief Delete link from dist link list * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' link earler has been inserted into 'dist' * If the above is not true, bad things will happen. * @@ -2172,7 +2186,7 @@ erts_link_set_dead_dist(ErtsLink *lnk, Eterm nodename); * whole size of the link data structure is returned; otherwise, * half of the size is returned. * - * When the funcion is called it is assumed that: + * When the function is called it is assumed that: * - 'lnk' has not been released * If the above is not true, bad things will happen. * diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index a48d0391f6..4f317c9b25 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -2357,12 +2357,13 @@ rmon_refc_read(ErtsResourceMonitors *rms) return rms->refc & ERTS_RESOURCE_REFC_MASK; } -static void dtor_demonitor(ErtsMonitor* mon, void* context) +static int dtor_demonitor(ErtsMonitor* mon, void* context, Sint reds) { ASSERT(erts_monitor_is_origin(mon)); ASSERT(is_internal_pid(mon->other.item)); erts_proc_sig_send_demonitor(mon); + return 1; } # define NIF_RESOURCE_DTOR &nif_resource_dtor diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 18ed782ae3..b7dbe625a2 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -1544,16 +1544,18 @@ static void insert_monitor_data(ErtsMonitor *mon, int type, Eterm id) mdp->origin.flags |= ERTS_ML_FLG_DBG_VISITED; } -static void insert_monitor(ErtsMonitor *mon, void *idp) +static int insert_monitor(ErtsMonitor *mon, void *idp, Sint reds) { Eterm id = *((Eterm *) idp); insert_monitor_data(mon, MONITOR_REF, id); + return 1; } -static void clear_visited_monitor(ErtsMonitor *mon, void *p) +static int clear_visited_monitor(ErtsMonitor *mon, void *p, Sint reds) { ErtsMonitorData *mdp = erts_monitor_to_data(mon); mdp->origin.flags &= ~ERTS_ML_FLG_DBG_VISITED; + return 1; } static void @@ -1621,16 +1623,18 @@ static void insert_link_data(ErtsLink *lnk, int type, Eterm id) ldp->a.flags |= ERTS_ML_FLG_DBG_VISITED; } -static void insert_link(ErtsLink *lnk, void *idp) +static int insert_link(ErtsLink *lnk, void *idp, Sint reds) { Eterm id = *((Eterm *) idp); insert_link_data(lnk, LINK_REF, id); + return 1; } -static void clear_visited_link(ErtsLink *lnk, void *p) +static int clear_visited_link(ErtsLink *lnk, void *p, Sint reds) { ErtsLinkData *ldp = erts_link_to_data(lnk); ldp->a.flags &= ~ERTS_ML_FLG_DBG_VISITED; + return 1; } static void @@ -1798,18 +1802,20 @@ insert_sig_offheap(ErlOffHeap *ohp, void *arg) insert_offheap(ohp, SIGNAL_REF, proc->common.id); } -static void -insert_sig_monitor(ErtsMonitor *mon, void *arg) +static int +insert_sig_monitor(ErtsMonitor *mon, void *arg, Sint reds) { Process *proc = arg; insert_monitor_data(mon, SIGNAL_REF, proc->common.id); + return 1; } -static void -insert_sig_link(ErtsLink *lnk, void *arg) +static int +insert_sig_link(ErtsLink *lnk, void *arg, Sint reds) { Process *proc = arg; insert_link_data(lnk, SIGNAL_REF, proc->common.id); + return 1; } static void diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index 18418a76e1..668ee4ce96 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -3590,9 +3590,10 @@ stretch_limit(Process *c_p, ErtsSigRecvTracing *tp, int -erts_proc_sig_handle_exit(Process *c_p, int *redsp) +erts_proc_sig_handle_exit(Process *c_p, Sint *redsp) { - int cnt, limit; + int cnt; + Sint limit; ErtsMessage *sig, ***next_nm_sig; ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(c_p, 0); @@ -3673,7 +3674,7 @@ erts_proc_sig_handle_exit(Process *c_p, int *redsp) case ERTS_SIG_Q_OP_MONITOR: { ErtsProcExitContext pectxt = {c_p, am_noproc}; erts_proc_exit_handle_monitor((ErtsMonitor *) sig, - (void *) &pectxt); + (void *) &pectxt, -1); cnt += 4; break; } @@ -3687,7 +3688,7 @@ erts_proc_sig_handle_exit(Process *c_p, int *redsp) case ERTS_SIG_Q_OP_LINK: { ErtsProcExitContext pectxt = {c_p, am_noproc}; - erts_proc_exit_handle_link((ErtsLink *) sig, (void *) &pectxt); + erts_proc_exit_handle_link((ErtsLink *) sig, (void *) &pectxt, -1); break; } @@ -4449,8 +4450,8 @@ void erts_proc_sig_debug_foreach_sig(Process *c_p, void (*msg_func)(ErtsMessage *, void *), void (*oh_func)(ErlOffHeap *, void *), - void (*mon_func)(ErtsMonitor *, void *), - void (*lnk_func)(ErtsLink *, void *), + ErtsMonitorFunc mon_func, + ErtsLinkFunc lnk_func, void *arg) { ErtsMessage *queue[] = {c_p->sig_qs.first, c_p->sig_qs.cont, c_p->sig_inq.first}; @@ -4486,13 +4487,13 @@ erts_proc_sig_debug_foreach_sig(Process *c_p, case ERTS_LNK_TYPE_PORT: case ERTS_LNK_TYPE_PROC: case ERTS_LNK_TYPE_DIST_PROC: - lnk_func((ErtsLink *) sig, arg); + lnk_func((ErtsLink *) sig, arg, -1); break; case ERTS_MON_TYPE_PORT: case ERTS_MON_TYPE_PROC: case ERTS_MON_TYPE_DIST_PROC: case ERTS_MON_TYPE_NODE: - mon_func((ErtsMonitor *) sig, arg); + mon_func((ErtsMonitor *) sig, arg, -1); break; default: ERTS_INTERNAL_ERROR("Unexpected sig type"); @@ -4513,7 +4514,7 @@ erts_proc_sig_debug_foreach_sig(Process *c_p, /* Fall through... */ case ERTS_SIG_Q_OP_MONITOR: - mon_func((ErtsMonitor *) sig, arg); + mon_func((ErtsMonitor *) sig, arg, -1); break; case ERTS_SIG_Q_OP_UNLINK: @@ -4525,7 +4526,7 @@ erts_proc_sig_debug_foreach_sig(Process *c_p, /* Fall through... */ case ERTS_SIG_Q_OP_LINK: - lnk_func((ErtsLink *) sig, arg); + lnk_func((ErtsLink *) sig, arg, -1); break; case ERTS_SIG_Q_OP_GROUP_LEADER: { diff --git a/erts/emulator/beam/erl_proc_sig_queue.h b/erts/emulator/beam/erl_proc_sig_queue.h index 6b065a7add..5a02708bb7 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.h +++ b/erts/emulator/beam/erl_proc_sig_queue.h @@ -740,7 +740,7 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep, * queue. */ int -erts_proc_sig_handle_exit(Process *c_p, int *redsp); +erts_proc_sig_handle_exit(Process *c_p, Sint *redsp); /** * @@ -970,8 +970,8 @@ void erts_proc_sig_debug_foreach_sig(Process *c_p, void (*msg_func)(ErtsMessage *, void *), void (*oh_func)(ErlOffHeap *, void *), - void (*mon_func)(ErtsMonitor *, void *), - void (*lnk_func)(ErtsLink *, void *), + ErtsMonitorFunc mon_func, + ErtsLinkFunc lnk_func, void *arg); extern Process *erts_dirty_process_signal_handler; diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index c2799f6612..f9cc85b6d7 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -12055,8 +12055,8 @@ erts_set_self_exiting(Process *c_p, Eterm reason) add2runq(enqueue, enq_prio, c_p, state, NULL); } -void -erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt) +int +erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) { Process *c_p = ((ErtsProcExitContext *) vctxt)->c_p; Eterm reason = ((ErtsProcExitContext *) vctxt)->reason; @@ -12215,10 +12215,11 @@ erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt) erts_monitor_release_both(mdp); else if (mon) erts_monitor_release(mon); + return 1; } -void -erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt) +int +erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt, Sint reds) { Process *c_p = ((ErtsProcExitContext *) vctxt)->c_p; Eterm reason = ((ErtsProcExitContext *) vctxt)->reason; @@ -12288,6 +12289,7 @@ erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt) erts_link_release_both(ldp); else if (lnk) erts_link_release(lnk); + return 1; } /* this function fishishes a process and propagates exit messages - called diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 43937f216c..cdc03cf940 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1820,8 +1820,8 @@ typedef struct { Process *c_p; Eterm reason; } ErtsProcExitContext; -void erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt); -void erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt); +int erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt, Sint reds); +int erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt, Sint reds); Eterm erts_get_process_priority(erts_aint32_t state); Eterm erts_set_process_priority(Process *p, Eterm prio); diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c index 10ea401022..46e460582c 100644 --- a/erts/emulator/beam/erl_process_dump.c +++ b/erts/emulator/beam/erl_process_dump.c @@ -100,16 +100,18 @@ erts_deep_process_dump(fmtfn_t to, void *to_arg) dump_binaries(to, to_arg, all_binaries); } -static void -monitor_size(ErtsMonitor *mon, void *vsize) +static int +monitor_size(ErtsMonitor *mon, void *vsize, Sint reds) { *((Uint *) vsize) += erts_monitor_size(mon); + return 1; } -static void -link_size(ErtsMonitor *lnk, void *vsize) +static int +link_size(ErtsMonitor *lnk, void *vsize, Sint reds) { *((Uint *) vsize) += erts_link_size(lnk); + return 1; } Uint erts_process_memory(Process *p, int include_sigs_in_transit) diff --git a/erts/emulator/beam/erl_rbtree.h b/erts/emulator/beam/erl_rbtree.h index e50abf5cec..ce401fa7e7 100644 --- a/erts/emulator/beam/erl_rbtree.h +++ b/erts/emulator/beam/erl_rbtree.h @@ -161,7 +161,7 @@ * * - void <ERTS_RBT_PREFIX>_rbt_foreach( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element. * Order is undefined. @@ -170,7 +170,7 @@ * * - void <ERTS_RBT_PREFIX>_rbt_foreach_destroy( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element. * Order is undefined. Each element should be destroyed @@ -180,39 +180,46 @@ * * - int <ERTS_RBT_PREFIX>_rbt_foreach_yielding( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element. * Order is undefined. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. The tree should not be - * modified until all of it has been processed. + * Yield when 'reds' reductions has been processed. The 'op' + * function return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op'. * * - int <ERTS_RBT_PREFIX>_rbt_foreach_destroy_yielding( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element. * Order is undefined. Each element should be destroyed * by 'op'. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. + * Yield when 'reds' reductions has been processed. The 'op' + * function return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op'. * * - void <ERTS_RBT_PREFIX>_rbt_foreach_small( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element from * smallest towards larger elements. @@ -221,7 +228,7 @@ * * - void <ERTS_RBT_PREFIX>_rbt_foreach_large( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element from * largest towards smaller elements. @@ -230,40 +237,46 @@ * * - int <ERTS_RBT_PREFIX>_rbt_foreach_small_yielding( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element from * smallest towards larger elements. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. The tree should not be - * modified until all of it has been processed. + * Yield when 'reds' reductions has been processed. The 'op' + * function return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op'. * * - int <ERTS_RBT_PREFIX>_rbt_foreach_large_yielding( * ERTS_RBT_T *tree, - * void (*op)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element from * largest towards smaller elements. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. The tree should not be - * modified until all of it has been processed. + * Yield when 'reds' reductions has been processed. The 'op' + * function return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op'. * * - void <ERTS_RBT_PREFIX>_rbt_foreach_small_destroy( * ERTS_RBT_T **tree, - * void (*op)(ERTS_RBT_T *, void *), - * void (*destr)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), + * int (*destr)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element from * smallest towards larger elements. @@ -277,8 +290,8 @@ * * - void <ERTS_RBT_PREFIX>_rbt_foreach_large_destroy( * ERTS_RBT_T **tree, - * void (*op)(ERTS_RBT_T *, void *), - * void (*destr)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), + * int (*destr)(ERTS_RBT_T *, void *), * void *arg); * Operate by calling the operator 'op' on each element from * largest towards smaller elements. @@ -292,11 +305,11 @@ * * - int <ERTS_RBT_PREFIX>_rbt_foreach_small_destroy_yielding( * ERTS_RBT_T **tree, - * void (*op)(ERTS_RBT_T *, void *), - * void (*destr)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), + * int (*destr)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element from * smallest towards larger elements. * @@ -305,20 +318,23 @@ * Note that elements are often destroyed in another order * than the order that the elements are operated on. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. The tree should not be - * modified until all of it has been processed. + * Yield when 'reds' reductions has been processed. The 'op' and + * 'destr' functions return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op' and 'destroy'. * * - int <ERTS_RBT_PREFIX>_rbt_foreach_large_destroy_yielding( * ERTS_RBT_T **tree, - * void (*op)(ERTS_RBT_T *, void *), - * void (*destr)(ERTS_RBT_T *, void *), + * int (*op)(ERTS_RBT_T *, void *), + * int (*destr)(ERTS_RBT_T *, void *), * void *arg, * <ERTS_RBT_PREFIX>_rbt_yield_state_t *ystate, - * Sint ylimit); + * Sint reds); * Operate by calling the operator 'op' on each element from * largest towards smaller elements. * @@ -327,10 +343,13 @@ * Note that elements are often destroyed in another order * than the order that the elements are operated on. * - * Yield when 'ylimit' elements has been processed. True is - * returned when yielding, and false is returned when - * the whole tree has been processed. The tree should not be - * modified until all of it has been processed. + * Yield when 'reds' reductions has been processed. The 'op' and + * 'destr' functions return the number of reductions that each element + * took to process. The number of reductions remaining is returned, + * meaning that if 0 is returned, there are more elements to be + * processed. If a value greater than 0 is returned the foreach has + * ended. The tree should not be modified until all of it has been + * processed. * * 'arg' is passed as argument to 'op' and 'destroy'. * @@ -447,17 +466,6 @@ # define ERTS_RBT_API_INLINE__ ERTS_INLINE #endif -#ifndef ERTS_RBT_YIELD_STAT_INITER -# define ERTS_RBT_YIELD_STAT_INITER {NULL, 0} -#endif -#ifndef ERTS_RBT_YIELD_STAT_INIT -# define ERTS_RBT_YIELD_STAT_INIT(YS) \ - do { \ - (YS)->x = NULL; \ - (YS)->up = 0; \ - } while (0) -#endif - #define ERTS_RBT_CONCAT_MACRO_VALUES___(X, Y) \ X ## Y #define ERTS_RBT_CONCAT_MACRO_VALUES__(X, Y) \ @@ -470,8 +478,38 @@ typedef struct { ERTS_RBT_T *x; int up; +#ifdef DEBUG + int debug_red_adj; +#endif } ERTS_RBT_YIELD_STATE_T__; +#define ERTS_RBT_CALLBACK_FOREACH_FUNC(NAME) int (*NAME)(ERTS_RBT_T *, void *, Sint) + +#ifndef ERTS_RBT_YIELD_STAT_INITER +# ifdef DEBUG +# define ERTS_RBT_YIELD_STAT_INITER {NULL, 0, CONTEXT_REDS} +# else +# define ERTS_RBT_YIELD_STAT_INITER {NULL, 0} +# endif +#endif +#ifndef ERTS_RBT_YIELD_STAT_INIT +# define ERTS_RBT_YIELD_STAT_INIT__(YS) \ + do { \ + (YS)->x = NULL; \ + (YS)->up = 0; \ + } while (0) +# ifdef DEBUG +# define ERTS_RBT_YIELD_STAT_INIT(YS) \ + do { \ + ERTS_RBT_YIELD_STAT_INIT__(YS); \ + (YS)->debug_red_adj = CONTEXT_REDS; \ + } while(0) +# else +# define ERTS_RBT_YIELD_STAT_INIT(YS) ERTS_RBT_YIELD_STAT_INIT__(YS) +# endif +#endif + + #define ERTS_RBT_FUNC__(Name) \ ERTS_RBT_CONCAT_MACRO_VALUES__(ERTS_RBT_PREFIX, _rbt_ ## Name) @@ -1302,11 +1340,11 @@ ERTS_RBT_FUNC__(largest)(ERTS_RBT_T *root) static ERTS_INLINE int ERTS_RBT_FUNC__(foreach_unordered__)(ERTS_RBT_T **root, int destroying, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg, - int yielding, + int yielding, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { ERTS_RBT_T *c, *p, *x; @@ -1314,13 +1352,17 @@ ERTS_RBT_FUNC__(foreach_unordered__)(ERTS_RBT_T **root, if (yielding && ystate->x) { x = ystate->x; +#ifdef DEBUG + if (ystate->debug_red_adj > 0) + ystate->debug_red_adj -= 100; +#endif ERTS_RBT_ASSERT(ystate->up); goto restart_up; } else { x = *root; if (!x) - return 0; + return reds; if (destroying) *root = NULL; } @@ -1346,10 +1388,10 @@ ERTS_RBT_FUNC__(foreach_unordered__)(ERTS_RBT_T **root, #ifdef ERTS_RBT_DEBUG int cdir; #endif - if (yielding && ylimit-- <= 0) { + if (yielding && reds <= 0) { ystate->x = x; ystate->up = 1; - return 1; + return 0; } restart_up: @@ -1375,14 +1417,20 @@ ERTS_RBT_FUNC__(foreach_unordered__)(ERTS_RBT_T **root, } #endif - (*op)(x, arg); + reds -= (*op)(x, arg, reds); +#ifdef DEBUG + if (yielding) + reds -= ystate->debug_red_adj; +#endif if (!p) { + /* Done */ if (yielding) { ystate->x = NULL; ystate->up = 0; + return reds <= 0 ? 1 : reds; } - return 0; /* Done */ + return 1; } c = ERTS_RBT_GET_RIGHT(p); @@ -1407,20 +1455,26 @@ static ERTS_INLINE int ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, int from_small, int destroying, - void (*op)(ERTS_RBT_T *, void *), - void (*destroy)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), + ERTS_RBT_CALLBACK_FOREACH_FUNC(destroy), void *arg, - int yielding, + int yielding, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { ERTS_RBT_T *c, *p, *x; ERTS_RBT_ASSERT(!yielding || ystate); ERTS_RBT_ASSERT(!destroying || destroy); + ERTS_RBT_ASSERT(!yielding || yop); + ERTS_RBT_ASSERT(yielding || op); if (yielding && ystate->x) { x = ystate->x; +#ifdef DEBUG + if (ystate->debug_red_adj > 0) + ystate->debug_red_adj -= 100; +#endif if (ystate->up) goto restart_up; else @@ -1429,7 +1483,7 @@ ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, else { x = *root; if (!x) - return 0; + return reds; if (destroying) *root = NULL; } @@ -1445,12 +1499,16 @@ ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, x = c; } - (*op)(x, arg); + reds -= (*op)(x, arg, reds); +#ifdef DEBUG + if (yielding) + reds -= ystate->debug_red_adj; +#endif - if (yielding && --ylimit <= 0) { + if (yielding && reds <= 0) { ystate->x = x; ystate->up = 0; - return 1; + return 0; } restart_down: @@ -1472,12 +1530,16 @@ ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, ? ERTS_RBT_GET_LEFT(p) : ERTS_RBT_GET_RIGHT(p)) == x); - (*op)(p, arg); + reds -= (*op)(p, arg, reds); +#ifdef DEBUG + if (yielding) + reds -= ystate->debug_red_adj; +#endif - if (yielding && --ylimit <= 0) { + if (yielding && reds <= 0) { ystate->x = x; ystate->up = 1; - return 1; + return 0; restart_up: p = ERTS_RBT_GET_PARENT(x); } @@ -1510,15 +1572,20 @@ ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, } #endif - (*destroy)(x, arg); + reds -= (*destroy)(x, arg, reds); +#ifdef DEBUG + if (yielding) + reds -= ystate->debug_red_adj; +#endif } if (!p) { if (yielding) { ystate->x = NULL; ystate->up = 0; + return reds <= 0 ? 1 : reds; } - return 0; /* Done */ + return 1; /* Done */ } x = p; } @@ -1531,7 +1598,7 @@ ERTS_RBT_FUNC__(foreach_ordered__)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg) { (void) ERTS_RBT_FUNC__(foreach_unordered__)(&root, 0, op, arg, @@ -1544,7 +1611,7 @@ ERTS_RBT_FUNC__(foreach)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach_small)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg) { (void) ERTS_RBT_FUNC__(foreach_ordered__)(&root, 1, 0, @@ -1558,7 +1625,7 @@ ERTS_RBT_FUNC__(foreach_small)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach_large)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg) { (void) ERTS_RBT_FUNC__(foreach_ordered__)(&root, 0, 0, @@ -1572,13 +1639,13 @@ ERTS_RBT_FUNC__(foreach_large)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_yielding)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_unordered__)(&root, 0, op, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_YIELDING */ @@ -1587,14 +1654,14 @@ ERTS_RBT_FUNC__(foreach_yielding)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_small_yielding)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_ordered__)(&root, 1, 0, op, NULL, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_SMALL_YIELDING */ @@ -1603,14 +1670,14 @@ ERTS_RBT_FUNC__(foreach_small_yielding)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_large_yielding)(ERTS_RBT_T *root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_ordered__)(&root, 0, 0, op, NULL, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_LARGE_YIELDING */ @@ -1619,11 +1686,11 @@ ERTS_RBT_FUNC__(foreach_large_yielding)(ERTS_RBT_T *root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach_destroy)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg) { (void) ERTS_RBT_FUNC__(foreach_unordered__)(root, 1, op, arg, - 0, NULL, 0); + 0, NULL, 0); } #endif /* ERTS_RBT_WANT_FOREACH_DESTROY */ @@ -1632,8 +1699,8 @@ ERTS_RBT_FUNC__(foreach_destroy)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach_small_destroy)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), - void (*destr)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), + ERTS_RBT_CALLBACK_FOREACH_FUNC(destr), void *arg) { (void) ERTS_RBT_FUNC__(foreach_ordered__)(root, 1, 1, @@ -1647,8 +1714,8 @@ ERTS_RBT_FUNC__(foreach_small_destroy)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ void ERTS_RBT_FUNC__(foreach_large_destroy)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), - void (*destr)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), + ERTS_RBT_CALLBACK_FOREACH_FUNC(destr), void *arg) { (void) ERTS_RBT_FUNC__(foreach_ordered__)(root, 0, 1, @@ -1662,13 +1729,13 @@ ERTS_RBT_FUNC__(foreach_large_destroy)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_destroy_yielding)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_unordered__)(root, 1, op, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_DESTROY_YIELDING */ @@ -1677,15 +1744,15 @@ ERTS_RBT_FUNC__(foreach_destroy_yielding)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_small_destroy_yielding)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), - void (*destr)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), + ERTS_RBT_CALLBACK_FOREACH_FUNC(destr), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_ordered__)(root, 1, 1, op, destr, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_SMALL_DESTROY_YIELDING */ @@ -1694,15 +1761,15 @@ ERTS_RBT_FUNC__(foreach_small_destroy_yielding)(ERTS_RBT_T **root, static ERTS_RBT_API_INLINE__ int ERTS_RBT_FUNC__(foreach_large_destroy_yielding)(ERTS_RBT_T **root, - void (*op)(ERTS_RBT_T *, void *), - void (*destr)(ERTS_RBT_T *, void *), + ERTS_RBT_CALLBACK_FOREACH_FUNC(op), + ERTS_RBT_CALLBACK_FOREACH_FUNC(destr), void *arg, ERTS_RBT_YIELD_STATE_T__ *ystate, - Sint ylimit) + Sint reds) { return ERTS_RBT_FUNC__(foreach_ordered__)(root, 0, 1, op, destr, arg, - 1, ystate, ylimit); + 1, ystate, reds); } #endif /* ERTS_RBT_WANT_FOREACH_LARGE_DESTROY_YIELDING */ @@ -1855,6 +1922,7 @@ ERTS_RBT_FUNC__(hdbg_check_tree)(ERTS_RBT_T *root, ERTS_RBT_T *n) #ifdef ERTS_RBT_UNDEF # undef ERTS_RBT_PREFIX # undef ERTS_RBT_T +# undef ERTS_RBT_CALLBACK_FOREACH_FUNC # undef ERTS_RBT_KEY_T # undef ERTS_RBT_FLAGS_T # undef ERTS_RBT_INIT_EMPTY_TNODE diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c index 29c698e34f..d26ea19494 100644 --- a/erts/emulator/beam/erl_time_sup.c +++ b/erts/emulator/beam/erl_time_sup.c @@ -1911,8 +1911,8 @@ typedef struct { ErtsTimeOffsetMonitorInfo *to_mon_info; } ErtsTimeOffsetMonitorContext; -static void -save_time_offset_monitor(ErtsMonitor *mon, void *vcntxt) +static int +save_time_offset_monitor(ErtsMonitor *mon, void *vcntxt, Sint reds) { ErtsTimeOffsetMonitorContext *cntxt; ErtsMonitorData *mdp = erts_monitor_to_data(mon); @@ -1935,7 +1935,7 @@ save_time_offset_monitor(ErtsMonitor *mon, void *vcntxt) cntxt->to_mon_info[mix].ref = make_internal_ref(&cntxt->to_mon_info[mix].heap[0]); - + return 1; } static void diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 7322239a73..6a2be52e11 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -3644,20 +3644,22 @@ typedef struct { Eterm reason; } ErtsPortExitContext; -static void link_port_exit(ErtsLink *lnk, void *vpectxt) +static int link_port_exit(ErtsLink *lnk, void *vpectxt, Sint reds) { ErtsPortExitContext *pectxt = vpectxt; erts_proc_sig_send_link_exit(NULL, pectxt->port_id, lnk, pectxt->reason, NIL); + return 1; } -static void monitor_port_exit(ErtsMonitor *mon, void *vpectxt) +static int monitor_port_exit(ErtsMonitor *mon, void *vpectxt, Sint reds) { ErtsPortExitContext *pectxt = vpectxt; if (erts_monitor_is_target(mon)) erts_proc_sig_send_monitor_down(mon, pectxt->reason); else erts_proc_sig_send_demonitor(mon); + return 1; } /* 'from' is sending 'this_port' an exit signal, (this_port must be internal). @@ -4836,7 +4838,7 @@ typedef struct { void *arg; } prt_one_lnk_data; -static void prt_one_monitor(ErtsMonitor *mon, void *vprtd) +static int prt_one_monitor(ErtsMonitor *mon, void *vprtd, Sint reds) { ErtsMonitorData *mdp = erts_monitor_to_data(mon); prt_one_lnk_data *prtd = (prt_one_lnk_data *) vprtd; @@ -4844,12 +4846,14 @@ static void prt_one_monitor(ErtsMonitor *mon, void *vprtd) erts_print(prtd->to, prtd->arg, "(%p,%T)", mon->other.ptr, mdp->ref); else erts_print(prtd->to, prtd->arg, "(%T,%T)", mon->other.item, mdp->ref); + return 1; } -static void prt_one_lnk(ErtsLink *lnk, void *vprtd) +static int prt_one_lnk(ErtsLink *lnk, void *vprtd, Sint reds) { prt_one_lnk_data *prtd = (prt_one_lnk_data *) vprtd; erts_print(prtd->to, prtd->arg, "%T", lnk->other.item); + return 1; } static void dump_port_state(fmtfn_t to, void *arg, erts_aint32_t state) |