summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2014-01-12 13:27:53 -0200
committershennetsind <ind@henn.et>2014-01-12 13:27:53 -0200
commit209d15e07d52a52c110b01f4bad0b52080a69550 (patch)
tree25323e678f26f09143b7c3c486f5f81ac6379e7f /src/common
parent95f13f3420822111f928ba6079fbc2061bd38c5f (diff)
downloadhercules-209d15e07d52a52c110b01f4bad0b52080a69550.tar.gz
hercules-209d15e07d52a52c110b01f4bad0b52080a69550.tar.bz2
hercules-209d15e07d52a52c110b01f4bad0b52080a69550.tar.xz
hercules-209d15e07d52a52c110b01f4bad0b52080a69550.zip
Fixed ERS Cache sharing
Enforcing cache to match the option condition in order for it to be shared. Special Thanks to Haruna! Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/common')
-rw-r--r--src/common/db.c5
-rw-r--r--src/common/ers.c25
-rw-r--r--src/common/ers.h4
3 files changed, 24 insertions, 10 deletions
diff --git a/src/common/db.c b/src/common/db.c
index ddfb032d4..8c15c0feb 100644
--- a/src/common/db.c
+++ b/src/common/db.c
@@ -2751,9 +2751,10 @@ void* db_data2ptr(DBData *data)
* @see #db_final(void)
*/
void db_init(void) {
- db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_CLEAN);
- db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_CLEAN);
+ db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
+ db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
ers_chunk_size(db_alloc_ers, 50);
+ ers_chunk_size(db_iterator_ers, 10);
DB_COUNTSTAT(db_init);
}
diff --git a/src/common/ers.c b/src/common/ers.c
index a7dad49ab..eb351a988 100644
--- a/src/common/ers.c
+++ b/src/common/ers.c
@@ -45,6 +45,7 @@
#include "../common/cbasetypes.h"
#include "../common/malloc.h" // CREATE, RECREATE, aMalloc, aFree
#include "../common/showmsg.h" // ShowMessage, ShowError, ShowFatalError, CL_BOLD, CL_NORMAL
+#include "../common/nullpo.h"
#include "ers.h"
#ifndef DISABLE_ERS
@@ -88,6 +89,9 @@ typedef struct ers_cache
// Default = ERS_BLOCK_ENTRIES, can be adjusted for performance for individual cache sizes.
unsigned int ChunkSize;
+ // Misc options, some options are shared from the instance
+ enum ERSOptions Options;
+
// Linked list
struct ers_cache *Next, *Prev;
} ers_cache_t;
@@ -123,12 +127,14 @@ static ers_cache_t *CacheList = NULL;
static struct ers_instance_t *InstanceList = NULL;
#endif
-static ers_cache_t *ers_find_cache(unsigned int size)
-{
+/**
+ * @param Options the options from the instance seeking a cache, we use it to give it a cache with matching configuration
+ **/
+static ers_cache_t *ers_find_cache(unsigned int size, enum ERSOptions Options) {
ers_cache_t *cache;
for (cache = CacheList; cache; cache = cache->Next)
- if (cache->ObjectSize == size)
+ if ( cache->ObjectSize == size && cache->Options == ( Options & ERS_CACHE_OPTIONS ) )
return cache;
CREATE(cache, ers_cache_t, 1);
@@ -141,6 +147,7 @@ static ers_cache_t *ers_find_cache(unsigned int size)
cache->UsedObjs = 0;
cache->Max = 0;
cache->ChunkSize = ERS_BLOCK_ENTRIES;
+ cache->Options = (Options & ERS_CACHE_OPTIONS);
if (CacheList == NULL)
{
@@ -239,7 +246,7 @@ static void ers_obj_free_entry(ERS self, void *entry)
return;
}
- if( instance->Options & ERS_OPT_CLEAN )
+ if( instance->Cache->Options & ERS_OPT_CLEAN )
memset((unsigned char*)reuse + sizeof(struct ers_list), 0, instance->Cache->ObjectSize - sizeof(struct ers_list));
reuse->Next = instance->Cache->ReuseList;
@@ -297,9 +304,10 @@ static void ers_obj_destroy(ERS self)
void ers_cache_size(ERS self, unsigned int new_size) {
struct ers_instance_t *instance = (struct ers_instance_t *)self;
- if (instance == NULL) {//change as per piotrhalaczkiewicz comment
- ShowError("ers_cache_size: NULL object, skipping...\n");
- return;
+ nullpo_retv(instance);
+
+ if( !(instance->Cache->Options&ERS_OPT_FLEX_CHUNK) ) {
+ ShowWarning("ers_cache_size: '%s' has adjusted its chunk size to '%d', however ERS_OPT_FLEX_CHUNK is missing!\n",instance->Name,new_size);
}
instance->Cache->ChunkSize = new_size;
@@ -324,7 +332,8 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options)
instance->Name = ( options & ERS_OPT_FREE_NAME ) ? aStrdup(name) : name;
instance->Options = options;
- instance->Cache = ers_find_cache(size);
+ instance->Cache = ers_find_cache(size,instance->Options);
+
instance->Cache->ReferenceCount++;
#ifdef DEBUG
if (InstanceList == NULL) {
diff --git a/src/common/ers.h b/src/common/ers.h
index e63711b81..d74ee02a5 100644
--- a/src/common/ers.h
+++ b/src/common/ers.h
@@ -76,6 +76,10 @@ enum ERSOptions {
ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */
ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */
ERS_OPT_CLEAN = 0x8,/* clears used memory upon ers_free so that its all new to be reused on the next alloc */
+ ERS_OPT_FLEX_CHUNK = 0x10,/* signs that it should look for its own cache given it'll have a dynamic chunk size, so that it doesn't affect the other ERS it'd otherwise be sharing */
+
+ /* Compound, is used to determine whether it should be looking for a cache of matching options */
+ ERS_CACHE_OPTIONS = ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK,
};
/**