From: Pieter Noordhuis Date: Thu, 4 Nov 2010 09:09:30 +0000 (+0100) Subject: Stop using the freelist robj* cache X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/a9b18e54d4e348dd678a396cc8691dd693687de7 Stop using the freelist robj* cache --- diff --git a/src/object.c b/src/object.c index b1eae963..de62f504 100644 --- a/src/object.c +++ b/src/object.c @@ -3,22 +3,12 @@ #include robj *createObject(int type, void *ptr) { - robj *o; - - if (server.vm_enabled) pthread_mutex_lock(&server.obj_freelist_mutex); - if (listLength(server.objfreelist)) { - listNode *head = listFirst(server.objfreelist); - o = listNodeValue(head); - listDelNode(server.objfreelist,head); - if (server.vm_enabled) pthread_mutex_unlock(&server.obj_freelist_mutex); - } else { - if (server.vm_enabled) pthread_mutex_unlock(&server.obj_freelist_mutex); - o = zmalloc(sizeof(*o)); - } + robj *o = zmalloc(sizeof(*o)); o->type = type; o->encoding = REDIS_ENCODING_RAW; o->ptr = ptr; o->refcount = 1; + /* Set the LRU to the current lruclock (minutes resolution). * We do this regardless of the fact VM is active as LRU is also * used for the maxmemory directive when Redis is used as cache. @@ -204,11 +194,7 @@ void decrRefCount(void *obj) { default: redisPanic("Unknown object type"); break; } o->ptr = NULL; /* defensive programming. We'll see NULL in traces. */ - if (server.vm_enabled) pthread_mutex_lock(&server.obj_freelist_mutex); - if (listLength(server.objfreelist) > REDIS_OBJFREELIST_MAX || - !listAddNodeHead(server.objfreelist,o)) - zfree(o); - if (server.vm_enabled) pthread_mutex_unlock(&server.obj_freelist_mutex); + zfree(o); } } diff --git a/src/redis.c b/src/redis.c index 30fe807d..9312ce4b 100644 --- a/src/redis.c +++ b/src/redis.c @@ -616,10 +616,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { while (server.vm_enabled && zmalloc_used_memory() > server.vm_max_memory) { - int retval; - - if (tryFreeOneObjectFromFreelist() == REDIS_OK) continue; - retval = (server.vm_max_threads == 0) ? + int retval = (server.vm_max_threads == 0) ? vmSwapOneObjectBlocking() : vmSwapOneObjectThreaded(); if (retval == REDIS_ERR && !(loops % 300) && @@ -825,7 +822,6 @@ void initServer() { server.clients = listCreate(); server.slaves = listCreate(); server.monitors = listCreate(); - server.objfreelist = listCreate(); createSharedObjects(); server.el = aeCreateEventLoop(); server.db = zmalloc(sizeof(redisDb)*server.dbnum); @@ -1261,27 +1257,6 @@ void monitorCommand(redisClient *c) { /* ============================ Maxmemory directive ======================== */ -/* Try to free one object form the pre-allocated objects free list. - * This is useful under low mem conditions as by default we take 1 million - * free objects allocated. On success REDIS_OK is returned, otherwise - * REDIS_ERR. */ -int tryFreeOneObjectFromFreelist(void) { - robj *o; - - if (server.vm_enabled) pthread_mutex_lock(&server.obj_freelist_mutex); - if (listLength(server.objfreelist)) { - listNode *head = listFirst(server.objfreelist); - o = listNodeValue(head); - listDelNode(server.objfreelist,head); - if (server.vm_enabled) pthread_mutex_unlock(&server.obj_freelist_mutex); - zfree(o); - return REDIS_OK; - } else { - if (server.vm_enabled) pthread_mutex_unlock(&server.obj_freelist_mutex); - return REDIS_ERR; - } -} - /* This function gets called when 'maxmemory' is set on the config file to limit * the max memory used by the server, and we are out of memory. * This function will try to, in order: @@ -1299,9 +1274,6 @@ void freeMemoryIfNeeded(void) { while (server.maxmemory && zmalloc_used_memory() > server.maxmemory) { int j, k, freed = 0; - /* Basic strategy -- remove objects from the free list. */ - if (tryFreeOneObjectFromFreelist() == REDIS_OK) continue; - for (j = 0; j < server.dbnum; j++) { long bestval = 0; /* just to prevent warning */ sds bestkey = NULL; diff --git a/src/redis.h b/src/redis.h index 8818fa05..9d80b0be 100644 --- a/src/redis.h +++ b/src/redis.h @@ -41,7 +41,6 @@ #define REDIS_STATIC_ARGS 8 #define REDIS_DEFAULT_DBNUM 16 #define REDIS_CONFIGLINE_MAX 1024 -#define REDIS_OBJFREELIST_MAX 1000000 /* Max number of objects to cache */ #define REDIS_MAX_SYNC_TIME 60 /* Slave can't take more to sync */ #define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */ #define REDIS_MAX_WRITE_PER_EVENT (1024*64) @@ -366,7 +365,6 @@ struct redisServer { char neterr[ANET_ERR_LEN]; aeEventLoop *el; int cronloops; /* number of times the cron function run */ - list *objfreelist; /* A list of freed objects to avoid malloc() */ time_t lastsave; /* Unix time of last save succeeede */ /* Fields used only for stats */ time_t stat_starttime; /* server start time */ @@ -447,7 +445,6 @@ struct redisServer { list *io_processed; /* List of VM I/O jobs already processed */ list *io_ready_clients; /* Clients ready to be unblocked. All keys loaded */ pthread_mutex_t io_mutex; /* lock to access io_jobs/io_done/io_thread_job */ - pthread_mutex_t obj_freelist_mutex; /* safe redis objects creation/free */ pthread_mutex_t io_swapfile_mutex; /* So we can lseek + write */ pthread_attr_t io_threads_attr; /* attributes for threads creation */ int io_active_threads; /* Number of running I/O threads */ @@ -685,7 +682,6 @@ robj *dupStringObject(robj *o); robj *tryObjectEncoding(robj *o); robj *getDecodedObject(robj *o); size_t stringObjectLen(robj *o); -int tryFreeOneObjectFromFreelist(void); robj *createStringObjectFromLongLong(long long value); robj *createListObject(void); robj *createZiplistObject(void); diff --git a/src/vm.c b/src/vm.c index 1aad95d7..c2e0d9ed 100644 --- a/src/vm.c +++ b/src/vm.c @@ -96,7 +96,6 @@ void vmInit(void) { server.io_processed = listCreate(); server.io_ready_clients = listCreate(); pthread_mutex_init(&server.io_mutex,NULL); - pthread_mutex_init(&server.obj_freelist_mutex,NULL); pthread_mutex_init(&server.io_swapfile_mutex,NULL); server.io_active_threads = 0; if (pipe(pipefds) == -1) {