static ErtsLink *create_link(Uint type, Eterm pid) { Uint lnk_size = ERTS_LINK_SIZE; ErtsLink *n; Eterm *hp; if (!IS_CONST(pid)) { lnk_size += NC_HEAP_SIZE(pid); } if (lnk_size <= ERTS_LINK_SH_SIZE) { n = (ErtsLink *) erts_alloc(ERTS_ALC_T_NLINK_SH, lnk_size*sizeof(Uint)); } else { n = (ErtsLink *) erts_alloc(ERTS_ALC_T_NLINK_LH, lnk_size*sizeof(Uint)); erts_smp_atomic_add_nob(&tot_link_lh_size, lnk_size*sizeof(Uint)); } hp = n->heap; n->left = n->right = NULL; /* Always the same initial value*/ n->type = (Uint16) type; n->balance = 0; /* Always the same initial value */ if (n->type == LINK_NODE) { ERTS_LINK_REFC(n) = 0; } else { ERTS_LINK_ROOT(n) = NULL; } CP_LINK_VAL(n->pid, hp, pid); return n; }
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(ERTS_LINK_ROOT(lnk), *idp); }
void erts_destroy_link(ErtsLink *lnk) { Uint lnk_size = ERTS_LINK_SIZE; ErlNode *node; ASSERT(lnk->type == LINK_NODE || ERTS_LINK_ROOT(lnk) == NULL); if (!IS_CONST(lnk->pid)) { lnk_size += NC_HEAP_SIZE(lnk->pid); if (is_external(lnk->pid)) { node = external_thing_ptr(lnk->pid)->node; erts_deref_node_entry(node); } } if (lnk_size <= ERTS_LINK_SH_SIZE) { erts_free(ERTS_ALC_T_NLINK_SH, (void *) lnk); } else { erts_free(ERTS_ALC_T_NLINK_LH, (void *) lnk); erts_smp_atomic_add_nob(&tot_link_lh_size, -1*lnk_size*sizeof(Uint)); } }