From 6b9be0de63f8e031e8400b829fd2dc9b125bb0b4 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 26 Apr 2007 00:11:51 +0200 Subject: [PATCH] rnd-20070426-1-src * fixed(?) very strange bug apparently triggered by memset() when code was cross-compiled with MinGW cross-compiler for Windows XP platform (this only happened when using SDL.dll also self-compiled with MinGW) --- ChangeLog | 5 + src/conftime.h | 2 +- src/files.c | 2 +- src/game_em/init.c | 2 +- src/game_em/sound.c | 4 +- src/libgame/hash.c | 496 +++++++++++++++++++++++++------------------- src/libgame/hash.h | 39 ++-- src/libgame/sound.c | 8 +- 8 files changed, 322 insertions(+), 236 deletions(-) diff --git a/ChangeLog b/ChangeLog index c746ab0c..0cc72e05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-04-26 + * fixed(?) very strange bug apparently triggered by memset() when code + was cross-compiled with MinGW cross-compiler for Windows XP platform + (this only happened when using SDL.dll also self-compiled with MinGW) + 2007-04-19 * added graphics engine directive "border.draw_masked_when_fading" that enables/disables drawing of border mask over screen that is just faded diff --git a/src/conftime.h b/src/conftime.h index 6b7e2e54..b97818ad 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2007-04-25 23:33" +#define COMPILE_DATE_STRING "2007-04-25 23:54" diff --git a/src/files.c b/src/files.c index 57368d34..9a27a0d6 100644 --- a/src/files.c +++ b/src/files.c @@ -9100,7 +9100,7 @@ static struct MusicFileInfo *get_music_file_info_ext(char *basename, int music, /* ---------- music file info found ---------- */ - memset(&tmp_music_file_info, 0, sizeof(struct MusicFileInfo)); + clear_mem(&tmp_music_file_info, sizeof(struct MusicFileInfo)); for (i = 0; token_to_value_ptr[i].token != NULL; i++) { diff --git a/src/game_em/init.c b/src/game_em/init.c index b5a0e033..6e7fe948 100644 --- a/src/game_em/init.c +++ b/src/game_em/init.c @@ -366,7 +366,7 @@ void sound_play(void) #endif - memset(play, 0, sizeof(play)); + clear_mem(play, sizeof(play)); } unsigned int InitEngineRandom_EM(long seed) diff --git a/src/game_em/sound.c b/src/game_em/sound.c index 5aedabb3..c1334cc7 100644 --- a/src/game_em/sound.c +++ b/src/game_em/sound.c @@ -86,7 +86,7 @@ int sound_thread(void) mix_buffer = 0; mix_count = 0; - memset(sound_play, 0, sizeof(sound_play)); /* not playing any sounds */ + clear_mem(sound_play, sizeof(sound_play)); /* not playing any sounds */ for (;;) { @@ -294,7 +294,7 @@ int sound_thread(void) if (mix_count && audio_fd != -1) { /* prepare mix buffer */ - memset(mix_buffer, 0, fragment_size * sizeof(*mix_buffer)); + clear_mem(mix_buffer, fragment_size * sizeof(*mix_buffer)); for (i = 0; i < mix_count; i++) { diff --git a/src/libgame/hash.c b/src/libgame/hash.c index e44313a8..65f4270c 100644 --- a/src/libgame/hash.c +++ b/src/libgame/hash.c @@ -47,210 +47,271 @@ create_hashtable(unsigned int minsize, float maxloadfactor, unsigned int (*hashf) (void*), int (*eqf) (void*,void*)) { - struct hashtable *h; - unsigned int i, size = 1u; - /* Check requested hashtable isn't too large */ - if (minsize > (1u << 31)) return NULL; - /* Enforce size as power of 2 */ - while (size < minsize) size <<= 1; - h = (struct hashtable *)malloc(sizeof(struct hashtable)); - if (NULL == h) return NULL; /*oom*/ - h->table = (struct entry **)malloc(sizeof(struct entry*) * size); - if (NULL == h->table) { free(h); return NULL; } /*oom*/ - - for (i=0; i < size; i++) { h->table[i] = NULL; } - h->tablelength = size; - h->entrycount = 0; - h->hashfn = hashf; - h->eqfn = eqf; - h->loadlimit = (unsigned int) ((float)size * maxloadfactor); - return h; + struct hashtable *h; + unsigned int i, size = 1u; + + /* Check requested hashtable isn't too large */ + if (minsize > (1u << 31)) + return NULL; + + /* Enforce size as power of 2 */ + while (size < minsize) + size <<= 1; + + h = (struct hashtable *)malloc(sizeof(struct hashtable)); + + if (h == NULL) + return NULL; + + h->table = (struct entry **)malloc(sizeof(struct entry*) * size); + + if (h->table == NULL) + { + free(h); + + return NULL; + } + + for (i=0; i < size; i++) + h->table[i] = NULL; + + h->tablelength = size; + h->entrycount = 0; + h->hashfn = hashf; + h->eqfn = eqf; + h->loadlimit = (unsigned int) ((float)size * maxloadfactor); + + return h; } /*****************************************************************************/ static unsigned int hash(struct hashtable *h, void *k) { - /* Aim to protect against poor hash functions by adding logic here - * - logic taken from java 1.4 hashtable source */ - unsigned int i = h->hashfn(k); - i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ - return i; + /* Aim to protect against poor hash functions by adding logic here + * - logic taken from java 1.4 hashtable source */ + + unsigned int i = h->hashfn(k); + + i += ~(i << 9); + i ^= ((i >> 14) | (i << 18)); /* >>> */ + i += (i << 4); + i ^= ((i >> 10) | (i << 22)); /* >>> */ + + return i; } + /*****************************************************************************/ static unsigned int indexFor(unsigned int tablelength, unsigned int hashvalue) { - /* Only works if tablelength == 2^N */ - return (hashvalue & (tablelength - 1u)); + /* Only works if tablelength == 2^N */ + return (hashvalue & (tablelength - 1u)); } /*****************************************************************************/ static int hashtable_expand(struct hashtable *h) { - /* Double the size of the table to accomodate more entries */ - struct entry **newtable; - struct entry *e; - struct entry **pE; - unsigned int newsize, i, index; - /* Check we're not hitting max capacity */ - if (0 == (newsize = (h->tablelength << 1))) return 0; - - newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize); - if (NULL != newtable) + /* Double the size of the table to accomodate more entries */ + struct entry **newtable; + struct entry *e; + struct entry **pE; + unsigned int newsize, i, index; + + /* Check we're not hitting max capacity */ + if (0 == (newsize = (h->tablelength << 1))) + return 0; + + newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize); + + if (newtable != NULL) + { + memset(newtable, 0, newsize * sizeof(struct entry *)); + + /* This algorithm is not 'stable'. ie. it reverses the list + * when it transfers entries between the tables */ + for (i = 0; i < h->tablelength; i++) { - memset(newtable, 0, newsize * sizeof(struct entry *)); - /* This algorithm is not 'stable'. ie. it reverses the list - * when it transfers entries between the tables */ - for (i = 0; i < h->tablelength; i++) { - while (NULL != (e = h->table[i])) { - h->table[i] = e->next; - index = indexFor(newsize,e->h); - e->next = newtable[index]; - newtable[index] = e; - } - } - free(h->table); - h->table = newtable; + while ((e = h->table[i]) != NULL) + { + h->table[i] = e->next; + index = indexFor(newsize,e->h); + e->next = newtable[index]; + newtable[index] = e; + } } - /* Plan B: realloc instead */ - else + + free(h->table); + h->table = newtable; + } + else /* Plan B: realloc instead */ + { + newtable = (struct entry **) + realloc(h->table, newsize * sizeof(struct entry *)); + + if (newtable == NULL) + return 0; + + h->table = newtable; + + for (i = h->tablelength; i < newsize; i++) + newtable[i] = NULL; + + for (i = 0; i < h->tablelength; i++) { - newtable = (struct entry **) - realloc(h->table, newsize * sizeof(struct entry *)); - if (NULL == newtable) return 0; - h->table = newtable; - for (i = h->tablelength; i < newsize; i++) { - newtable[i] = NULL; - } - for (i = 0; i < h->tablelength; i++) { - for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize,e->h); - if (index == i) - { - pE = &(e->next); - } - else - { - *pE = e->next; - e->next = newtable[index]; - newtable[index] = e; - } - } - } + for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) + { + index = indexFor(newsize,e->h); + + if (index == i) + { + pE = &(e->next); + } + else + { + *pE = e->next; + e->next = newtable[index]; + newtable[index] = e; + } + } } - h->tablelength = newsize; - h->loadlimit <<= 1; - return -1; + } + + h->tablelength = newsize; + h->loadlimit <<= 1; + + return -1; } /*****************************************************************************/ unsigned int hashtable_count(struct hashtable *h) { - return h->entrycount; + return h->entrycount; } /*****************************************************************************/ int hashtable_insert(struct hashtable *h, void *k, void *v) { - /* This method allows duplicate keys - but they shouldn't be used */ - unsigned int index; - struct entry *e; - if (++(h->entrycount) > h->loadlimit) - { - /* Ignore the return value. If expand fails, we should - * still try cramming just this value into the existing table - * -- we may not have memory for a larger table, but one more - * element may be ok. Next time we insert, we'll try expanding again.*/ - hashtable_expand(h); - } - e = (struct entry *)malloc(sizeof(struct entry)); - if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); - e->k = k; - e->v = v; - e->next = h->table[index]; - h->table[index] = e; - return -1; + /* This method allows duplicate keys - but they shouldn't be used */ + unsigned int index; + struct entry *e; + + if (++(h->entrycount) > h->loadlimit) + { + /* Ignore the return value. If expand fails, we should + * still try cramming just this value into the existing table + * -- we may not have memory for a larger table, but one more + * element may be ok. Next time we insert, we'll try expanding again.*/ + + hashtable_expand(h); + } + + e = (struct entry *)malloc(sizeof(struct entry)); + + if (e == NULL) + { + --(h->entrycount); + + return 0; + } + + e->h = hash(h,k); + index = indexFor(h->tablelength,e->h); + e->k = k; + e->v = v; + e->next = h->table[index]; + h->table[index] = e; + + return -1; } /*****************************************************************************/ int hashtable_change(struct hashtable *h, void *k, void *v) { - struct entry *e; - unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - e = h->table[index]; - while (NULL != e) + struct entry *e; + unsigned int hashvalue, index; + + hashvalue = hash(h,k); + index = indexFor(h->tablelength,hashvalue); + e = h->table[index]; + + while (e != NULL) + { + /* Check hash value to short circuit heavier comparison */ + if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - free(e->v); - e->v = v; - return -1; - } - e = e->next; + free(e->v); + e->v = v; + + return -1; } - return 0; + + e = e->next; + } + + return 0; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_search(struct hashtable *h, void *k) { - struct entry *e; - unsigned int hashvalue, index; - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hashvalue); - e = h->table[index]; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; - e = e->next; - } - return NULL; + struct entry *e; + unsigned int hashvalue, index; + + hashvalue = hash(h,k); + index = indexFor(h->tablelength,hashvalue); + e = h->table[index]; + + while (e != NULL) + { + /* Check hash value to short circuit heavier comparison */ + if ((hashvalue == e->h) && (h->eqfn(k, e->k))) + return e->v; + + e = e->next; + } + + return NULL; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { - /* TODO: consider compacting the table when the load factor drops enough, - * or provide a 'compact' method. */ + /* TODO: consider compacting the table when the load factor drops enough, + * or provide a 'compact' method. */ + + struct entry *e; + struct entry **pE; + void *v; + unsigned int index = indexFor(h->tablelength,hash(h,k)); - struct entry *e; - struct entry **pE; - void *v; + pE = &(h->table[index]); + e = *pE; - unsigned int index = indexFor(h->tablelength,hash(h,k)); - pE = &(h->table[index]); - e = *pE; - while (NULL != e) + while (e != NULL) + { + if (h->eqfn(k, e->k)) { - if (h->eqfn(k, e->k)) - { - *pE = e->next; - h->entrycount--; - v = e->v; - free(e->k); - free(e); - return v; - } - pE = &(e->next); - e = e->next; + *pE = e->next; + h->entrycount--; + v = e->v; + free(e->k); + free(e); + + return v; } - return NULL; + + pE = &(e->next); + e = e->next; + } + + return NULL; } /*****************************************************************************/ @@ -258,26 +319,29 @@ hashtable_remove(struct hashtable *h, void *k) void hashtable_destroy(struct hashtable *h, int free_values) { - unsigned int i; - struct entry *e, *f; - struct entry **table = h->table; + unsigned int i; + struct entry *e, *f; + struct entry **table = h->table; - for (i = 0; i < h->tablelength; i++) + for (i = 0; i < h->tablelength; i++) + { + e = table[i]; + + while (e != NULL) { - e = table[i]; - while (NULL != e) - { - f = e; - e = e->next; - free(f->k); - if (free_values) - free(f->v); - free(f); - } + f = e; + e = e->next; + free(f->k); + + if (free_values) + free(f->v); + + free(f); } + } - free(h->table); - free(h); + free(h->table); + free(h); } @@ -287,26 +351,33 @@ hashtable_destroy(struct hashtable *h, int free_values) struct hashtable_itr * hashtable_iterator(struct hashtable *h) { - unsigned int i, tablelength; - struct hashtable_itr *itr = (struct hashtable_itr *) - malloc(sizeof(struct hashtable_itr)); - if (NULL == itr) return NULL; - itr->h = h; - itr->e = NULL; - tablelength = h->tablelength; - itr->index = tablelength; - if (0 == h->entrycount) return itr; + unsigned int i, tablelength; + struct hashtable_itr *itr = (struct hashtable_itr *) + malloc(sizeof(struct hashtable_itr)); - for (i = 0; i < tablelength; i++) + if (itr == NULL) + return NULL; + + itr->h = h; + itr->e = NULL; + tablelength = h->tablelength; + itr->index = tablelength; + + if (0 == h->entrycount) + return itr; + + for (i = 0; i < tablelength; i++) + { + if (h->table[i] != NULL) { - if (NULL != h->table[i]) - { - itr->e = h->table[i]; - itr->index = i; - break; - } + itr->e = h->table[i]; + itr->index = i; + + break; } - return itr; + } + + return itr; } /*****************************************************************************/ @@ -315,7 +386,7 @@ hashtable_iterator(struct hashtable *h) void * hashtable_iterator_key(struct hashtable_itr *i) { - return i->e->k; + return i->e->k; } /*****************************************************************************/ @@ -324,7 +395,7 @@ hashtable_iterator_key(struct hashtable_itr *i) void * hashtable_iterator_value(struct hashtable_itr *i) { - return i->e->v; + return i->e->v; } /*****************************************************************************/ @@ -334,33 +405,42 @@ hashtable_iterator_value(struct hashtable_itr *i) int hashtable_iterator_advance(struct hashtable_itr *itr) { - unsigned int j,tablelength; - struct entry **table; - struct entry *next; - if (NULL == itr->e) return 0; /* stupidity check */ + unsigned int j,tablelength; + struct entry **table; + struct entry *next; - next = itr->e->next; - if (NULL != next) - { - itr->e = next; - return -1; - } - tablelength = itr->h->tablelength; - if (tablelength <= (j = ++(itr->index))) - { - itr->e = NULL; - return 0; - } - table = itr->h->table; - while (NULL == (next = table[j])) - { - if (++j >= tablelength) - { - itr->index = tablelength; - return 0; - } - } - itr->index = j; + if (itr->e == NULL) + return 0; /* stupidity check */ + + next = itr->e->next; + if (next != NULL) + { itr->e = next; + return -1; + } + + tablelength = itr->h->tablelength; + if (tablelength <= (j = ++(itr->index))) + { + itr->e = NULL; + + return 0; + } + + table = itr->h->table; + while ((next = table[j]) == NULL) + { + if (++j >= tablelength) + { + itr->index = tablelength; + + return 0; + } + } + + itr->index = j; + itr->e = next; + + return -1; } diff --git a/src/libgame/hash.h b/src/libgame/hash.h index c8836fda..0d20f2c4 100644 --- a/src/libgame/hash.h +++ b/src/libgame/hash.h @@ -98,26 +98,27 @@ /*****************************************************************************/ struct entry { - void *k, *v; - unsigned int h; - struct entry *next; + void *k, *v; + unsigned int h; + struct entry *next; }; -struct hashtable { - unsigned int tablelength; - struct entry **table; - unsigned int entrycount; - unsigned int loadlimit; - unsigned int (*hashfn) (void *k); - int (*eqfn) (void *k1, void *k2); +struct hashtable +{ + unsigned int tablelength; + struct entry **table; + unsigned int entrycount; + unsigned int loadlimit; + unsigned int (*hashfn) (void *k); + int (*eqfn) (void *k1, void *k2); }; /*****************************************************************************/ struct hashtable_itr { - struct hashtable *h; - struct entry *e; - unsigned int index; + struct hashtable *h; + struct entry *e; + unsigned int index; }; @@ -162,7 +163,7 @@ hashtable_insert(struct hashtable *h, void *k, void *v); #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ int fnname (struct hashtable *h, keytype *k, valuetype *v) \ { \ - return hashtable_insert(h,k,v); \ + return hashtable_insert(h,k,v); \ } /***************************************************************************** @@ -181,7 +182,7 @@ hashtable_change(struct hashtable *h, void *k, void *v); #define DEFINE_HASHTABLE_CHANGE(fnname, keytype, valuetype) \ int fnname (struct hashtable *h, keytype *k, valuetype *v) \ { \ - return hashtable_change(h,k,v); \ + return hashtable_change(h,k,v); \ } /***************************************************************************** @@ -199,7 +200,7 @@ hashtable_search(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ - return (valuetype *) (hashtable_search(h,k)); \ + return (valuetype *) (hashtable_search(h,k)); \ } /***************************************************************************** @@ -217,7 +218,7 @@ hashtable_remove(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ valuetype * fnname (struct hashtable *h, keytype *k) \ { \ - return (valuetype *) (hashtable_remove(h,k)); \ + return (valuetype *) (hashtable_remove(h,k)); \ } @@ -256,7 +257,7 @@ hashtable_iterator(struct hashtable *h); extern inline void * hashtable_iterator_key(struct hashtable_itr *i) { - return i->e->k; + return i->e->k; } /*****************************************************************************/ @@ -265,7 +266,7 @@ hashtable_iterator_key(struct hashtable_itr *i) extern inline void * hashtable_iterator_value(struct hashtable_itr *i) { - return i->e->v; + return i->e->v; } /*****************************************************************************/ diff --git a/src/libgame/sound.c b/src/libgame/sound.c index c10575b8..fc187139 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -483,7 +483,7 @@ static void WriteReloadInfoToPipe(char *set_identifier, int type) if (leveldir_current == NULL) /* should never happen */ Error(ERR_EXIT, "leveldir_current == NULL"); - memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ snd_ctrl.active = FALSE; snd_ctrl.state = type; @@ -1147,8 +1147,8 @@ static void Mixer_Main_DSP() max_sample_size = fragment_size / (num_output_channels * sample_bytes); /* first clear the last premixing buffer */ - memset(premix_last_buffer, 0, - max_sample_size * num_output_channels * sizeof(long)); + clear_mem(premix_last_buffer, + max_sample_size * num_output_channels * sizeof(long)); for (i = 0; i < audio.num_channels; i++) { @@ -2171,7 +2171,7 @@ void StopSoundExt(int nr, int state) if (!audio.sound_available) return; - memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ snd_ctrl.active = FALSE; snd_ctrl.nr = nr; -- 2.34.1