void erts_destroy_monitor(ErtsMonitor *mon) { Uint mon_size = ERTS_MONITOR_SIZE; ErlNode *node; ASSERT(!IS_CONST(mon->ref)); mon_size += NC_HEAP_SIZE(mon->ref); if (is_external(mon->ref)) { node = external_thing_ptr(mon->ref)->node; erts_deref_node_entry(node); } if (!IS_CONST(mon->pid)) { mon_size += NC_HEAP_SIZE(mon->pid); if (is_external(mon->pid)) { node = external_thing_ptr(mon->pid)->node; erts_deref_node_entry(node); } } if (mon_size <= ERTS_MONITOR_SH_SIZE) { erts_free(ERTS_ALC_T_MONITOR_SH, (void *) mon); } else { erts_free(ERTS_ALC_T_MONITOR_LH, (void *) mon); erts_smp_atomic_add_nob(&tot_link_lh_size, -1*mon_size*sizeof(Uint)); } }
void erts_cleanup_offheap(ErlOffHeap *offheap) { union erl_off_heap_ptr u; for (u.hdr = offheap->first; u.hdr; u.hdr = u.hdr->next) { switch (thing_subtag(u.hdr->thing_word)) { case REFC_BINARY_SUBTAG: erts_bin_release(u.pb->val); break; case FUN_SUBTAG: if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) { erts_erase_fun_entry(u.fun->fe); } break; case REF_SUBTAG: ASSERT(is_magic_ref_thing(u.hdr)); erts_bin_release((Binary *)u.mref->mb); break; default: ASSERT(is_external_header(u.hdr->thing_word)); erts_deref_node_entry(u.ext->node); break; } } }
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)); } }