📄 erl_node_tables.c
字号:
ProcBin *pb; struct insert_offheap2_arg a; a.type = BIN_REF; for(pb = oh->mso; pb; pb = pb->next) { if(pb->val->flags & BIN_FLAG_MATCH_PROG) { InsertedBin *ib; int insert_bin = 1; for (ib = inserted_bins; ib; ib = ib->next) if(ib->bin_val == pb->val) { insert_bin = 0; break; } if (insert_bin) { Uint id_heap[BIG_UINT_HEAP_SIZE]; Uint *hp = &id_heap[0]; InsertedBin *nib; a.id = erts_bld_uint(&hp, NULL, (Uint) pb->val); erts_match_prog_foreach_offheap(pb->val, insert_offheap2, (void *) &a); nib = erts_alloc(ERTS_ALC_T_NC_TMP, sizeof(InsertedBin)); nib->bin_val = pb->val; nib->next = inserted_bins; inserted_bins = nib; } } } }#if 0 if(oh->funs) { /* No need to */ }#endif}static void doit_insert_monitor(ErtsMonitor *monitor, void *p){ Eterm *idp = p; if(is_external(monitor->pid)) insert_node(external_thing_ptr(monitor->pid)->node, MONITOR_REF, *idp); if(is_external(monitor->ref)) insert_node(external_thing_ptr(monitor->ref)->node, MONITOR_REF, *idp);}static void doit_insert_link(ErtsLink *lnk, void *p){ Eterm *idp = p; if(is_external(lnk->pid)) insert_node(external_thing_ptr(lnk->pid)->node, LINK_REF, *idp);}static voidinsert_monitors(ErtsMonitor *monitors, Eterm id){ erts_doforall_monitors(monitors,&doit_insert_monitor,&id);}static voidinsert_links(ErtsLink *lnk, Eterm id){ erts_doforall_links(lnk,&doit_insert_link,&id);}static void doit_insert_link2(ErtsLink *lnk, void *p){ Eterm *idp = p; if(is_external(lnk->pid)) insert_node(external_thing_ptr(lnk->pid)->node, LINK_REF, *idp); insert_links(lnk->root, *idp);}static voidinsert_links2(ErtsLink *lnk, Eterm id){ erts_doforall_links(lnk,&doit_insert_link2,&id);}static voidinsert_ets_table(DbTable *tab, void *unused){ struct insert_offheap2_arg a; a.type = ETS_REF; a.id = tab->common.id; erts_db_foreach_offheap(tab, insert_offheap2, (void *) &a);}static voidinsert_bif_timer(Eterm receiver, Eterm msg, ErlHeapFragment *bp, void *arg){ if (bp) { Eterm heap[3]; insert_offheap(&bp->off_heap, TIMER_REF, (is_internal_pid(receiver) ? receiver : TUPLE2(&heap[0], AM_process, receiver))); }}static voidinit_referred_node(void *node, void *unused){ referred_nodes[no_referred_nodes].node = (ErlNode *) node; referred_nodes[no_referred_nodes].referrers = NULL; no_referred_nodes++;}static voidinit_referred_dist(void *dist, void *unused){ referred_dists[no_referred_dists].dist = (DistEntry *) dist; referred_dists[no_referred_dists].referrers = NULL; no_referred_dists++;}#ifdef ERTS_SMPstatic voidinsert_sys_msg(Eterm from, Eterm to, Eterm msg, ErlHeapFragment *bp){ insert_offheap(&bp->off_heap, HEAP_REF, to);}#endifstatic voidsetup_reference_table(void){ ErlHeapFragment *hfp; DistEntry *dep; HashInfo hi; int i; Eterm heap[3]; inserted_bins = NULL; hash_get_info(&hi, &erts_node_table); referred_nodes = erts_alloc(ERTS_ALC_T_NC_TMP, hi.objs*sizeof(ReferredNode)); no_referred_nodes = 0; hash_foreach(&erts_node_table, init_referred_node, NULL); ASSERT(no_referred_nodes == hi.objs); hash_get_info(&hi, &erts_dist_table); referred_dists = erts_alloc(ERTS_ALC_T_NC_TMP, hi.objs*sizeof(ReferredDist)); no_referred_dists = 0; hash_foreach(&erts_dist_table, init_referred_dist, NULL); ASSERT(no_referred_dists == hi.objs); /* Go through the hole system, and build a table of all references to ErlNode and DistEntry structures */ insert_node(erts_this_node, SYSTEM_REF, TUPLE2(&heap[0], AM_system, am_undefined));#ifdef HYBRID /* Insert Heap */ insert_offheap(&erts_global_offheap, HEAP_REF, TUPLE2(&heap[0], AM_processes, am_undefined));#endif /* Insert all processes */ for (i = 0; i < erts_max_processes; i++) if (process_tab[i]) { /* Insert Heap */ insert_offheap(&(process_tab[i]->off_heap), HEAP_REF, process_tab[i]->id); /* Insert message buffers */ for(hfp = process_tab[i]->mbuf; hfp; hfp = hfp->next) insert_offheap(&(hfp->off_heap), HEAP_REF, process_tab[i]->id);#ifdef ERTS_SMP /* Insert msg msg buffers */ { ErlMessage *msg; for (msg = process_tab[i]->msg.first; msg; msg = msg->next) if (msg->bp) insert_offheap(&(msg->bp->off_heap), HEAP_REF, process_tab[i]->id); for (msg = process_tab[i]->msg_inq.first; msg; msg = msg->next) if (msg->bp) insert_offheap(&(msg->bp->off_heap), HEAP_REF, process_tab[i]->id); }#endif /* Insert links */ if(process_tab[i]->nlinks) insert_links(process_tab[i]->nlinks, process_tab[i]->id); if(process_tab[i]->monitors) insert_monitors(process_tab[i]->monitors, process_tab[i]->id); /* Insert controller */ if (process_tab[i]->dist_entry) insert_dist_entry(process_tab[i]->dist_entry, CTRL_REF, process_tab[i]->id, 0); } #ifdef ERTS_SMP erts_foreach_sys_msg_in_q(insert_sys_msg);#endif /* Insert all ports */ for (i = 0; i < erts_max_ports; i++) { if (erts_port[i].status & ERTS_PORT_SFLGS_DEAD) continue; /* Insert links */ if(erts_port[i].nlinks) insert_links(erts_port[i].nlinks, erts_port[i].id); /* Insert port data */ for(hfp = erts_port[i].bp; hfp; hfp = hfp->next) insert_offheap(&(hfp->off_heap), HEAP_REF, erts_port[i].id); /* Insert controller */ if (erts_port[i].dist_entry) insert_dist_entry(erts_port[i].dist_entry, CTRL_REF, erts_port[i].id, 0); } { /* Add binaries stored elsewhere ... */ ErlOffHeap oh; ProcBin pb[2] = {{0},{0}}; ProcBin *mso = NULL; int i = 0; Binary *default_match_spec; Binary *default_meta_match_spec; /* Only the ProcBin members val and next will be inspected (by insert_offheap()) */#undef ADD_BINARY#define ADD_BINARY(Bin) \ if ((Bin)) { \ pb[i].val = (Bin); \ pb[i].next = mso; \ mso = &pb[i]; \ i++; \ } erts_get_default_trace_pattern(NULL, &default_match_spec, &default_meta_match_spec, NULL, NULL); ADD_BINARY(default_match_spec); ADD_BINARY(default_meta_match_spec); oh.mso = mso; oh.externals = NULL;#ifndef HYBRID /* FIND ME! */ oh.funs = NULL;#endif insert_offheap(&oh, BIN_REF, AM_match_spec);#undef ADD_BINARY } /* Insert all dist links */ for(dep = erts_visible_dist_entries; dep; dep = dep->next) { if(dep->nlinks) insert_links2(dep->nlinks, dep->sysname); if(dep->node_links) insert_links(dep->node_links, dep->sysname); if(dep->monitors) insert_monitors(dep->monitors, dep->sysname); } for(dep = erts_hidden_dist_entries; dep; dep = dep->next) { if(dep->nlinks) insert_links2(dep->nlinks, dep->sysname); if(dep->node_links) insert_links(dep->node_links, dep->sysname); if(dep->monitors) insert_monitors(dep->monitors, dep->sysname); } /* Not connected dist entries should not have any links, but inspect them anyway */ for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) { if(dep->nlinks) insert_links2(dep->nlinks, dep->sysname); if(dep->node_links) insert_links(dep->node_links, dep->sysname); if(dep->monitors) insert_monitors(dep->monitors, dep->sysname); } /* Insert all ets tables */ erts_db_foreach_table(insert_ets_table, NULL); /* Insert all bif timers */ erts_bif_timer_foreach(insert_bif_timer, NULL); /* Insert node table (references to dist) */ hash_foreach(&erts_node_table, insert_erl_node, NULL);}/* Returns an erlang term on this format: {{node_references, [{{Node, Creation}, Refc, [{{ReferrerType, ID}, [{ReferenceType,References}, '...']}, '...']}, '...']}, {dist_references, [{Node, Refc, [{{ReferrerType, ID}, [{ReferenceType,References}, '...']}, '...']}, '...']}} */static Etermreference_table_term(Uint **hpp, Uint *szp){#undef MK_2TUP#undef MK_3TUP#undef MK_CONS#undef MK_UINT#define MK_2TUP(E1, E2) erts_bld_tuple(hpp, szp, 2, (E1), (E2))#define MK_3TUP(E1, E2, E3) erts_bld_tuple(hpp, szp, 3, (E1), (E2), (E3))#define MK_CONS(CAR, CDR) erts_bld_cons(hpp, szp, (CAR), (CDR))#define MK_UINT(UI) erts_bld_uint(hpp, szp, (UI)) int i; Eterm tup; Eterm tup2; Eterm nl = NIL; Eterm dl = NIL; Eterm nrid; for(i = 0; i < no_referred_nodes; i++) { NodeReferrer *nrp; Eterm nril = NIL; for(nrp = referred_nodes[i].referrers; nrp; nrp = nrp->next) { Eterm nrl = NIL; /* NodeReferenceList = [{ReferenceType,References}] */ if(nrp->heap_ref) { tup = MK_2TUP(AM_heap, MK_UINT(nrp->heap_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->link_ref) { tup = MK_2TUP(AM_link, MK_UINT(nrp->link_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->monitor_ref) { tup = MK_2TUP(AM_monitor, MK_UINT(nrp->monitor_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->ets_ref) { tup = MK_2TUP(AM_ets, MK_UINT(nrp->ets_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->bin_ref) { tup = MK_2TUP(AM_binary, MK_UINT(nrp->bin_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->timer_ref) { tup = MK_2TUP(AM_timer, MK_UINT(nrp->timer_ref)); nrl = MK_CONS(tup, nrl); } if(nrp->system_ref) { tup = MK_2TUP(AM_system, MK_UINT(nrp->system_ref)); nrl = MK_CONS(tup, nrl); } nrid = nrp->id; if (!IS_CONST(nrp->id)) { Uint nrid_sz = size_object(nrp->id); if (szp) *szp += nrid_sz; if (hpp) nrid = copy_struct(nrp->id, nrid_sz, hpp, NULL); } if (is_internal_pid(nrid) || nrid == am_error_logger) { ASSERT(!nrp->ets_ref && !nrp->bin_ref && !nrp->system_ref); tup = MK_2TUP(AM_process, nrid); } else if (is_tuple(nrid)) { Eterm *t; ASSERT(!nrp->ets_ref && !nrp->bin_ref); t = tuple_val(nrid); ASSERT(2 == arityval(t[0])); tup = MK_2TUP(t[1], t[2]); } else if(is_internal_port(nrid)) { ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->bin_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_port, nrid); } else if(nrp->ets_ref) { ASSERT(!nrp->heap_ref && !nrp->link_ref && !nrp->monitor_ref && !nrp->bin_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_ets, nrid); } else if(nrp->bin_ref) { ASSERT(is_small(nrid) || is_big(nrid)); ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->link_ref && !nrp->monitor_ref && !nrp->timer_ref && !nrp->system_ref); tup = MK_2TUP(AM_match_spec, nrid); } else { ASSERT(!nrp->heap_ref && !nrp->ets_ref && !nrp->bin_ref); ASSERT(is_atom(nrid)); tup = MK_2TUP(AM_dist, nrid); } tup = MK_2TUP(tup, nrl); /* NodeReferenceIdList = [{{ReferrerType, ID}, NodeReferenceList}] */ nril = MK_CONS(tup, nril); } /* NodeList = [{{Node, Creation}, Refc, NodeReferenceIdList}] */ tup = MK_2TUP(referred_nodes[i].node->sysname, MK_UINT(referred_nodes[i].node->creation)); tup = MK_3TUP(tup, MK_UINT(erts_refc_read(&referred_nodes[i].node->refc, 1)), nril); nl = MK_CONS(tup, nl); } for(i = 0; i < no_referred_dists; i++) { DistReferrer *drp; Eterm dril = NIL; for(drp = referred_dists[i].referrers; drp; drp = drp->next) { Eterm drl = NIL; /* DistReferenceList = [{ReferenceType,References}] */ if(drp->node_ref) { tup = MK_2TUP(AM_node, MK_UINT(drp->node_ref)); drl = MK_CONS(tup, drl); } if(drp->ctrl_ref) { tup = MK_2TUP(AM_control, MK_UINT(drp->ctrl_ref)); drl = MK_CONS(tup, drl); } if (is_internal_pid(drp->id)) { ASSERT(drp->ctrl_ref && !drp->node_ref); tup = MK_2TUP(AM_process, drp->id); } else if(is_internal_port(drp->id)) { ASSERT(drp->ctrl_ref && !drp->node_ref); tup = MK_2TUP(AM_port, drp->id); } else { ASSERT(!drp->ctrl_ref && drp->node_ref); ASSERT(is_atom(drp->id)); tup = MK_2TUP(drp->id, MK_UINT(drp->creation)); tup = MK_2TUP(AM_node, tup); } tup = MK_2TUP(tup, drl); /* DistReferenceIdList = [{{ReferrerType, ID}, DistReferenceList}] */ dril = MK_CONS(tup, dril); } /* DistList = [{Dist, Refc, ReferenceIdList}] */ tup = MK_3TUP(referred_dists[i].dist->sysname, MK_UINT(erts_refc_read(&referred_dists[i].dist->refc, 1)), dril); dl = MK_CONS(tup, dl); } /* {{node_references, NodeList}, {dist_references, DistList}} */ tup = MK_2TUP(AM_node_references, nl); tup2 = MK_2TUP(AM_dist_references, dl); tup = MK_2TUP(tup, tup2); return tup;#undef MK_2TUP#undef MK_3TUP#undef MK_CONS#undef MK_UINT}static voiddelete_reference_table(void){ Uint i; for(i = 0; i < no_referred_nodes; i++) { NodeReferrer *nrp; NodeReferrer *tnrp; nrp = referred_nodes[i].referrers; while(nrp) { tnrp = nrp; nrp = nrp->next; erts_free(ERTS_ALC_T_NC_TMP, (void *) tnrp); } } if (referred_nodes) erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_nodes); for(i = 0; i < no_referred_dists; i++) { DistReferrer *drp; DistReferrer *tdrp; drp = referred_dists[i].referrers; while(drp) { tdrp = drp; drp = drp->next; erts_free(ERTS_ALC_T_NC_TMP, (void *) tdrp); } } if (referred_dists) erts_free(ERTS_ALC_T_NC_TMP, (void *) referred_dists); while(inserted_bins) { InsertedBin *ib = inserted_bins; inserted_bins = inserted_bins->next; erts_free(ERTS_ALC_T_NC_TMP, (void *)ib); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -