static void delete_table(Process* c_p, HashTable* table) { Uint idx = table->first_to_delete; Uint n = table->num_to_delete; /* * There are no longer any references to this hash table. * * Any literals pointed for deletion can be queued for * deletion and the table itself can be deallocated. */ #ifdef DEBUG if (n == 1) { ASSERT(is_tuple_arity(table->term[idx], 2)); } #endif while (n > 0) { Eterm term = table->term[idx]; if (is_tuple_arity(term, 2)) { if (is_immed(tuple_val(term)[2])) { erts_release_literal_area(term_to_area(term)); } else { erts_queue_release_literals(c_p, term_to_area(term)); } } idx++, n--; } erts_free(ERTS_ALC_T_PERSISTENT_TERM, table); }
static void later_release_literal_area(void *vlrlap) { ErtsLaterReleasLiteralArea *lrlap; lrlap = (ErtsLaterReleasLiteralArea *) vlrlap; erts_release_literal_area(lrlap->la); erts_free(ERTS_ALC_T_RELEASE_LAREA, vlrlap); }
static void complete_literal_area_switch(void *literal_area) { Process *p = erts_literal_area_collector; erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); erts_resume(p, ERTS_PROC_LOCK_STATUS); erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS); if (literal_area) erts_release_literal_area((ErtsLiteralArea *) literal_area); }
BIF_RETTYPE erts_internal_release_literal_area_switch_0(BIF_ALIST_0) { ErtsLiteralArea *unused_la; ErtsLiteralAreaRef *la_ref; if (BIF_P != erts_literal_area_collector) BIF_ERROR(BIF_P, EXC_NOTSUP); erts_smp_mtx_lock(&release_literal_areas.mtx); la_ref = release_literal_areas.first; if (la_ref) { release_literal_areas.first = la_ref->next; if (!release_literal_areas.first) release_literal_areas.last = NULL; } erts_smp_mtx_unlock(&release_literal_areas.mtx); unused_la = ERTS_COPY_LITERAL_AREA(); if (!la_ref) { ERTS_SET_COPY_LITERAL_AREA(NULL); if (unused_la) { #ifdef ERTS_SMP ErtsLaterReleasLiteralArea *lrlap; lrlap = erts_alloc(ERTS_ALC_T_RELEASE_LAREA, sizeof(ErtsLaterReleasLiteralArea)); lrlap->la = unused_la; erts_schedule_thr_prgr_later_cleanup_op( later_release_literal_area, (void *) lrlap, &lrlap->lop, (sizeof(ErtsLaterReleasLiteralArea) + sizeof(ErtsLiteralArea) + ((unused_la->end - &unused_la->start[0]) - 1)*(sizeof(Eterm)))); #else erts_release_literal_area(unused_la); #endif } BIF_RET(am_false); } ERTS_SET_COPY_LITERAL_AREA(la_ref->literal_area); erts_free(ERTS_ALC_T_LITERAL_REF, la_ref); #ifdef ERTS_SMP erts_schedule_thr_prgr_later_op(complete_literal_area_switch, unused_la, &later_literal_area_switch); erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, NULL); ERTS_BIF_YIELD_RETURN(BIF_P, am_true); #else erts_release_literal_area(unused_la); BIF_RET(am_true); #endif }