void lf_ordlist_destroy(struct lf_ordlist *lst) { if (lst->tail->n.refct_claim != 4) lf_ordlist_print(stdout, lst); assert(lst->tail->n.refct_claim == 4); mem_release(lst->fl, lst->head); assert(lst->tail->n.refct_claim == 2); mem_release(lst->fl, lst->tail); mem_freelist_destroy(lst->fl); free(lst); }
void eng_release() { if (g_eng == NULL) return; rs_release_resources(); lod_releasemgr(); #if !defined(_DEBUG_) pak_close(&g_eng->data_pak); #endif prf_releasemgr(); sct_release(); wld_releasemgr(); scn_releasemgr(); cmp_releasemgr(); phx_release(); hud_release(); gfx_release(); rs_reportleaks(); rs_releasemgr(); tsk_releasemgr(); if (g_eng->timer != NULL) timer_destroyinstance(g_eng->timer); /* check for main memory leaks */ if (BIT_CHECK(g_eng->params.flags, ENG_FLAG_DEV)) { int leak_cnt = mem_freelist_getleaks(&g_eng->data_freelist, NULL); if (leak_cnt > 0) log_printf(LOG_WARNING, "%d leaks found on dynamic 'data' memory", leak_cnt); } mem_freelist_destroy(&g_eng->data_freelist); mem_stack_destroy(&g_eng->lsr_stack); log_print(LOG_TEXT, "engine released."); if (BIT_CHECK(g_eng->params.flags, ENG_FLAG_CONSOLE)) { log_outputfunc(FALSE, NULL, NULL); con_release(); } FREE(g_eng); g_eng = NULL; }
struct lf_ordlist *lf_ordlist_create(size_t nbrelm, int (*cmp)(void *a, void *b)) { struct lf_ordlist *lst; lst = calloc(1, sizeof(*lst)); if (!lst) return NULL; lst->cmp = cmp; lst->nelms = nbrelm + 2; lst->fl = mem_freelist_create(lst->nelms, 1, sizeof(struct lf_ordlist_node)); if (!lst->fl) goto err_fl; lst->head = mem_new(lst->fl); if (!lst->head) goto err_head; lst->tail = mem_new(lst->fl); if (!lst->tail) goto err_tail; mem_incr_ref(lst->tail); NEXT(lst->head) = (struct node *) lst->tail; return lst; err_tail: mem_release(lst->fl, lst->head); err_head: mem_freelist_destroy(lst->fl); err_fl: free(lst); return NULL; }
void mt_thread_destroy(mt_thread thread) { /* reset events */ if (thread->events[EVENT_STOP] != NULL) SetEvent(thread->events[EVENT_STOP]); if (thread->events[EVENT_RESUME] != NULL) ResetEvent(thread->events[EVENT_RESUME]); /* wait for thread to finish */ if (thread->t != NULL) { WaitForSingleObject(thread->t, INFINITE); CloseHandle(thread->t); } /* destroy events */ if (thread->events[EVENT_RESUME] != NULL) CloseHandle(thread->events[EVENT_RESUME]); if (thread->events[EVENT_STOP] != NULL) CloseHandle(thread->events[EVENT_STOP]); mem_freelist_destroy(&thread->local_mem); mem_stack_destroy(&thread->tmp_mem); FREE(thread); }
void test_freelist() { const uint item_cnt = 100000; const uint max_size = item_cnt * 1024; void** ptrs = (void**)ALLOC(item_cnt*sizeof(void*), 0); uint* h = (uint*)ALLOC(item_cnt*sizeof(uint), 0); size_t* sizes = (size_t*)ALLOC(item_cnt*sizeof(size_t), 0); uint free_cnt = 0; struct freelist_alloc freelist; struct allocator alloc; mem_freelist_create(mem_heap(), &freelist, max_size, 0); mem_freelist_bindalloc(&freelist, &alloc); uint64 t1 = timer_querytick(); log_printf(LOG_TEXT, "allocating %d items from freelist (with hash validation)...", item_cnt); for (uint i = 0; i < item_cnt; i++) { int s = rand_geti(8, 1024); ASSERT(s <= 1024); ptrs[i] = A_ALLOC(&alloc, s, 6); ASSERT(ptrs[i]); if (i > 0 && rand_flipcoin(50)) { uint idx_tofree = rand_geti(0, i-1); if (ptrs[idx_tofree] != NULL) { A_FREE(&alloc, ptrs[idx_tofree]); ptrs[idx_tofree] = NULL; } } // random fill the buffer memset(ptrs[i], 0x00, s); h[i] = hash_murmur32(ptrs[i], s, 100); sizes[i] = s; } // check if the remaining buffers are untouched for (uint i = 0; i < item_cnt; i++) { if (ptrs[i] != NULL) { #if defined(_DEBUG_) uint hh = hash_murmur32(ptrs[i], sizes[i], 100); ASSERT(h[i] == hh); #endif } } for (uint i = 0; i < item_cnt; i++) { //if (rand_flipcoin(50)) { if (ptrs[i] != NULL) { A_FREE(&alloc, ptrs[i]); free_cnt ++; ptrs[i] = NULL; } //} } /* report leaks */ uint leaks_cnt = mem_freelist_getleaks(&freelist, NULL); if (leaks_cnt > 0) log_printf(LOG_TEXT, "%d leaks found", leaks_cnt); mem_freelist_destroy(&freelist); log_print(LOG_TEXT, "done."); log_printf(LOG_TEXT, "took %f ms.", timer_calctm(t1, timer_querytick())*1000.0f); FREE(ptrs); FREE(h); FREE(sizes); }