⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_node_tables.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif    res = hash_table_sz(&erts_node_table) + node_entries*sizeof(ErlNode);    if (lock)	erts_smp_mtx_unlock(&erts_node_table_mtx);    return res;}voiderts_node_table_info(int to, void *to_arg){    int lock = !ERTS_IS_CRASH_DUMPING;    if (lock)	erts_smp_mtx_lock(&erts_node_table_mtx);    hash_info(to, to_arg, &erts_node_table);    if (lock)	erts_smp_mtx_unlock(&erts_node_table_mtx);}ErlNode *erts_find_or_insert_node(Eterm sysname, Uint creation){    ErlNode *res;    ErlNode ne;    ne.sysname = sysname;    ne.creation = creation;    erts_smp_mtx_lock(&erts_node_table_mtx);    res = hash_put(&erts_node_table, (void *) &ne);    ASSERT(res);    if (res != erts_this_node) {	long refc = erts_refc_inctest(&res->refc, 0);	if (refc < 2) /* New or pending delete */	    erts_refc_inc(&res->refc, 1);    }    erts_smp_mtx_unlock(&erts_node_table_mtx);    return res;}void erts_delete_node(ErlNode *enp){    ASSERT(enp != erts_this_node);    if(enp != erts_this_node) {	erts_smp_mtx_lock(&erts_node_table_mtx);	/*	 * Another thread might have looked up this node after we	 * decided to delete it (refc became zero). If so, the other	 * thread incremented refc twice. Once for the new reference	 * and once for this thread. Therefore, delete node if refc	 * is 0 or -1 after a decrement.	 */	if (erts_refc_dectest(&enp->refc, -1) <= 0)	    (void) hash_erase(&erts_node_table, (void *) enp);	erts_smp_mtx_unlock(&erts_node_table_mtx);    }}struct pn_data {    int to;    void *to_arg;    Eterm sysname;    int no_sysname;    int no_total;};static void print_node(void *venp, void *vpndp){    struct pn_data *pndp = ((struct pn_data *) vpndp);    ErlNode *enp = ((ErlNode *) venp);    if(pndp->sysname == NIL       || enp->sysname == pndp->sysname) {	if (pndp->no_sysname == 0) {	    erts_print(pndp->to, pndp->to_arg, "Creation:");	}	if(pndp->sysname == NIL) {	    erts_print(pndp->to, pndp->to_arg, "Name: %T ", enp->sysname);	}	erts_print(pndp->to, pndp->to_arg, " %d", enp->creation);#ifdef DEBUG	erts_print(pndp->to, pndp->to_arg, " (refc=%ld)",		   erts_refc_read(&enp->refc, 1));#endif	pndp->no_sysname++;    }    pndp->no_total++;}void erts_print_node_info(int to,			  void *to_arg,			  Eterm sysname,			  int *no_sysname,			  int *no_total){    int lock = !ERTS_IS_CRASH_DUMPING;    struct pn_data pnd;    pnd.to = to;    pnd.to_arg = to_arg;    pnd.sysname = sysname;    pnd.no_sysname = 0;    pnd.no_total = 0;    if (lock)	erts_smp_mtx_lock(&erts_node_table_mtx);    hash_foreach(&erts_node_table, print_node, (void *) &pnd);    if (pnd.no_sysname != 0) {	erts_print(to, to_arg, "\n");    }    if (lock)	erts_smp_mtx_unlock(&erts_node_table_mtx);    if(no_sysname)	*no_sysname = pnd.no_sysname;    if(no_total)	*no_total = pnd.no_total;}/* ----------------------------------------------------------------------- */voiderts_set_this_node(Eterm sysname, Uint creation){    erts_smp_mtx_lock(&erts_node_table_mtx);    erts_smp_mtx_lock(&erts_dist_table_mtx);    (void) hash_erase(&erts_dist_table, (void *) erts_this_dist_entry);    erts_this_dist_entry->sysname = sysname;    erts_this_dist_entry->creation = creation;    (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);    (void) hash_erase(&erts_node_table, (void *) erts_this_node);    erts_this_node->sysname = sysname;    erts_this_node->creation = creation;    (void) hash_put(&erts_node_table, (void *) erts_this_node);    erts_smp_mtx_unlock(&erts_dist_table_mtx);    erts_smp_mtx_unlock(&erts_node_table_mtx);}void erts_init_node_tables(void){    HashFunctions f;    f.hash  = (H_FUN)			dist_table_hash;    f.cmp   = (HCMP_FUN)		dist_table_cmp;    f.alloc = (HALLOC_FUN)		dist_table_alloc;    f.free  = (HFREE_FUN)		dist_table_free;    erts_this_dist_entry = erts_alloc(ERTS_ALC_T_DIST_ENTRY, sizeof(DistEntry));    dist_entries = 1;    hash_init(ERTS_ALC_T_DIST_TABLE, &erts_dist_table, "dist_table", 11, f);    erts_hidden_dist_entries			= NULL;    erts_visible_dist_entries			= NULL;    erts_not_connected_dist_entries		= NULL;    erts_no_of_hidden_dist_entries		= 0;    erts_no_of_visible_dist_entries		= 0;    erts_no_of_not_connected_dist_entries	= 0;    erts_this_dist_entry->next			= NULL;    erts_this_dist_entry->prev			= NULL;    erts_refc_init(&erts_this_dist_entry->refc, 1); /* erts_this_node */    erts_this_dist_entry->sysname		= am_Noname;    erts_this_dist_entry->cid			= NIL;    erts_this_dist_entry->node_links		= NULL;    erts_this_dist_entry->nlinks		= NULL;    erts_this_dist_entry->monitors		= NULL;    erts_this_dist_entry->status		= 0;    erts_this_dist_entry->flags			= 0;    erts_this_dist_entry->cache			= NULL;    erts_this_dist_entry->version		= 0;    (void) hash_put(&erts_dist_table, (void *) erts_this_dist_entry);    f.hash  = (H_FUN)      			node_table_hash;    f.cmp   = (HCMP_FUN)   			node_table_cmp;    f.alloc = (HALLOC_FUN) 			node_table_alloc;    f.free  = (HFREE_FUN)  			node_table_free;    hash_init(ERTS_ALC_T_NODE_TABLE, &erts_node_table, "node_table", 11, f);    erts_this_node = erts_alloc(ERTS_ALC_T_NODE_ENTRY, sizeof(ErlNode));    node_entries = 1;    erts_refc_init(&erts_this_node->refc, 1); /* The system itself */    erts_this_node->sysname			= am_Noname;    erts_this_node->creation			= 0;    erts_this_node->dist_entry			= erts_this_dist_entry;    (void) hash_put(&erts_node_table, (void *) erts_this_node);#ifdef ERTS_SMP    {	int i;	for (i = 0; i < ERTS_NO_OF_DIST_ENTRY_MUTEXES; i++)	    erts_smp_mtx_init(&dist_entry_mutexes[i], "dist_entry");	erts_this_dist_entry->mtxp = &dist_entry_mutexes[0];	erts_smp_mtx_init(&erts_node_table_mtx, "node_table");	erts_smp_mtx_init(&erts_dist_table_mtx, "dist_table");    }#endif    references_atoms_need_init = 1;}#ifdef ERTS_SMPvoiderts_lock_node_tables_and_entries(void){    int i;    for (i = 0; i < ERTS_NO_OF_DIST_ENTRY_MUTEXES; i++)	erts_smp_mtx_lock(&dist_entry_mutexes[i]);    erts_smp_mtx_lock(&erts_node_table_mtx);    erts_smp_mtx_lock(&erts_dist_table_mtx);}voiderts_unlock_node_tables_and_entries(void){    int i;    erts_smp_mtx_unlock(&erts_dist_table_mtx);    erts_smp_mtx_unlock(&erts_node_table_mtx);    for (i = ERTS_NO_OF_DIST_ENTRY_MUTEXES-1; i >= 0; i--)	erts_smp_mtx_unlock(&dist_entry_mutexes[i]);}#ifdef ERTS_ENABLE_LOCK_CHECKint erts_lc_is_dist_entry_locked(DistEntry *dep){    return erts_smp_lc_mtx_is_locked(dep->mtxp);}#endif#endif/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * The following is only supposed to be used for testing, and debugging.     * *                                                                           * * erts_get_node_and_dist_references() returns a table of all references to  * * all entries in the node and dist tables. The hole system will be searched * * at once. This will give a consistent view over the references, but can    * * can damage the real-time properties of the system.                        *\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "erl_db.h"#undef  INIT_AM#define INIT_AM(S) AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)static Eterm AM_heap;static Eterm AM_link;static Eterm AM_monitor;static Eterm AM_process;static Eterm AM_port;static Eterm AM_ets;static Eterm AM_binary;static Eterm AM_match_spec;static Eterm AM_control;static Eterm AM_dist;static Eterm AM_node;static Eterm AM_dist_references;static Eterm AM_node_references;static Eterm AM_system;static Eterm AM_timer;#ifdef HYBRIDstatic Eterm AM_processes;#endifstatic void setup_reference_table(void);static Eterm reference_table_term(Uint **hpp, Uint *szp);static void delete_reference_table(void);#if BIG_UINT_HEAP_SIZE > 3 /* 2-tuple */#define ID_HEAP_SIZE BIG_UINT_HEAP_SIZE#else#define ID_HEAP_SIZE 3 /* 2-tuple */#endiftypedef struct node_referrer_ {    struct node_referrer_ *next;    int heap_ref;    int link_ref;    int monitor_ref;    int ets_ref;    int bin_ref;    int timer_ref;    int system_ref;    Eterm id;    Uint id_heap[ID_HEAP_SIZE];} NodeReferrer;typedef struct {    ErlNode *node;    NodeReferrer *referrers;} ReferredNode;typedef struct dist_referrer_ {    struct dist_referrer_ *next;    int node_ref;    int ctrl_ref;    Eterm id;    Uint creation;} DistReferrer;typedef struct {    DistEntry *dist;    DistReferrer *referrers;} ReferredDist;typedef struct inserted_bin_ {    struct inserted_bin_ *next;    Binary *bin_val;} InsertedBin;static ReferredNode *referred_nodes;static int no_referred_nodes;static ReferredDist *referred_dists;static int no_referred_dists;static InsertedBin *inserted_bins;Etermerts_get_node_and_dist_references(struct process *proc){    Uint *hp;    Uint size;    Eterm res;#ifdef DEBUG    Uint *endp;#endif    erts_smp_proc_unlock(proc, ERTS_PROC_LOCK_MAIN);    erts_smp_block_system(0);    /* No need to lock any thing since we are alone... */    if (references_atoms_need_init) {	INIT_AM(heap);	INIT_AM(link);	INIT_AM(monitor);	INIT_AM(process);	INIT_AM(port);	INIT_AM(ets);	INIT_AM(binary);	INIT_AM(match_spec);	INIT_AM(control);	INIT_AM(dist);	INIT_AM(node);	INIT_AM(dist_references);	INIT_AM(node_references);	INIT_AM(timer);	INIT_AM(system);#ifdef HYBRID	INIT_AM(processes);#endif	references_atoms_need_init = 0;    }    setup_reference_table();    /* Get term size */    size = 0;    (void) reference_table_term(NULL, &size);    hp = HAlloc(proc, size);#ifdef DEBUG    ASSERT(size > 0);    endp = hp + size;#endif    /* Write term */    res = reference_table_term(&hp, NULL);    ASSERT(endp == hp);    delete_reference_table();    erts_smp_release_system();    erts_smp_proc_lock(proc, ERTS_PROC_LOCK_MAIN);    return res;}#define HEAP_REF 1#define LINK_REF 2#define ETS_REF  3 #define BIN_REF  4#define NODE_REF 5#define CTRL_REF 6#define MONITOR_REF 7#define TIMER_REF 8#define SYSTEM_REF 9#define INC_TAB_SZ 10static voidinsert_dist_referrer(ReferredDist *referred_dist,		    int type,		    Eterm id,		    Uint creation){    DistReferrer *drp;    for(drp = referred_dist->referrers; drp; drp = drp->next)	if(id == drp->id && (type == CTRL_REF			     || creation == drp->creation))	    break;    if(!drp) {	drp = (DistReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP,					  sizeof(DistReferrer));	drp->next = referred_dist->referrers;	referred_dist->referrers = drp;	drp->id = id;	drp->creation = creation;	drp->node_ref = 0;	drp->ctrl_ref = 0;    }    switch (type) {    case NODE_REF:	drp->node_ref++;	break;    case CTRL_REF:	drp->ctrl_ref++;	break;    default:		ASSERT(0);    }}static voidinsert_dist_entry(DistEntry *dist, int type, Eterm id, Uint creation){    ReferredDist *rdp = NULL;    int i;    for(i = 0; i < no_referred_dists; i++) {	if(dist == referred_dists[i].dist) {	    rdp = &referred_dists[i];	    break;	}    }    if(!rdp)	erl_exit(1,		 "Reference to non-existing distribution table entry found!\n");    insert_dist_referrer(rdp, type, id, creation);}static voidinsert_node_referrer(ReferredNode *referred_node, int type, Eterm id){    NodeReferrer *nrp;    for(nrp = referred_node->referrers; nrp; nrp = nrp->next)	if(EQ(id, nrp->id))	    break;    if(!nrp) {	nrp = (NodeReferrer *) erts_alloc(ERTS_ALC_T_NC_TMP,					  sizeof(NodeReferrer));	nrp->next = referred_node->referrers;	referred_node->referrers = nrp;	if(IS_CONST(id))	    nrp->id = id;	else {	    Uint *hp = &nrp->id_heap[0];	    ASSERT(is_big(id) || is_tuple(id));	    nrp->id = copy_struct(id, size_object(id), &hp, NULL);	}	nrp->heap_ref = 0;	nrp->link_ref = 0;	nrp->monitor_ref = 0;	nrp->ets_ref = 0;	nrp->bin_ref = 0;	nrp->timer_ref = 0;	nrp->system_ref = 0;    }    switch (type) {    case HEAP_REF:	nrp->heap_ref++;	break;    case LINK_REF:	nrp->link_ref++;	break;    case ETS_REF:	nrp->ets_ref++;		break;    case BIN_REF:	nrp->bin_ref++;		break;    case MONITOR_REF:   nrp->monitor_ref++;     break;    case TIMER_REF:	nrp->timer_ref++;	break;    case SYSTEM_REF:	nrp->system_ref++;	break;    default:		ASSERT(0);    }}static voidinsert_node(ErlNode *node, int type, Eterm id){    int i;    ReferredNode *rnp = NULL;    for(i = 0; i < no_referred_nodes; i++) {	if(node == referred_nodes[i].node) {	    rnp = &referred_nodes[i];	    break;	}    }    if (!rnp)	erl_exit(1, "Reference to non-existing node table entry found!\n");    insert_node_referrer(rnp, type, id);}static voidinsert_erl_node(void *venp, void *unused){    ErlNode *enp = (ErlNode *) venp;    insert_dist_entry(enp->dist_entry, NODE_REF, enp->sysname, enp->creation);}struct insert_offheap2_arg {    int type;    Eterm id;};static void insert_offheap(ErlOffHeap *, int, Eterm);static voidinsert_offheap2(ErlOffHeap *oh, void *arg) {    struct insert_offheap2_arg *a = (struct insert_offheap2_arg *) arg;    insert_offheap(oh, a->type, a->id);}static voidinsert_offheap(ErlOffHeap *oh, int type, Eterm id){    if(oh->externals) {	ExternalThing *etp = oh->externals;	while (etp) {	    insert_node(etp->node, type, id);	    etp = etp->next;	}    }    if(oh->mso) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -