[util] Make hash-tables semi-thread-safe

They take a pointer to a free-list used for hashlinks so the hashlink
pools can be per-thread. However, hash tables that are not updated are
always thread-safe, so this affects only updates. progs_t has been set
up such that it is easy for multiple progs within one thread can share
hashlinks.
This commit is contained in:
Bill Currie 2020-03-25 15:43:16 +09:00
parent ee6b078f18
commit 4cef9792f4
57 changed files with 177 additions and 128 deletions

View file

@ -37,6 +37,7 @@
///@{ ///@{
typedef struct hashtab_s hashtab_t; typedef struct hashtab_s hashtab_t;
typedef struct hashlink_s hashlink_t;
/** create a new hash table. /** create a new hash table.
\param tsize table size. larger values will give better distribution, but \param tsize table size. larger values will give better distribution, but
@ -50,6 +51,13 @@ typedef struct hashtab_s hashtab_t;
element to be freed and the second is the user data pointer. element to be freed and the second is the user data pointer.
\param ud user data pointer. set to whatever you want, it will be passed \param ud user data pointer. set to whatever you want, it will be passed
to the get key and free functions as the second parameter. to the get key and free functions as the second parameter.
\param hlfl Address of opaque pointer used for per-thread allocation of
internal memory. If null, a local static pointer will be used,
but the hash table will not be thread-safe unless all tables
created with a null \a hlfl (hashlink freelist) are used in
only the one thread. However, this applys only to updating a
hash table; hash tables that are not updated can be safely
shared between threads.
\return pointer to the hash table (to be passed to the other functions) \return pointer to the hash table (to be passed to the other functions)
or 0 on error. or 0 on error.
@ -59,7 +67,8 @@ typedef struct hashtab_s hashtab_t;
previous ones until the later one is removed (Hash_Del). previous ones until the later one is removed (Hash_Del).
*/ */
hashtab_t *Hash_NewTable (int tsize, const char *(*gk)(const void*,void*), hashtab_t *Hash_NewTable (int tsize, const char *(*gk)(const void*,void*),
void (*f)(void*,void*), void *ud); void (*f)(void*,void*), void *ud,
hashlink_t **hlfl);
/** change the hash and compare functions used by the Hash_*Element functions. /** change the hash and compare functions used by the Hash_*Element functions.
the default hash function just returns the address of the element, and the the default hash function just returns the address of the element, and the

View file

@ -1705,6 +1705,7 @@ struct progs_s {
int null_bad; int null_bad;
int no_exec_limit; int no_exec_limit;
struct hashlink_s **hashlink_freelist;
void (*file_error) (progs_t *pr, const char *path); void (*file_error) (progs_t *pr, const char *path);
void *(*load_file) (progs_t *pr, const char *path, off_t *size); void *(*load_file) (progs_t *pr, const char *path, off_t *size);
void *(*allocate_progs_mem) (progs_t *pr, int size); void *(*allocate_progs_mem) (progs_t *pr, int size);

View file

@ -245,7 +245,7 @@ s_soundlist_f (void)
void void
SND_SFX_Init (void) SND_SFX_Init (void)
{ {
snd_sfx_hash = Hash_NewTable (511, snd_sfx_getkey, snd_sfx_free, 0); snd_sfx_hash = Hash_NewTable (511, snd_sfx_getkey, snd_sfx_free, 0, 0);
precache = Cvar_Get ("precache", "1", CVAR_NONE, NULL, precache = Cvar_Get ("precache", "1", CVAR_NONE, NULL,
"Toggle the use of a precache"); "Toggle the use of a precache");

View file

@ -586,7 +586,7 @@ Menu_Init (void)
PR_Init (&menu_pr_state); PR_Init (&menu_pr_state);
menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0); menu_hash = Hash_NewTable (61, menu_get_key, menu_free, 0, 0);
PR_RegisterBuiltins (&menu_pr_state, builtins); PR_RegisterBuiltins (&menu_pr_state, builtins);

View file

@ -92,8 +92,10 @@ PR_RegisterBuiltins (progs_t *pr, builtin_t *builtins)
int count; int count;
if (!pr->builtin_hash) { if (!pr->builtin_hash) {
pr->builtin_hash = Hash_NewTable (1021, builtin_get_key, 0, pr); pr->builtin_hash = Hash_NewTable (1021, builtin_get_key, 0, pr,
pr->builtin_num_hash = Hash_NewTable (1021, 0, 0, pr); pr->hashlink_freelist);
pr->builtin_num_hash = Hash_NewTable (1021, 0, 0, pr,
pr->hashlink_freelist);
Hash_SetHashCompare (pr->builtin_num_hash, builtin_get_hash, Hash_SetHashCompare (pr->builtin_num_hash, builtin_get_hash,
builtin_compare); builtin_compare);
} }

View file

@ -1610,7 +1610,8 @@ PR_Debug_Init (progs_t *pr)
PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear); PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear);
if (!file_hash) { if (!file_hash) {
file_hash = Hash_NewTable (1024, file_get_key, file_free, 0); file_hash = Hash_NewTable (1024, file_get_key, file_free, 0,
pr->hashlink_freelist);
} }
PR_AddLoadFunc (pr, PR_LoadDebug); PR_AddLoadFunc (pr, PR_LoadDebug);
} }

View file

@ -234,17 +234,20 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
if (pr->function_hash) { if (pr->function_hash) {
Hash_FlushTable (pr->function_hash); Hash_FlushTable (pr->function_hash);
} else { } else {
pr->function_hash = Hash_NewTable (1021, function_get_key, 0, pr); pr->function_hash = Hash_NewTable (1021, function_get_key, 0, pr,
pr->hashlink_freelist);
} }
if (pr->global_hash) { if (pr->global_hash) {
Hash_FlushTable (pr->global_hash); Hash_FlushTable (pr->global_hash);
} else { } else {
pr->global_hash = Hash_NewTable (1021, var_get_key, 0, pr); pr->global_hash = Hash_NewTable (1021, var_get_key, 0, pr,
pr->hashlink_freelist);
} }
if (pr->field_hash) { if (pr->field_hash) {
Hash_FlushTable (pr->field_hash); Hash_FlushTable (pr->field_hash);
} else { } else {
pr->field_hash = Hash_NewTable (1021, var_get_key, 0, pr); pr->field_hash = Hash_NewTable (1021, var_get_key, 0, pr,
pr->hashlink_freelist);
} }
// byte swap the lumps // byte swap the lumps

View file

@ -1513,7 +1513,7 @@ PR_Opcode_Init (void)
// already initialized // already initialized
return; return;
} }
opcode_table = Hash_NewTable (1021, 0, 0, 0); opcode_table = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (opcode_table, opcode_get_hash, opcode_compare); Hash_SetHashCompare (opcode_table, opcode_get_hash, opcode_compare);
for (op = pr_opcodes; op->name; op++) { for (op = pr_opcodes; op->name; op++) {

View file

@ -53,7 +53,8 @@ resource_get_key (const void *r, void *unused)
VISIBLE void VISIBLE void
PR_Resources_Init (progs_t *pr) PR_Resources_Init (progs_t *pr)
{ {
pr->resource_hash = Hash_NewTable (1021, resource_get_key, 0, 0); pr->resource_hash = Hash_NewTable (1021, resource_get_key, 0, 0,
pr->hashlink_freelist);
pr->resources = 0; pr->resources = 0;
} }

View file

@ -259,7 +259,7 @@ PR_LoadStrings (progs_t *pr)
Hash_FlushTable (res->strref_hash); Hash_FlushTable (res->strref_hash);
} else { } else {
res->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free, res->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
res); res, pr->hashlink_freelist);
res->string_map = 0; res->string_map = 0;
res->free_string_refs = 0; res->free_string_refs = 0;
res->dyn_str_size = 0; res->dyn_str_size = 0;

View file

@ -193,7 +193,8 @@ GIB_Progs_Init (progs_t *pr)
PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear); PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear);
bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key, bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key,
bi_gib_builtin_free, 0); bi_gib_builtin_free, 0,
pr->hashlink_freelist);
PR_RegisterBuiltins (pr, builtins); PR_RegisterBuiltins (pr, builtins);
} }

View file

@ -99,7 +99,7 @@ GIB_Builtin_Add (const char *name, void (*func) (void))
if (!gib_builtins) if (!gib_builtins)
gib_builtins = gib_builtins =
Hash_NewTable (1024, GIB_Builtin_Get_Key, GIB_Builtin_Free, 0); Hash_NewTable (1024, GIB_Builtin_Get_Key, GIB_Builtin_Free, 0, 0);
new = calloc (1, sizeof (gib_builtin_t)); new = calloc (1, sizeof (gib_builtin_t));
new->func = func; new->func = func;

View file

@ -388,8 +388,7 @@ ObjectHash_Construct (gib_object_t *obj)
{ {
ObjectHash_t *data = malloc (sizeof (ObjectHash_t)); ObjectHash_t *data = malloc (sizeof (ObjectHash_t));
data->objects = Hash_NewTable (1024, ObjRef_Get_Key, ObjRef_Free, data->objects = Hash_NewTable (1024, ObjRef_Get_Key, ObjRef_Free, NULL, 0);
NULL);
return data; return data;
} }

View file

@ -117,8 +117,8 @@ GIB_Function_Define (const char *name, const char *text, gib_tree_t * program,
if (script) if (script)
script->refs++; script->refs++;
if (!gib_functions) if (!gib_functions)
gib_functions = gib_functions = Hash_NewTable (1024, GIB_Function_Get_Key,
Hash_NewTable (1024, GIB_Function_Get_Key, GIB_Function_Free, 0); GIB_Function_Free, 0, 0);
func = Hash_Find (gib_functions, name); func = Hash_Find (gib_functions, name);
if (func) { if (func) {

View file

@ -125,7 +125,8 @@ GIB_Method_Build_Hash (gib_class_t *class, hashtab_t *inherited,
{ {
gib_methodtab_t *m; gib_methodtab_t *m;
gib_method_t *method; gib_method_t *method;
hashtab_t *new = Hash_NewTable (1024, GIB_Method_Get_Key, GIB_Method_Free, 0); hashtab_t *new = Hash_NewTable (1024, GIB_Method_Get_Key,
GIB_Method_Free, 0, 0);
for (m = methods; m->name; m++) { for (m = methods; m->name; m++) {
method = malloc (sizeof (gib_method_t)); method = malloc (sizeof (gib_method_t));
@ -207,7 +208,7 @@ GIB_Object_Create (const char *classname, qboolean classobj)
obj->handstr = strdup (va ("%lu", obj->handle)); obj->handstr = strdup (va ("%lu", obj->handle));
obj->refs = 1; obj->refs = 1;
obj->signals = Hash_NewTable (128, GIB_Signal_Get_Key, obj->signals = Hash_NewTable (128, GIB_Signal_Get_Key,
GIB_Signal_Free, NULL); GIB_Signal_Free, NULL, 0);
obj->slots = llist_new (GIB_Slot_Free, NULL, NULL); obj->slots = llist_new (GIB_Slot_Free, NULL, NULL);
if (classobj) { if (classobj) {
@ -392,7 +393,8 @@ GIB_Object_Signal_Emit (gib_object_t *sender, int argc, const char **argv)
void void
GIB_Object_Init (void) GIB_Object_Init (void)
{ {
gib_classes = Hash_NewTable (1024, GIB_Class_Get_Key, GIB_Class_Free, 0); gib_classes = Hash_NewTable (1024, GIB_Class_Get_Key,
GIB_Class_Free, 0, 0);
GIB_Classes_Init (); GIB_Classes_Init ();
} }

View file

@ -63,7 +63,7 @@ GIB_Regex_Free (void *ele, void *ptr)
void void
GIB_Regex_Init (void) GIB_Regex_Init (void)
{ {
gib_regexs = Hash_NewTable (512, GIB_Regex_Get_Key, GIB_Regex_Free, 0); gib_regexs = Hash_NewTable (512, GIB_Regex_Get_Key, GIB_Regex_Free, 0, 0);
} }
regex_t * regex_t *

View file

@ -171,5 +171,5 @@ GIB_Event_Callback (gib_event_t * event, unsigned int argc, ...)
void void
GIB_Event_Init (void) GIB_Event_Init (void)
{ {
gib_events = Hash_NewTable (1024, GIB_Event_Get_Key, GIB_Event_Free, 0); gib_events = Hash_NewTable (1024, GIB_Event_Get_Key, GIB_Event_Free, 0, 0);
} }

View file

@ -117,7 +117,8 @@ GIB_Var_Get_Complex (hashtab_t ** first, hashtab_t ** second, char *key,
if (!(var = GIB_Var_Get (*first, *second, key+start)) && create) { if (!(var = GIB_Var_Get (*first, *second, key+start)) && create) {
var = GIB_Var_New (key+start); var = GIB_Var_New (key+start);
if (!*first) if (!*first)
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0); *first = Hash_NewTable (256, GIB_Var_Get_Key,
GIB_Var_Free, 0, 0);
Hash_Add (*first, var); Hash_Add (*first, var);
} }
@ -181,7 +182,8 @@ GIB_Var_Get_Very_Complex (hashtab_t ** first, hashtab_t ** second, dstring_t *ke
if (create) { if (create) {
var = GIB_Var_New (key->str+start); var = GIB_Var_New (key->str+start);
if (!*first) if (!*first)
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0); *first = Hash_NewTable (256, GIB_Var_Get_Key,
GIB_Var_Free, 0, 0);
Hash_Add (*first, var); Hash_Add (*first, var);
} else } else
return 0; return 0;
@ -293,7 +295,7 @@ GIB_Domain_Get (const char *name)
if (!d) { if (!d) {
d = calloc (1, sizeof (gib_domain_t)); d = calloc (1, sizeof (gib_domain_t));
d->name = strdup (name); d->name = strdup (name);
d->vars = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0); d->vars = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0, 0);
Hash_Add (gib_domains, d); Hash_Add (gib_domains, d);
} }
return d->vars; return d->vars;
@ -302,12 +304,13 @@ GIB_Domain_Get (const char *name)
hashtab_t * hashtab_t *
GIB_Var_Hash_New (void) GIB_Var_Hash_New (void)
{ {
return Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0); return Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0, 0);
} }
void void
GIB_Var_Init (void) GIB_Var_Init (void)
{ {
gib_globals = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0); gib_globals = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0, 0);
gib_domains = Hash_NewTable (1024, GIB_Domain_Get_Key, GIB_Domain_Free, 0); gib_domains = Hash_NewTable (1024, GIB_Domain_Get_Key,
GIB_Domain_Free, 0, 0);
} }

View file

@ -600,7 +600,7 @@ Mod_IQMBuildBlendPalette (iqm_t *iqm, int *size)
} }
num_blends = iqm->num_joints; num_blends = iqm->num_joints;
blend_hash = Hash_NewTable (1023, 0, 0, 0); blend_hash = Hash_NewTable (1023, 0, 0, 0, 0);
Hash_SetHashCompare (blend_hash, blend_get_hash, blend_compare); Hash_SetHashCompare (blend_hash, blend_get_hash, blend_compare);
for (i = 0; i < iqm->num_verts; i++) { for (i = 0; i < iqm->num_verts; i++) {

View file

@ -242,6 +242,6 @@ skin_free (void *_sb, void *unused)
void void
Skin_Init (void) Skin_Init (void)
{ {
skin_cache = Hash_NewTable (127, skin_getkey, skin_free, 0); skin_cache = Hash_NewTable (127, skin_getkey, skin_free, 0, 0);
m_funcs->Skin_InitTranslations (); m_funcs->Skin_InitTranslations ();
} }

View file

@ -162,7 +162,8 @@ RUA_Cmd_Init (progs_t *pr, int secure)
PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear); PR_Resources_Register (pr, "Cmd", res, bi_cmd_clear);
if (!bi_cmds) if (!bi_cmds)
bi_cmds = Hash_NewTable (1021, bi_cmd_get_key, bi_cmd_free, 0); bi_cmds = Hash_NewTable (1021, bi_cmd_get_key, bi_cmd_free, 0,
pr->hashlink_freelist);
PR_RegisterBuiltins (pr, builtins); PR_RegisterBuiltins (pr, builtins);
} }

View file

@ -162,7 +162,7 @@ bi_Hash_NewTable (progs_t *pr)
gk = ht->gk ? bi_get_key : 0; gk = ht->gk ? bi_get_key : 0;
f = ht->f ? bi_free : 0; f = ht->f ? bi_free : 0;
ht->tab = Hash_NewTable (tsize, gk, f, ht); ht->tab = Hash_NewTable (tsize, gk, f, ht, pr->hashlink_freelist);
R_INT (pr) = table_index (res, ht); R_INT (pr) = table_index (res, ht);
} }

View file

@ -2215,10 +2215,14 @@ RUA_Obj_Init (progs_t *pr, int secure)
probj_t *probj = calloc (1, sizeof (*probj)); probj_t *probj = calloc (1, sizeof (*probj));
probj->pr = pr; probj->pr = pr;
probj->selector_hash = Hash_NewTable (1021, selector_get_key, 0, probj); probj->selector_hash = Hash_NewTable (1021, selector_get_key, 0, probj,
probj->classes = Hash_NewTable (1021, class_get_key, 0, probj); pr->hashlink_freelist);
probj->protocols = Hash_NewTable (1021, protocol_get_key, 0, probj); probj->classes = Hash_NewTable (1021, class_get_key, 0, probj,
probj->load_methods = Hash_NewTable (1021, 0, 0, probj); pr->hashlink_freelist);
probj->protocols = Hash_NewTable (1021, protocol_get_key, 0, probj,
pr->hashlink_freelist);
probj->load_methods = Hash_NewTable (1021, 0, 0, probj,
pr->hashlink_freelist);
probj->msg = dstring_newstr(); probj->msg = dstring_newstr();
Hash_SetHashCompare (probj->load_methods, load_methods_get_hash, Hash_SetHashCompare (probj->load_methods, load_methods_get_hash,
load_methods_compare); load_methods_compare);

View file

@ -455,7 +455,7 @@ void
RUA_Plist_Init (progs_t *pr, int secure) RUA_Plist_Init (progs_t *pr, int secure)
{ {
plist_resources_t *res = calloc (1, sizeof (plist_resources_t)); plist_resources_t *res = calloc (1, sizeof (plist_resources_t));
res->plist_tab = Hash_NewTable (1021, 0, 0, 0); res->plist_tab = Hash_NewTable (1021, 0, 0, 0, pr->hashlink_freelist);
Hash_SetHashCompare (res->plist_tab, plist_get_hash, plist_compare); Hash_SetHashCompare (res->plist_tab, plist_get_hash, plist_compare);
PR_Resources_Register (pr, "plist", res, bi_plist_clear); PR_Resources_Register (pr, "plist", res, bi_plist_clear);

View file

@ -583,9 +583,11 @@ Cmd_StuffCmds_f (void)
VISIBLE void VISIBLE void
Cmd_Init_Hash (void) Cmd_Init_Hash (void)
{ {
cmd_hash = Hash_NewTable (1021, cmd_get_key, 0, 0); cmd_hash = Hash_NewTable (1021, cmd_get_key, 0, 0, 0);
cmd_alias_hash = Hash_NewTable (1021, cmd_alias_get_key, cmd_alias_free, 0); cmd_alias_hash = Hash_NewTable (1021, cmd_alias_get_key,
cmd_provider_hash = Hash_NewTable(1021, cmd_provider_get_key, cmd_provider_free, 0); cmd_alias_free, 0, 0);
cmd_provider_hash = Hash_NewTable(1021, cmd_provider_get_key,
cmd_provider_free, 0, 0);
} }
VISIBLE void VISIBLE void

View file

@ -580,8 +580,8 @@ calias_get_key (const void *c, void *unused)
VISIBLE void VISIBLE void
Cvar_Init_Hash (void) Cvar_Init_Hash (void)
{ {
cvar_hash = Hash_NewTable (1021, cvar_get_key, cvar_free, 0); cvar_hash = Hash_NewTable (1021, cvar_get_key, cvar_free, 0, 0);
calias_hash = Hash_NewTable (1021, calias_get_key, calias_free, 0); calias_hash = Hash_NewTable (1021, calias_get_key, calias_free, 0, 0);
} }
VISIBLE void VISIBLE void

View file

@ -45,11 +45,11 @@
#include "compat.h" #include "compat.h"
typedef struct hashlink_s { struct hashlink_s {
struct hashlink_s *next; struct hashlink_s *next;
struct hashlink_s **prev; struct hashlink_s **prev;
void *data; void *data;
} hashlink_t; };
struct hashtab_s { struct hashtab_s {
size_t tab_size; size_t tab_size;
@ -60,38 +60,39 @@ struct hashtab_s {
uintptr_t (*get_hash)(const void*,void*); uintptr_t (*get_hash)(const void*,void*);
const char *(*get_key)(const void*,void*); const char *(*get_key)(const void*,void*);
void (*free_ele)(void*,void*); void (*free_ele)(void*,void*);
hashlink_t **hashlink_freelist;
hashlink_t *tab[1]; // variable size hashlink_t *tab[1]; // variable size
}; };
static hashlink_t *free_hashlinks;
static hashlink_t * static hashlink_t *
new_hashlink (void) new_hashlink (hashlink_t **free_hashlinks)
{ {
hashlink_t *link; hashlink_t *link;
if (!free_hashlinks) { if (!*free_hashlinks) {
int i; int i;
if (!(free_hashlinks = calloc (1024, sizeof (hashlink_t)))) if (!(*free_hashlinks = calloc (1024, sizeof (hashlink_t))))
return 0; return 0;
for (i = 0, link = free_hashlinks; i < 1023; i++, link++) for (i = 0, link = *free_hashlinks; i < 1023; i++, link++)
link->next = link + 1; link->next = link + 1;
link->next = 0; link->next = 0;
} }
link = free_hashlinks; link = *free_hashlinks;
free_hashlinks = link->next; *free_hashlinks = link->next;
link->next = 0; link->next = 0;
return link; return link;
} }
static void static void
free_hashlink (hashlink_t *link) free_hashlink (hashlink_t *link, hashlink_t **free_hashlinks)
{ {
link->next = free_hashlinks; link->next = *free_hashlinks;
free_hashlinks = link; *free_hashlinks = link;
} }
static hashlink_t *default_hashlink_freelist;
VISIBLE unsigned long VISIBLE unsigned long
Hash_String (const char *str) Hash_String (const char *str)
{ {
@ -183,7 +184,8 @@ get_index (uintptr_t hash, size_t size, size_t bits)
VISIBLE hashtab_t * VISIBLE hashtab_t *
Hash_NewTable (int tsize, const char *(*gk)(const void*,void*), Hash_NewTable (int tsize, const char *(*gk)(const void*,void*),
void (*f)(void*,void*), void *ud) void (*f)(void*,void*), void *ud,
hashlink_t **hashlink_freelist)
{ {
hashtab_t *tab = calloc (1, field_offset (hashtab_t, tab[tsize])); hashtab_t *tab = calloc (1, field_offset (hashtab_t, tab[tsize]));
if (!tab) if (!tab)
@ -192,6 +194,10 @@ Hash_NewTable (int tsize, const char *(*gk)(const void*,void*),
tab->user_data = ud; tab->user_data = ud;
tab->get_key = gk; tab->get_key = gk;
tab->free_ele = f; tab->free_ele = f;
if (!hashlink_freelist) {
hashlink_freelist = &default_hashlink_freelist;
}
tab->hashlink_freelist = hashlink_freelist;
while (tsize) { while (tsize) {
tab->size_bits++; tab->size_bits++;
@ -228,7 +234,7 @@ Hash_FlushTable (hashtab_t *tab)
hashlink_t *t = tab->tab[i]->next; hashlink_t *t = tab->tab[i]->next;
void *data = tab->tab[i]->data; void *data = tab->tab[i]->data;
free_hashlink (tab->tab[i]); free_hashlink (tab->tab[i], tab->hashlink_freelist);
tab->tab[i] = t; tab->tab[i] = t;
if (tab->free_ele) if (tab->free_ele)
tab->free_ele (data, tab->user_data); tab->free_ele (data, tab->user_data);
@ -242,7 +248,7 @@ Hash_Add (hashtab_t *tab, void *ele)
{ {
unsigned long h = Hash_String (tab->get_key(ele, tab->user_data)); unsigned long h = Hash_String (tab->get_key(ele, tab->user_data));
size_t ind = get_index (h, tab->tab_size, tab->size_bits); size_t ind = get_index (h, tab->tab_size, tab->size_bits);
hashlink_t *lnk = new_hashlink (); hashlink_t *lnk = new_hashlink (tab->hashlink_freelist);
if (!lnk) if (!lnk)
return -1; return -1;
@ -261,7 +267,7 @@ Hash_AddElement (hashtab_t *tab, void *ele)
{ {
unsigned long h = tab->get_hash (ele, tab->user_data); unsigned long h = tab->get_hash (ele, tab->user_data);
size_t ind = get_index (h, tab->tab_size, tab->size_bits); size_t ind = get_index (h, tab->tab_size, tab->size_bits);
hashlink_t *lnk = new_hashlink (); hashlink_t *lnk = new_hashlink (tab->hashlink_freelist);
if (!lnk) if (!lnk)
return -1; return -1;
@ -375,7 +381,7 @@ Hash_Del (hashtab_t *tab, const char *key)
if (lnk->next) if (lnk->next)
lnk->next->prev = lnk->prev; lnk->next->prev = lnk->prev;
*lnk->prev = lnk->next; *lnk->prev = lnk->next;
free_hashlink (lnk); free_hashlink (lnk, tab->hashlink_freelist);
tab->num_ele--; tab->num_ele--;
return data; return data;
} }
@ -398,7 +404,7 @@ Hash_DelElement (hashtab_t *tab, void *ele)
if (lnk->next) if (lnk->next)
lnk->next->prev = lnk->prev; lnk->next->prev = lnk->prev;
*lnk->prev = lnk->next; *lnk->prev = lnk->next;
free_hashlink (lnk); free_hashlink (lnk, tab->hashlink_freelist);
tab->num_ele--; tab->num_ele--;
return data; return data;
} }

View file

@ -228,7 +228,7 @@ Info_ParseString (const char *s, int maxsize, int flags)
char *key, *value, *end; char *key, *value, *end;
info = malloc (sizeof (info_t)); info = malloc (sizeof (info_t));
info->tab = Hash_NewTable (61, info_get_key, free_key, 0); info->tab = Hash_NewTable (61, info_get_key, free_key, 0, 0);
info->maxsize = maxsize; info->maxsize = maxsize;
info->cursize = 0; info->cursize = 0;

View file

@ -66,7 +66,7 @@ pack_new (const char *name)
free (pack); free (pack);
return 0; return 0;
} }
pack->file_hash = Hash_NewTable (1021, pack_get_key, 0, 0); pack->file_hash = Hash_NewTable (1021, pack_get_key, 0, 0, 0);
if (!pack->file_hash) { if (!pack->file_hash) {
free (pack->filename); free (pack->filename);
free (pack); free (pack);

View file

@ -241,9 +241,9 @@ VISIBLE void
PI_Init (void) PI_Init (void)
{ {
PI_InitCvars (); PI_InitCvars ();
registered_plugins = Hash_NewTable (253, plugin_get_key, 0, 0); registered_plugins = Hash_NewTable (253, plugin_get_key, 0, 0, 0);
loaded_plugins = Hash_NewTable(253, loaded_plugin_get_key, loaded_plugins = Hash_NewTable(253, loaded_plugin_get_key,
loaded_plugin_delete, 0); loaded_plugin_delete, 0, 0);
Cmd_AddCommand("plugin_load", PI_Plugin_Load_f, Cmd_AddCommand("plugin_load", PI_Plugin_Load_f,
"load the plugin of the given type name and name"); "load the plugin of the given type name and name");
Cmd_AddCommand("plugin_unload", PI_Plugin_Unload_f, Cmd_AddCommand("plugin_unload", PI_Plugin_Unload_f,

View file

@ -149,7 +149,8 @@ VISIBLE plitem_t *
PL_NewDictionary (void) PL_NewDictionary (void)
{ {
plitem_t *item = PL_NewItem (QFDictionary); plitem_t *item = PL_NewItem (QFDictionary);
hashtab_t *dict = Hash_NewTable (1021, dict_get_key, dict_free, NULL); //FIXME need a per-thread hashlink freelist for plist to be thread-safe
hashtab_t *dict = Hash_NewTable (1021, dict_get_key, dict_free, NULL, 0);
item->data = dict; item->data = dict;
return item; return item;
} }

View file

@ -307,7 +307,7 @@ qfs_var_free (void *_v, void *unused)
static hashtab_t * static hashtab_t *
qfs_new_vars (void) qfs_new_vars (void)
{ {
return Hash_NewTable (61, qfs_var_get_key, qfs_var_free, 0); return Hash_NewTable (61, qfs_var_get_key, qfs_var_free, 0, 0);
} }
static void static void
@ -549,7 +549,7 @@ qfs_build_gamedir (const char **list)
gamedir_t *gamedir; gamedir_t *gamedir;
plitem_t *gdpl; plitem_t *gdpl;
dstring_t *path; dstring_t *path;
hashtab_t *dirs = Hash_NewTable (31, qfs_dir_get_key, qfs_dir_free, 0); hashtab_t *dirs = Hash_NewTable (31, qfs_dir_get_key, qfs_dir_free, 0, 0);
hashtab_t *vars = qfs_new_vars (); hashtab_t *vars = qfs_new_vars ();
const char *dir = 0; const char *dir = 0;

View file

@ -140,7 +140,7 @@ Segtext_new (const char *source_string)
if (!source_string) if (!source_string)
return 0; return 0;
text = new_text (); text = new_text ();
text->tab = Hash_NewTable (61, segtext_getkey, 0, 0); text->tab = Hash_NewTable (61, segtext_getkey, 0, 0, 0);
src = strdup (source_string); src = strdup (source_string);
// The first chunk is special in that it holds the pointer to the copied // The first chunk is special in that it holds the pointer to the copied

View file

@ -86,7 +86,7 @@ wad_new (const char *name)
free (wad); free (wad);
return 0; return 0;
} }
wad->lump_hash = Hash_NewTable (1021, 0, 0, 0); wad->lump_hash = Hash_NewTable (1021, 0, 0, 0, 0);
if (!wad->lump_hash) { if (!wad->lump_hash) {
free (wad->filename); free (wad->filename);
free (wad); free (wad);

View file

@ -375,7 +375,7 @@ glsl_Draw_Init (void)
qpic_t *pic; qpic_t *pic;
//FIXME glpic_t *gl; //FIXME glpic_t *gl;
pic_cache = Hash_NewTable (127, cachepic_getkey, cachepic_free, 0); pic_cache = Hash_NewTable (127, cachepic_getkey, cachepic_free, 0, 0);
QFS_GamedirCallback (Draw_ClearCache); QFS_GamedirCallback (Draw_ClearCache);
//FIXME temporary work around for the timing of cvar creation and palette //FIXME temporary work around for the timing of cvar creation and palette
//loading //loading

View file

@ -72,7 +72,7 @@ GLSL_RegisterEffect (const char *name, const char *src)
segtext_t *text; segtext_t *text;
if (!effect_tab) if (!effect_tab)
effect_tab = Hash_NewTable (61, effect_get_key, 0, 0); effect_tab = Hash_NewTable (61, effect_get_key, 0, 0, 0);
if (Hash_Find (effect_tab, name)) { if (Hash_Find (effect_tab, name)) {
Sys_Printf ("WARNING: ignoring duplicate '%s' effect\n", name); Sys_Printf ("WARNING: ignoring duplicate '%s' effect\n", name);

View file

@ -345,7 +345,8 @@ void
R_Progs_Init (progs_t *pr) R_Progs_Init (progs_t *pr)
{ {
draw_resources_t *res = calloc (1, sizeof (draw_resources_t)); draw_resources_t *res = calloc (1, sizeof (draw_resources_t));
res->pic_hash = Hash_NewTable (61, bi_draw_get_key, 0, 0); res->pic_hash = Hash_NewTable (61, bi_draw_get_key, 0, 0,
pr->hashlink_freelist);
PR_Resources_Register (pr, "Draw", res, bi_draw_clear); PR_Resources_Register (pr, "Draw", res, bi_draw_clear);
PR_RegisterBuiltins (pr, builtins); PR_RegisterBuiltins (pr, builtins);

View file

@ -233,7 +233,7 @@ OK_Init (void)
{ {
old_keyname_t *ok; old_keyname_t *ok;
old_key_table = Hash_NewTable (1021, ok_get_key, 0, 0); old_key_table = Hash_NewTable (1021, ok_get_key, 0, 0, 0);
for (ok = old_keynames; ok->old_name; ok++) for (ok = old_keynames; ok->old_name; ok++)
Hash_Add (old_key_table, ok); Hash_Add (old_key_table, ok);
} }

View file

@ -1204,7 +1204,7 @@ Client_Init (void)
{ {
size_t i; size_t i;
ucmd_table = Hash_NewTable (251, ucmds_getkey, 0, 0); ucmd_table = Hash_NewTable (251, ucmds_getkey, 0, 0, 0);
for (i = 0; i < sizeof (ucmds) / sizeof (ucmds[0]); i++) for (i = 0; i < sizeof (ucmds) / sizeof (ucmds[0]); i++)
Hash_Add (ucmd_table, &ucmds[i]); Hash_Add (ucmd_table, &ucmds[i]);
} }

View file

@ -79,7 +79,7 @@ connection_compare (const void *_c1, const void *_c2, void *unused)
void void
Connection_Init (void) Connection_Init (void)
{ {
connections = Hash_NewTable (1023, 0, connection_free, 0); connections = Hash_NewTable (1023, 0, connection_free, 0, 0);
Hash_SetHashCompare (connections, connection_get_hash, connection_compare); Hash_SetHashCompare (connections, connection_get_hash, connection_compare);
} }

View file

@ -541,7 +541,7 @@ void
Server_Init (void) Server_Init (void)
{ {
Sys_RegisterShutdown (server_shutdown, 0); Sys_RegisterShutdown (server_shutdown, 0);
server_hash = Hash_NewTable (61, server_get_key, server_free, 0); server_hash = Hash_NewTable (61, server_get_key, server_free, 0, 0);
Cmd_AddCommand ("sv_new", sv_new_f, "Add a new server"); Cmd_AddCommand ("sv_new", sv_new_f, "Add a new server");
Cmd_AddCommand ("sv_del", sv_del_f, "Remove an existing server"); Cmd_AddCommand ("sv_del", sv_del_f, "Remove an existing server");
Cmd_AddCommand ("sv_list", sv_list_f, "List available servers"); Cmd_AddCommand ("sv_list", sv_list_f, "List available servers");

View file

@ -2009,7 +2009,7 @@ static builtin_t builtins[] = {
void void
SV_UserInit (void) SV_UserInit (void)
{ {
ucmd_table = Hash_NewTable (251, ucmds_getkey, ucmds_free, 0); ucmd_table = Hash_NewTable (251, ucmds_getkey, ucmds_free, 0, 0);
Hash_SetHashCompare (ucmd_table, ucmd_get_hash, ucmd_compare); Hash_SetHashCompare (ucmd_table, ucmd_get_hash, ucmd_compare);
PR_RegisterBuiltins (&sv_pr_state, builtins); PR_RegisterBuiltins (&sv_pr_state, builtins);
cl_rollspeed = Cvar_Get ("cl_rollspeed", "200", CVAR_NONE, NULL, cl_rollspeed = Cvar_Get ("cl_rollspeed", "200", CVAR_NONE, NULL,

View file

@ -323,7 +323,10 @@ parse_key (qwaq_resources_t *res)
{ {
qwaq_key_t *key = Hash_Find (res->key_sequences, res->escbuff.str); qwaq_key_t *key = Hash_Find (res->key_sequences, res->escbuff.str);
//Sys_Printf ("parse_key: %s\n", res->escbuff.str + 1);
if (key) { if (key) {
//Sys_Printf (" %d %03x %s\n", key->key, key->shift,
// Key_KeynumToString (key->key));
key_event (res, key->key, key->shift); key_event (res, key->key, key->shift);
} }
} }
@ -417,7 +420,8 @@ void qwaq_input_init (qwaq_resources_t *res)
if (res->key_sequences) { if (res->key_sequences) {
Hash_FlushTable (res->key_sequences); Hash_FlushTable (res->key_sequences);
} else { } else {
res->key_sequences = Hash_NewTable (127, key_sequence_getkey, 0, 0); res->key_sequences = Hash_NewTable (127, key_sequence_getkey, 0, 0,
res->pr->hashlink_freelist);
} }
for (size_t i = 0; i < sizeof (default_keys) / sizeof (default_keys[0]); for (size_t i = 0; i < sizeof (default_keys) / sizeof (default_keys[0]);
i++) { i++) {

View file

@ -97,7 +97,7 @@ FindMiptex (const char *name)
if (strcmp (name, "skip") == 0) if (strcmp (name, "skip") == 0)
return TEX_SKIP; return TEX_SKIP;
if (!miptex_hash) if (!miptex_hash)
miptex_hash = Hash_NewTable (1023, miptex_getkey, 0, 0); miptex_hash = Hash_NewTable (1023, miptex_getkey, 0, 0, 0);
if (miptexnames) { if (miptexnames) {
index = (intptr_t) Hash_Find (miptex_hash, mpname); index = (intptr_t) Hash_Find (miptex_hash, mpname);
if (index) if (index)

View file

@ -192,9 +192,10 @@ add_static_instance (const char *class, def_t *instance_def)
static_instance_t *instance = malloc (sizeof (*instance)); static_instance_t *instance = malloc (sizeof (*instance));
if (!static_instances) { if (!static_instances) {
static_instances = Hash_NewTable (1021, static_instance_get_key, 0, 0); static_instances = Hash_NewTable (1021, static_instance_get_key,
0, 0, 0);
static_instance_classes = Hash_NewTable (1021, static_instance_get_key, static_instance_classes = Hash_NewTable (1021, static_instance_get_key,
0, 0); 0, 0, 0);
} }
instance->class = save_string (class); instance->class = save_string (class);
@ -561,7 +562,7 @@ _get_class (symbol_t *sym, int create)
class_t *c; class_t *c;
if (!class_hash) if (!class_hash)
class_hash = Hash_NewTable (1021, class_get_key, 0, 0); class_hash = Hash_NewTable (1021, class_get_key, 0, 0, 0);
if (sym) { if (sym) {
c = Hash_Find (class_hash, sym->name); c = Hash_Find (class_hash, sym->name);
if (c || !create) if (c || !create)
@ -1272,7 +1273,7 @@ get_category (symbol_t *class_name, const char *category_name, int create)
class_t *class; class_t *class;
if (!category_hash) { if (!category_hash) {
category_hash = Hash_NewTable (1021, 0, 0, 0); category_hash = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (category_hash, Hash_SetHashCompare (category_hash,
category_get_hash, category_compare); category_get_hash, category_compare);
} }
@ -1549,7 +1550,7 @@ get_protocol (const char *name, int create)
protocol_t *p; protocol_t *p;
if (!protocol_hash) if (!protocol_hash)
protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0); protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0, 0);
if (name) { if (name) {
p = Hash_Find (protocol_hash, name); p = Hash_Find (protocol_hash, name);

View file

@ -241,8 +241,8 @@ get_function (const char *name, type_t *type, int overload, int create)
overloaded_function_t *func; overloaded_function_t *func;
if (!overloaded_functions) { if (!overloaded_functions) {
overloaded_functions = Hash_NewTable (1021, ol_func_get_key, 0, 0); overloaded_functions = Hash_NewTable (1021, ol_func_get_key, 0, 0, 0);
function_map = Hash_NewTable (1021, func_map_get_key, 0, 0); function_map = Hash_NewTable (1021, func_map_get_key, 0, 0, 0);
} }
name = save_string (name); name = save_string (name);

View file

@ -105,8 +105,8 @@ do_grab (const char *token)
size_t i; size_t i;
initialized = 1; initialized = 1;
frame_tab = Hash_NewTable (1021, frame_get_key, frame_free, 0); frame_tab = Hash_NewTable (1021, frame_get_key, frame_free, 0, 0);
grab_tab = Hash_NewTable (1021, frame_get_key, 0, 0); grab_tab = Hash_NewTable (1021, frame_get_key, 0, 0, 0);
for (i = 0; i < sizeof (grab_list) / sizeof (grab_list[0]); i++) for (i = 0; i < sizeof (grab_list) / sizeof (grab_list[0]); i++)
Hash_Add (grab_tab, &grab_list[i]); Hash_Add (grab_tab, &grab_list[i]);
} }

View file

@ -642,14 +642,14 @@ linker_begin (void)
linker_current_file = dstring_newstr (); linker_current_file = dstring_newstr ();
extern_data_defs = Hash_NewTable (16381, defs_get_key, 0, 0); extern_data_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
defined_data_defs = Hash_NewTable (16381, defs_get_key, 0, 0); defined_data_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
extern_field_defs = Hash_NewTable (16381, defs_get_key, 0, 0); extern_field_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
defined_field_defs = Hash_NewTable (16381, defs_get_key, 0, 0); defined_field_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
extern_type_defs = Hash_NewTable (16381, defs_get_key, 0, 0); extern_type_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
defined_type_defs = Hash_NewTable (16381, defs_get_key, 0, 0); defined_type_defs = Hash_NewTable (16381, defs_get_key, 0, 0, 0);
work_strings = strpool_new (); work_strings = strpool_new ();
work_code = codespace_new (); work_code = codespace_new ();

View file

@ -113,7 +113,8 @@ new_method (type_t *ret_type, param_t *selector, param_t *opt_params)
meth->def = 0; meth->def = 0;
if (!known_methods) if (!known_methods)
known_methods = Hash_NewTable (1021, method_get_key, method_free, 0); known_methods = Hash_NewTable (1021, method_get_key,
method_free, 0, 0);
Hash_Add (known_methods, meth); Hash_Add (known_methods, meth);
return meth; return meth;
@ -230,7 +231,7 @@ methodset_t *
new_methodset (void) new_methodset (void)
{ {
methodset_t *s = malloc (sizeof (*s)); methodset_t *s = malloc (sizeof (*s));
s->tab = Hash_NewTable (31, 0, 0, 0); s->tab = Hash_NewTable (31, 0, 0, 0, 0);
Hash_SetHashCompare (s->tab, methodset_get_hash, methodset_compare); Hash_SetHashCompare (s->tab, methodset_get_hash, methodset_compare);
return s; return s;
} }
@ -455,9 +456,9 @@ selector_index (const char *sel_id)
selector_t *sel = &_sel; selector_t *sel = &_sel;
if (!sel_hash) { if (!sel_hash) {
sel_hash = Hash_NewTable (1021, 0, 0, 0); sel_hash = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (sel_hash, sel_get_hash, sel_compare); Hash_SetHashCompare (sel_hash, sel_get_hash, sel_compare);
sel_index_hash = Hash_NewTable (1021, 0, 0, 0); sel_index_hash = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (sel_index_hash, sel_index_get_hash, Hash_SetHashCompare (sel_index_hash, sel_index_get_hash,
sel_index_compare); sel_index_compare);
} }

View file

@ -139,9 +139,9 @@ opcode_init (void)
Hash_FlushTable (opcode_type_table); Hash_FlushTable (opcode_type_table);
} else { } else {
PR_Opcode_Init (); PR_Opcode_Init ();
opcode_type_table = Hash_NewTable (1021, 0, opcode_free, 0); opcode_type_table = Hash_NewTable (1021, 0, opcode_free, 0, 0);
Hash_SetHashCompare (opcode_type_table, get_hash, compare); Hash_SetHashCompare (opcode_type_table, get_hash, compare);
opcode_void_table = Hash_NewTable (1021, get_key, 0, 0); opcode_void_table = Hash_NewTable (1021, get_key, 0, 0, 0);
} }
for (op = pr_opcodes; op->name; op++) { for (op = pr_opcodes; op->name; op++) {
if (op->min_version > options.code.progsversion) if (op->min_version > options.code.progsversion)

View file

@ -439,10 +439,10 @@ keyword_or_id (char *token)
if (!keyword_tab) { if (!keyword_tab) {
size_t i; size_t i;
keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0); keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0, 0);
qf_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0); qf_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0, 0);
at_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0); at_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0, 0);
obj_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0); obj_keyword_tab = Hash_NewTable (253, keyword_get_key, 0, 0, 0);
#define NUMKEYS(_k) (sizeof (_k) / sizeof (_k[0])) #define NUMKEYS(_k) (sizeof (_k) / sizeof (_k[0]))

View file

@ -247,7 +247,7 @@ init_qf (void)
PR_Init (&pr); PR_Init (&pr);
func_tab = Hash_NewTable (1021, 0, 0, 0); func_tab = Hash_NewTable (1021, 0, 0, 0, 0);
Hash_SetHashCompare (func_tab, func_hash, func_compare); Hash_SetHashCompare (func_tab, func_hash, func_compare);
} }

View file

@ -248,7 +248,7 @@ keyword_or_id (const char *token)
if (!keyword_tab) { if (!keyword_tab) {
size_t i; size_t i;
keyword_tab = Hash_NewTable (1021, keyword_get_key, 0, 0); keyword_tab = Hash_NewTable (1021, keyword_get_key, 0, 0, 0);
for (i = 0; i < sizeof (keywords) / sizeof (keywords[0]); i++) for (i = 0; i < sizeof (keywords) / sizeof (keywords[0]); i++)
Hash_Add (keyword_tab, &keywords[i]); Hash_Add (keyword_tab, &keywords[i]);
} }

View file

@ -63,7 +63,7 @@ strpool_new (void)
{ {
strpool_t *strpool = calloc (1, sizeof (strpool_t)); strpool_t *strpool = calloc (1, sizeof (strpool_t));
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool); strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool, 0);
strpool->size = 1; strpool->size = 1;
strpool->max_size = 16384; strpool->max_size = 16384;
strpool->strings = malloc (strpool->max_size); strpool->strings = malloc (strpool->max_size);
@ -77,7 +77,7 @@ strpool_build (const char *strings, int size)
intptr_t s; intptr_t s;
strpool_t *strpool = malloc (sizeof (strpool_t)); strpool_t *strpool = malloc (sizeof (strpool_t));
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool); strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool, 0);
strpool->size = size + (*strings != 0); strpool->size = size + (*strings != 0);
strpool->max_size = (strpool->size + 16383) & ~16383; strpool->max_size = (strpool->size + 16383) & ~16383;
strpool->strings = malloc (strpool->max_size); strpool->strings = malloc (strpool->max_size);
@ -131,7 +131,7 @@ save_string (const char *str)
{ {
char *s; char *s;
if (!saved_strings) if (!saved_strings)
saved_strings = Hash_NewTable (16381, ss_get_key, 0, 0); saved_strings = Hash_NewTable (16381, ss_get_key, 0, 0, 0);
s = Hash_Find (saved_strings, str); s = Hash_Find (saved_strings, str);
if (s) if (s)
return s; return s;

View file

@ -166,7 +166,7 @@ new_switch_block (void)
switch_block_t *switch_block = malloc (sizeof (switch_block_t)); switch_block_t *switch_block = malloc (sizeof (switch_block_t));
SYS_CHECKMEM (switch_block); SYS_CHECKMEM (switch_block);
switch_block->labels = Hash_NewTable (127, 0, 0, 0); switch_block->labels = Hash_NewTable (127, 0, 0, 0, 0);
Hash_SetHashCompare (switch_block->labels, get_hash, compare); Hash_SetHashCompare (switch_block->labels, get_hash, compare);
switch_block->test = 0; switch_block->test = 0;
return switch_block; return switch_block;

View file

@ -106,7 +106,7 @@ new_symtab (symtab_t *parent, stab_type_e type)
symtab->type = type; symtab->type = type;
if (symtab->type == stab_global) if (symtab->type == stab_global)
tabsize = 1023; tabsize = 1023;
symtab->tab = Hash_NewTable (tabsize, sym_getkey, 0, 0); symtab->tab = Hash_NewTable (tabsize, sym_getkey, 0, 0, 0);
symtab->symtail = &symtab->symbols; symtab->symtail = &symtab->symbols;
return symtab; return symtab;
} }

View file

@ -640,41 +640,47 @@ clear_immediates (void)
Hash_FlushTable (integer_imm_defs); Hash_FlushTable (integer_imm_defs);
Hash_FlushTable (double_imm_defs); Hash_FlushTable (double_imm_defs);
} else { } else {
value_table = Hash_NewTable (16381, 0, 0, 0); value_table = Hash_NewTable (16381, 0, 0, 0, 0);
Hash_SetHashCompare (value_table, value_get_hash, value_compare); Hash_SetHashCompare (value_table, value_get_hash, value_compare);
string_imm_defs = Hash_NewTable (16381, 0, imm_free, &string_imm_defs); string_imm_defs = Hash_NewTable (16381, 0, imm_free,
&string_imm_defs, 0);
Hash_SetHashCompare (string_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (string_imm_defs, imm_get_hash, imm_compare);
float_imm_defs = Hash_NewTable (16381, 0, imm_free, &float_imm_defs); float_imm_defs = Hash_NewTable (16381, 0, imm_free,
&float_imm_defs, 0);
Hash_SetHashCompare (float_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (float_imm_defs, imm_get_hash, imm_compare);
vector_imm_defs = Hash_NewTable (16381, 0, imm_free, &vector_imm_defs); vector_imm_defs = Hash_NewTable (16381, 0, imm_free,
&vector_imm_defs, 0);
Hash_SetHashCompare (vector_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (vector_imm_defs, imm_get_hash, imm_compare);
entity_imm_defs = Hash_NewTable (16381, 0, imm_free, &entity_imm_defs); entity_imm_defs = Hash_NewTable (16381, 0, imm_free,
&entity_imm_defs, 0);
Hash_SetHashCompare (entity_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (entity_imm_defs, imm_get_hash, imm_compare);
field_imm_defs = Hash_NewTable (16381, 0, imm_free, &field_imm_defs); field_imm_defs = Hash_NewTable (16381, 0, imm_free,
&field_imm_defs, 0);
Hash_SetHashCompare (field_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (field_imm_defs, imm_get_hash, imm_compare);
func_imm_defs = Hash_NewTable (16381, 0, imm_free, &func_imm_defs); func_imm_defs = Hash_NewTable (16381, 0, imm_free,
&func_imm_defs, 0);
Hash_SetHashCompare (func_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (func_imm_defs, imm_get_hash, imm_compare);
pointer_imm_defs = pointer_imm_defs = Hash_NewTable (16381, 0, imm_free,
Hash_NewTable (16381, 0, imm_free, &pointer_imm_defs); &pointer_imm_defs, 0);
Hash_SetHashCompare (pointer_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (pointer_imm_defs, imm_get_hash, imm_compare);
quaternion_imm_defs = quaternion_imm_defs = Hash_NewTable (16381, 0, imm_free,
Hash_NewTable (16381, 0, imm_free, &quaternion_imm_defs); &quaternion_imm_defs, 0);
Hash_SetHashCompare (quaternion_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (quaternion_imm_defs, imm_get_hash, imm_compare);
integer_imm_defs = integer_imm_defs = Hash_NewTable (16381, 0, imm_free,
Hash_NewTable (16381, 0, imm_free, &integer_imm_defs); &integer_imm_defs, 0);
Hash_SetHashCompare (integer_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (integer_imm_defs, imm_get_hash, imm_compare);
double_imm_defs = double_imm_defs = Hash_NewTable (16381, 0, imm_free,
Hash_NewTable (16381, 0, imm_free, &double_imm_defs); &double_imm_defs, 0);
Hash_SetHashCompare (double_imm_defs, imm_get_hash, imm_compare); Hash_SetHashCompare (double_imm_defs, imm_get_hash, imm_compare);
} }