diff options
author | 2010-01-11 18:02:38 +0000 | |
---|---|---|
committer | 2010-01-11 18:02:38 +0000 | |
commit | a9c5a5a27e0511163a774525f86cd9b66e497944 (patch) | |
tree | 758e84268350230cbb894d67b017ac1b300c9990 /src/emu/emualloc.c | |
parent | 2441940e7a1bdc7d637f6b01792846ee493291b9 (diff) |
Fixed memory freeing so that is it released in the opposite order
it was originally allocated.
Changed machine->region() to return a pointer to the now-public
region_info class.
Added new member function space() to the device_config, along with
shorter constants to be used (AS_PROGRAM, AS_DATA, AS_IO). With no
parameters, space() returns the first address space, which is
commonly the only space present. Updated a few devices that referenced
the old space[] array to call the new function instead.
Added #define to emualloc to ensure delete can't be freely used.
Diffstat (limited to 'src/emu/emualloc.c')
-rw-r--r-- | src/emu/emualloc.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/src/emu/emualloc.c b/src/emu/emualloc.c index a4af9bd7367..206a8c3fd38 100644 --- a/src/emu/emualloc.c +++ b/src/emu/emualloc.c @@ -54,6 +54,15 @@ const int memory_block_alloc_chunk = 256; /*************************************************************************** + MACROS +***************************************************************************/ + +// enable deletion +#undef delete + + + +/*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -190,7 +199,8 @@ void dump_unfreed_mem(void) -------------------------------------------------*/ resource_pool::resource_pool() - : listlock(osd_lock_alloc()) + : listlock(osd_lock_alloc()), + ordered_head(NULL) { memset(hash, 0, sizeof(hash)); } @@ -217,9 +227,18 @@ resource_pool::~resource_pool() void resource_pool::add(resource_pool_item &item) { osd_lock_acquire(listlock); + + // insert into hash table int hashval = reinterpret_cast<FPTR>(item.ptr) % hash_prime; item.next = hash[hashval]; hash[hashval] = &item; + + // insert into ordered list + item.ordered_next = ordered_head; + if (ordered_head != NULL) + ordered_head->ordered_prev = &item; + ordered_head = &item; + osd_lock_release(listlock); } @@ -244,8 +263,19 @@ void resource_pool::remove(void *ptr) // must match the pointer if ((*scanptr)->ptr == ptr) { + // remove from hash table resource_pool_item *deleteme = *scanptr; *scanptr = deleteme->next; + + // remove from ordered list + if (deleteme->ordered_prev != NULL) + deleteme->ordered_prev->ordered_next = deleteme->ordered_next; + else + ordered_head = deleteme->ordered_next; + if (deleteme->ordered_next != NULL) + deleteme->ordered_next->ordered_prev = deleteme->ordered_prev; + + // delete the object and break delete deleteme; break; } @@ -290,14 +320,13 @@ bool resource_pool::contains(void *_ptrstart, void *_ptrend) osd_lock_acquire(listlock); resource_pool_item *item = NULL; - for (int hashval = 0; hashval < hash_prime; hashval++) - for (item = hash[hashval]; item != NULL; item = item->next) - { - UINT8 *objstart = reinterpret_cast<UINT8 *>(item->ptr); - UINT8 *objend = objstart + item->size; - if (ptrstart >= objstart && ptrend <= objend) - goto found; - } + for (item = ordered_head; item != NULL; item = item->ordered_next) + { + UINT8 *objstart = reinterpret_cast<UINT8 *>(item->ptr); + UINT8 *objend = objstart + item->size; + if (ptrstart >= objstart && ptrend <= objend) + goto found; + } found: osd_lock_release(listlock); @@ -313,13 +342,11 @@ found: void resource_pool::clear() { osd_lock_acquire(listlock); - for (int hashval = 0; hashval < hash_prime; hashval++) - while (hash[hashval] != NULL) - { - resource_pool_item *deleteme = hash[hashval]; - hash[hashval] = deleteme->next; - delete deleteme; - } + + // important: delete in reverse order of adding + while (ordered_head != NULL) + remove(ordered_head->ptr); + osd_lock_release(listlock); } @@ -471,8 +498,9 @@ void memory_entry::report_unfreed() // check for leaked memory UINT32 total = 0; - for (int hashval = 0; hashval < hash_prime; hashval++) - for (memory_entry *entry = hash[hashval]; entry; entry = entry->next) + + for (int hashnum = 0; hashnum < hash_prime; hashnum++) + for (memory_entry *entry = hash[hashnum]; entry != NULL; entry = entry->next) if (entry->file != NULL) { if (total == 0) |