/* does not free, regardless of the value of ht->free_keyval, invoked only when deleting. */ boolean ht_remove(hashtable ht, const void *key) { unsigned int hkey; hashentry *he, *prehe; assert(ht!=NULL); hkey = ht->hash(key); prehe = NULL; LOCK; he = ht->table[hkey%ht->table_size]; while(he!=NULL) { if(he->hashkey == hkey && ht->isequal(he->keyval,key)) { if(prehe != NULL) { prehe->next = he->next; } else { ht->table[hkey%ht->table_size] = he->next; } UNLOCK; free(he); return TRUE; } prehe = he; he = he->next; } UNLOCK; return FALSE; }
KHMEXP void perf_set_thread_desc(const char * file, int line, const wchar_t * name, const wchar_t * creator) { thread_info * t; char * fn_copy; perf_once(); t = malloc(sizeof(*t)); ZeroMemory(t, sizeof(*t)); #ifdef _WIN32 t->thread = GetCurrentThreadId(); #else #error Unsupported platform #endif StringCbCopy(t->name, sizeof(t->name), name); if (creator) StringCbCopy(t->creator, sizeof(t->creator), creator); if (file[0] == '.' && file[1] == '\\') file += 2; EnterCriticalSection(&cs_alloc); fn_copy = hash_lookup(&fn_hash, file); if (fn_copy == NULL) { size_t cblen = 0; if (FAILED(StringCbLengthA(file, MAX_PATH * sizeof(char), &cblen))) fn_copy = NULL; else { fn_copy = malloc(cblen + sizeof(char)); if (fn_copy) { hash_bin * b; int hv; StringCbCopyA(fn_copy, cblen + sizeof(char), file); hv = fn_hash.hash(fn_copy) % fn_hash.n; b = malloc(sizeof(*b)); b->data = fn_copy; b->key = fn_copy; LINIT(b); LPUSH(&fn_hash.bins[hv], b); } } } t->file = fn_copy; t->line = line; LPUSH(&threads, t); LeaveCriticalSection(&cs_alloc); }
void ht_insert(hashtable ht, const void *keyval) { hashentry *he; assert(ht!=NULL); he = malloc_ordie(sizeof(hashentry)); he->hashkey = ht->hash(keyval); he->keyval = keyval; LOCK; he->next = ht->table[he->hashkey%ht->table_size]; ht->table[he->hashkey%ht->table_size] = he; UNLOCK; }
KHMEXP void * perf_malloc(const char * file, int line, size_t s) { allocation * a; void * ptr; size_t h; char * fn_copy = NULL; perf_once(); assert(s > 0); EnterCriticalSection(&cs_alloc); a = get_allocation(); ptr = malloc(s); assert(ptr); /* TODO: handle this gracefully */ if (file[0] == '.' && file[1] == '\\') file += 2; fn_copy = hash_lookup(&fn_hash, file); if (fn_copy == NULL) { size_t cblen = 0; if (FAILED(StringCbLengthA(file, MAX_PATH * sizeof(char), &cblen))) fn_copy = NULL; else { fn_copy = malloc(cblen + sizeof(char)); if (fn_copy) { hash_bin * b; int hv; StringCbCopyA(fn_copy, cblen + sizeof(char), file); hv = fn_hash.hash(fn_copy) % fn_hash.n; b = malloc(sizeof(*b)); b->data = fn_copy; b->key = fn_copy; LINIT(b); LPUSH(&fn_hash.bins[hv], b); } } } a->file = fn_copy; a->line = line; a->size = s; a->ptr = ptr; #ifdef _WIN32 a->thread = GetCurrentThreadId(); #endif h = HASHPTR(ptr); LPUSH(&ht[h], a); LeaveCriticalSection(&cs_alloc); return ptr; }