Changed ERS cache array to use a linked list.
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16744 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
ea9f31706f
commit
c322db5cbf
@ -57,7 +57,7 @@ struct ers_list
|
|||||||
struct ers_list *Next;
|
struct ers_list *Next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct ers_cache
|
||||||
{
|
{
|
||||||
// Allocated object size, including ers_list size
|
// Allocated object size, including ers_list size
|
||||||
unsigned int ObjectSize;
|
unsigned int ObjectSize;
|
||||||
@ -65,9 +65,6 @@ typedef struct
|
|||||||
// Number of ers_instances referencing this
|
// Number of ers_instances referencing this
|
||||||
int ReferenceCount;
|
int ReferenceCount;
|
||||||
|
|
||||||
// Our index in the ERS_Root array
|
|
||||||
unsigned int Index;
|
|
||||||
|
|
||||||
// Reuse linked list
|
// Reuse linked list
|
||||||
struct ers_list *ReuseList;
|
struct ers_list *ReuseList;
|
||||||
|
|
||||||
@ -82,6 +79,9 @@ typedef struct
|
|||||||
|
|
||||||
// Used objects count
|
// Used objects count
|
||||||
unsigned int Used;
|
unsigned int Used;
|
||||||
|
|
||||||
|
// Linked list
|
||||||
|
struct ers_cache *Next, *Prev;
|
||||||
} ers_cache_t;
|
} ers_cache_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -104,16 +104,15 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
// Array containing a pointer for all ers_cache structures
|
// Array containing a pointer for all ers_cache structures
|
||||||
static ers_cache_t *ERS_Root[ERS_ROOT_SIZE];
|
static ers_cache_t *CacheList;
|
||||||
|
|
||||||
static ers_cache_t *ers_find_cache(unsigned int size)
|
static ers_cache_t *ers_find_cache(unsigned int size)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
ers_cache_t *cache;
|
ers_cache_t *cache;
|
||||||
|
|
||||||
for (i = 0; i < ERS_ROOT_SIZE; i++)
|
for (cache = CacheList; cache; cache = cache->Next)
|
||||||
if (ERS_Root[i] != NULL && ERS_Root[i]->ObjectSize == size)
|
if (cache->ObjectSize == size)
|
||||||
return ERS_Root[i];
|
return cache;
|
||||||
|
|
||||||
CREATE(cache, ers_cache_t, 1);
|
CREATE(cache, ers_cache_t, 1);
|
||||||
cache->ObjectSize = size;
|
cache->ObjectSize = size;
|
||||||
@ -124,34 +123,34 @@ static ers_cache_t *ers_find_cache(unsigned int size)
|
|||||||
cache->Used = 0;
|
cache->Used = 0;
|
||||||
cache->Max = 0;
|
cache->Max = 0;
|
||||||
|
|
||||||
for (i = 0; i < ERS_ROOT_SIZE; i++)
|
if (CacheList == NULL)
|
||||||
{
|
{
|
||||||
if (ERS_Root[i] == NULL)
|
CacheList = cache;
|
||||||
{
|
|
||||||
ERS_Root[i] = cache;
|
|
||||||
cache->Index = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
if (i >= ERS_ROOT_SIZE)
|
|
||||||
{
|
{
|
||||||
ShowFatalError("ers_new: too many root objects, increase ERS_ROOT_SIZE.\n"
|
CacheList->Next = cache;
|
||||||
"exiting the program...\n");
|
cache->Prev = CacheList;
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ers_free_cache(ers_cache_t *cache)
|
static void ers_free_cache(ers_cache_t *cache, bool remove)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < cache->Used; i++)
|
for (i = 0; i < cache->Used; i++)
|
||||||
aFree(cache->Blocks[i]);
|
aFree(cache->Blocks[i]);
|
||||||
|
|
||||||
ERS_Root[cache->Index] = NULL;
|
if (cache->Prev)
|
||||||
|
cache->Prev->Next = cache->Next;
|
||||||
|
|
||||||
|
if (cache->Next)
|
||||||
|
cache->Next->Prev = cache->Prev;
|
||||||
|
|
||||||
|
if (CacheList == cache)
|
||||||
|
CacheList = cache->Next;
|
||||||
|
|
||||||
aFree(cache->Blocks);
|
aFree(cache->Blocks);
|
||||||
aFree(cache);
|
aFree(cache);
|
||||||
@ -247,7 +246,7 @@ static void ers_obj_destroy(ERS self)
|
|||||||
ShowWarning("Memory leak detected at ERS '%s', %d objects not freed.\n", instance->Name, instance->Count);
|
ShowWarning("Memory leak detected at ERS '%s', %d objects not freed.\n", instance->Name, instance->Count);
|
||||||
|
|
||||||
if (--instance->Cache->ReferenceCount <= 0)
|
if (--instance->Cache->ReferenceCount <= 0)
|
||||||
ers_free_cache(instance->Cache);
|
ers_free_cache(instance->Cache, true);
|
||||||
|
|
||||||
aFree(instance);
|
aFree(instance);
|
||||||
}
|
}
|
||||||
@ -284,11 +283,10 @@ void ers_report(void)
|
|||||||
|
|
||||||
void ers_force_destroy_all(void)
|
void ers_force_destroy_all(void)
|
||||||
{
|
{
|
||||||
int i;
|
ers_cache_t *cache;
|
||||||
|
|
||||||
for (i = 0; i < ERS_ROOT_SIZE; i++)
|
for (cache = CacheList; cache; cache = cache->Next)
|
||||||
if (ERS_Root[i] != NULL)
|
ers_free_cache(cache, false);
|
||||||
ers_free_cache(ERS_Root[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user