Custom flash heap

This commit is contained in:
John Sully 2019-01-29 18:10:46 -05:00
parent 58404e2e12
commit 0ffcf355fe
58 changed files with 442 additions and 225 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"zmalloc.h": "c"
}
}

View File

@ -119,7 +119,7 @@ ifeq ($(uname_S),DragonFly)
else
# All the other OSes (notably Linux)
FINAL_LDFLAGS+= -rdynamic
FINAL_LIBS+=-ldl -pthread -lrt
FINAL_LIBS+=-ldl -pthread -lrt -lmemkind
endif
endif
endif
@ -164,11 +164,11 @@ endif
REDIS_SERVER_NAME=redis-server
REDIS_SENTINEL_NAME=redis-sentinel
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o storage.o
REDIS_CLI_NAME=redis-cli
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage.o
REDIS_BENCHMARK_NAME=redis-benchmark
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o storage.o
REDIS_CHECK_RDB_NAME=redis-check-rdb
REDIS_CHECK_AOF_NAME=redis-check-aof

View File

@ -146,7 +146,7 @@ void ACLListFreeSds(void *item) {
* If the user with such name already exists NULL is returned. */
user *ACLCreateUser(const char *name, size_t namelen) {
if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL;
user *u = zmalloc(sizeof(*u));
user *u = zmalloc(sizeof(*u), MALLOC_LOCAL);
u->name = sdsnewlen(name,namelen);
u->flags = 0;
u->allowed_subcommands = NULL;
@ -267,7 +267,7 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) {
* this user, we have to allocate the subcommands array. */
if (u->allowed_subcommands == NULL) {
u->allowed_subcommands = zcalloc(USER_COMMAND_BITS_COUNT *
sizeof(sds*));
sizeof(sds*), MALLOC_LOCAL);
}
/* We also need to enlarge the allocation pointing to the

View File

@ -42,7 +42,7 @@ list *listCreate(void)
{
struct list *list;
if ((list = zmalloc(sizeof(*list))) == NULL)
if ((list = zmalloc(sizeof(*list), MALLOC_SHARED)) == NULL)
return NULL;
list->head = list->tail = NULL;
list->len = 0;
@ -89,7 +89,7 @@ list *listAddNodeHead(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
if ((node = zmalloc(sizeof(*node), MALLOC_SHARED)) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
@ -115,7 +115,7 @@ list *listAddNodeTail(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
if ((node = zmalloc(sizeof(*node), MALLOC_SHARED)) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
@ -134,7 +134,7 @@ list *listAddNodeTail(list *list, void *value)
list *listInsertNode(list *list, listNode *old_node, void *value, int after) {
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
if ((node = zmalloc(sizeof(*node), MALLOC_SHARED)) == NULL)
return NULL;
node->value = value;
if (after) {
@ -187,7 +187,7 @@ listIter *listGetIterator(list *list, int direction)
{
listIter *iter;
if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
if ((iter = zmalloc(sizeof(*iter), MALLOC_SHARED)) == NULL) return NULL;
if (direction == AL_START_HEAD)
iter->next = list->head;
else

View File

@ -64,9 +64,9 @@ aeEventLoop *aeCreateEventLoop(int setsize) {
aeEventLoop *eventLoop;
int i;
if ((eventLoop = zmalloc(sizeof(*eventLoop))) == NULL) goto err;
eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize);
eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize);
if ((eventLoop = zmalloc(sizeof(*eventLoop), MALLOC_LOCAL)) == NULL) goto err;
eventLoop->events = zmalloc(sizeof(aeFileEvent)*setsize, MALLOC_LOCAL);
eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize, MALLOC_LOCAL);
if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;
eventLoop->setsize = setsize;
eventLoop->lastTime = time(NULL);
@ -212,7 +212,7 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
long long id = eventLoop->timeEventNextId++;
aeTimeEvent *te;
te = zmalloc(sizeof(*te));
te = zmalloc(sizeof(*te), MALLOC_LOCAL);
if (te == NULL) return AE_ERR;
te->id = id;
aeAddMillisecondsToNow(milliseconds,&te->when_sec,&te->when_ms);

View File

@ -37,10 +37,10 @@ typedef struct aeApiState {
} aeApiState;
static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState));
aeApiState *state = zmalloc(sizeof(aeApiState), MALLOC_LOCAL);
if (!state) return -1;
state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize, MALLOC_LOCAL);
if (!state->events) {
zfree(state);
return -1;

View File

@ -74,7 +74,7 @@ typedef struct aeApiState {
static int aeApiCreate(aeEventLoop *eventLoop) {
int i;
aeApiState *state = zmalloc(sizeof(aeApiState));
aeApiState *state = zmalloc(sizeof(aeApiState), MALLOC_LOCAL);
if (!state) return -1;
state->portfd = port_create();

View File

@ -42,7 +42,7 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState));
if (!state) return -1;
state->events = zmalloc(sizeof(struct kevent)*eventLoop->setsize);
state->events = zmalloc(sizeof(struct kevent)*eventLoop->setsize, MALLOC_LOCAL);
if (!state->events) {
zfree(state);
return -1;

View File

@ -40,7 +40,7 @@ typedef struct aeApiState {
} aeApiState;
static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState));
aeApiState *state = zmalloc(sizeof(aeApiState), MALLOC_LOCAL);
if (!state) return -1;
FD_ZERO(&state->rfds);

View File

@ -143,7 +143,7 @@ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) {
if (len) { /* First block to allocate, or need another block. */
int numblocks;
block = zmalloc(sizeof(*block));
block = zmalloc(sizeof(*block), MALLOC_LOCAL);
block->free = AOF_RW_BUF_BLOCK_SIZE;
block->used = 0;
listAddNodeTail(server.aof_rewrite_buf_blocks,block);
@ -627,7 +627,7 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a
/* In Redis commands are always executed in the context of a client, so in
* order to load the append only file we need to create a fake client. */
struct client *createFakeClient(void) {
struct client *c = zmalloc(sizeof(*c));
struct client *c = zmalloc(sizeof(*c), MALLOC_LOCAL);
selectDb(c,0);
c->fd = -1;
@ -752,7 +752,7 @@ int loadAppendOnlyFile(char *filename) {
argc = atoi(buf+1);
if (argc < 1) goto fmterr;
argv = zmalloc(sizeof(robj*)*argc);
argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
fakeClient->argc = argc;
fakeClient->argv = argv;

View File

@ -129,7 +129,7 @@ void bioInit(void) {
}
void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) {
struct bio_job *job = zmalloc(sizeof(*job));
struct bio_job *job = zmalloc(sizeof(*job), MALLOC_LOCAL);
job->time = time(NULL);
job->arg1 = arg1;

View File

@ -621,9 +621,9 @@ void bitopCommand(client *c) {
/* Lookup keys, and store pointers to the string objects into an array. */
numkeys = c->argc - 3;
src = zmalloc(sizeof(unsigned char*) * numkeys);
len = zmalloc(sizeof(long) * numkeys);
objects = zmalloc(sizeof(robj*) * numkeys);
src = zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL);
len = zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL);
objects = zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL);
for (j = 0; j < numkeys; j++) {
o = lookupKeyRead(c->db,c->argv[j+3]);
/* Handle non-existing keys as empty strings. */

View File

@ -513,7 +513,7 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo
* is NULL for lists and sorted sets, or the stream ID for streams. */
void *key_data = NULL;
if (btype == BLOCKED_STREAM) {
key_data = zmalloc(sizeof(streamID));
key_data = zmalloc(sizeof(streamID), MALLOC_SHARED);
memcpy(key_data,ids+j,sizeof(streamID));
}
@ -596,7 +596,7 @@ void signalKeyAsReady(redisDb *db, robj *key) {
if (dictFind(db->ready_keys,key) != NULL) return;
/* Ok, we need to queue this key into server.ready_keys. */
rl = zmalloc(sizeof(*rl));
rl = zmalloc(sizeof(*rl), MALLOC_SHARED);
rl->key = key;
rl->db = db;
incrRefCount(key);

View File

@ -119,7 +119,7 @@ int clusterLoadConfig(char *filename) {
*
* To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */
maxline = 1024+CLUSTER_SLOTS*128;
line = zmalloc(maxline);
line = zmalloc(maxline, MALLOC_LOCAL);
while(fgets(line,maxline,fp) != NULL) {
int argc;
sds *argv;
@ -429,7 +429,7 @@ void clusterUpdateMyselfFlags(void) {
void clusterInit(void) {
int saveconf = 0;
server.cluster = zmalloc(sizeof(clusterState));
server.cluster = zmalloc(sizeof(clusterState), MALLOC_LOCAL);
server.cluster->myself = NULL;
server.cluster->currentEpoch = 0;
server.cluster->state = CLUSTER_FAIL;
@ -587,7 +587,7 @@ void clusterReset(int hard) {
* -------------------------------------------------------------------------- */
clusterLink *createClusterLink(clusterNode *node) {
clusterLink *link = zmalloc(sizeof(*link));
clusterLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL);
link->ctime = mstime();
link->sndbuf = sdsempty();
link->rcvbuf = sdsempty();
@ -692,7 +692,7 @@ unsigned int keyHashSlot(char *key, int keylen) {
* The node is created and returned to the user, but it is not automatically
* added to the nodes hash table. */
clusterNode *createClusterNode(char *nodename, int flags) {
clusterNode *node = zmalloc(sizeof(*node));
clusterNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL);
if (nodename)
memcpy(node->name, nodename, CLUSTER_NAMELEN);
@ -749,7 +749,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) {
}
/* Otherwise create a new report. */
fr = zmalloc(sizeof(*fr));
fr = zmalloc(sizeof(*fr), MALLOC_LOCAL);
fr->node = sender;
fr->time = mstime();
listAddNodeTail(l,fr);
@ -2401,7 +2401,7 @@ void clusterSendPing(clusterLink *link, int type) {
/* Note: clusterBuildMessageHdr() expects the buffer to be always at least
* sizeof(clusterMsg) or more. */
if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg);
buf = zcalloc(totlen);
buf = zcalloc(totlen, MALLOC_LOCAL);
hdr = (clusterMsg*) buf;
/* Populate the header. */
@ -2538,7 +2538,7 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) {
if (totlen < sizeof(buf)) {
payload = buf;
} else {
payload = zmalloc(totlen);
payload = zmalloc(totlen, MALLOC_LOCAL);
memcpy(payload,hdr,sizeof(*hdr));
hdr = (clusterMsg*) payload;
}
@ -2607,7 +2607,7 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type,
if (totlen < sizeof(buf)) {
heapbuf = buf;
} else {
heapbuf = zmalloc(totlen);
heapbuf = zmalloc(totlen, MALLOC_LOCAL);
memcpy(heapbuf,hdr,sizeof(*hdr));
hdr = (clusterMsg*) heapbuf;
}
@ -4277,7 +4277,7 @@ NULL
/* CLUSTER ADDSLOTS <slot> [slot] ... */
/* CLUSTER DELSLOTS <slot> [slot] ... */
int j, slot;
unsigned char *slots = zmalloc(CLUSTER_SLOTS);
unsigned char *slots = zmalloc(CLUSTER_SLOTS, MALLOC_LOCAL);
int del = !strcasecmp(c->argv[1]->ptr,"delslots");
memset(slots,0,CLUSTER_SLOTS);
@ -4546,7 +4546,7 @@ NULL
unsigned int keys_in_slot = countKeysInSlot(slot);
if (maxkeys > keys_in_slot) maxkeys = keys_in_slot;
keys = zmalloc(sizeof(robj*)*maxkeys);
keys = zmalloc(sizeof(robj*)*maxkeys, MALLOC_LOCAL);
numkeys = getKeysInSlot(slot, keys, maxkeys);
addReplyArrayLen(c,numkeys);
for (j = 0; j < numkeys; j++) {
@ -5008,7 +5008,7 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti
}
/* Add to the cache and return it to the caller. */
cs = zmalloc(sizeof(*cs));
cs = zmalloc(sizeof(*cs), MALLOC_LOCAL);
cs->fd = fd;
cs->last_dbid = -1;
cs->last_use_time = server.unixtime;
@ -5256,7 +5256,7 @@ try_again:
* to propagate the MIGRATE as a DEL command (if no COPY option was given).
* We allocate num_keys+1 because the additional argument is for "DEL"
* command name itself. */
if (!copy) newargv = zmalloc(sizeof(robj*)*(num_keys+1));
if (!copy) newargv = zmalloc(sizeof(robj*)*(num_keys+1), MALLOC_LOCAL);
for (j = 0; j < num_keys; j++) {
if (syncReadLine(cs->fd, buf2, sizeof(buf2), timeout) <= 0) {

View File

@ -159,8 +159,8 @@ void queueLoadModule(sds path, sds *argv, int argc) {
int i;
struct moduleLoadQueueEntry *loadmod;
loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry));
loadmod->argv = zmalloc(sizeof(robj*)*argc);
loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL);
loadmod->argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
loadmod->path = sdsnew(path);
loadmod->argc = argc;
for (i = 0; i < argc; i++) {
@ -1672,7 +1672,7 @@ void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char *
* If the old file does not exist at all, an empty state is returned. */
struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
FILE *fp = fopen(path,"r");
struct rewriteConfigState *state = zmalloc(sizeof(*state));
struct rewriteConfigState *state = zmalloc(sizeof(*state), MALLOC_LOCAL);
char buf[CONFIG_MAX_LINE+1];
int linenum = -1;

View File

@ -1200,7 +1200,7 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in
last = cmd->lastkey;
if (last < 0) last = argc+last;
keys = zmalloc(sizeof(int)*((last - cmd->firstkey)+1));
keys = zmalloc(sizeof(int)*((last - cmd->firstkey)+1), MALLOC_SHARED);
for (j = cmd->firstkey; j <= last; j += cmd->keystep) {
if (j >= argc) {
/* Modules commands, and standard commands with a not fixed number
@ -1267,7 +1267,7 @@ int *zunionInterGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *nu
/* Keys in z{union,inter}store come from two places:
* argv[1] = storage key,
* argv[3...n] = keys to intersect */
keys = zmalloc(sizeof(int)*(num+1));
keys = zmalloc(sizeof(int)*(num+1), MALLOC_SHARED);
/* Add all key positions for argv[3...n] to keys[] */
for (i = 0; i < num; i++) keys[i] = 3+i;
@ -1293,7 +1293,7 @@ int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
return NULL;
}
keys = zmalloc(sizeof(int)*num);
keys = zmalloc(sizeof(int)*num, MALLOC_SHARED);
*numkeys = num;
/* Add all key positions for argv[3...n] to keys[] */
@ -1314,7 +1314,7 @@ int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
UNUSED(cmd);
num = 0;
keys = zmalloc(sizeof(int)*2); /* Alloc 2 places for the worst case. */
keys = zmalloc(sizeof(int)*2, MALLOC_SHARED); /* Alloc 2 places for the worst case. */
keys[num++] = 1; /* <sort-key> is always present. */
@ -1372,7 +1372,7 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
}
}
keys = zmalloc(sizeof(int)*num);
keys = zmalloc(sizeof(int)*num, MALLOC_SHARED);
for (i = 0; i < num; i++) keys[i] = first+i;
*numkeys = num;
return keys;
@ -1405,7 +1405,7 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
* argv[1] = key,
* argv[5...n] = stored key if present
*/
keys = zmalloc(sizeof(int) * num);
keys = zmalloc(sizeof(int) * num, MALLOC_SHARED);
/* Add all key positions to keys[] */
keys[0] = 1;
@ -1454,7 +1454,7 @@ int *xreadGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys)
num /= 2; /* We have half the keys as there are arguments because
there are also the IDs, one per key. */
keys = zmalloc(sizeof(int) * num);
keys = zmalloc(sizeof(int) * num, MALLOC_SHARED);
for (i = streams_pos+1; i < argc-num; i++) keys[i-streams_pos-1] = i;
*numkeys = num;
return keys;
@ -1471,7 +1471,7 @@ void slotToKeyUpdateKey(robj *key, int add) {
size_t keylen = sdslen(key->ptr);
server.cluster->slots_keys_count[hashslot] += add ? 1 : -1;
if (keylen+2 > 64) indexed = zmalloc(keylen+2);
if (keylen+2 > 64) indexed = zmalloc(keylen+2, MALLOC_SHARED);
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
memcpy(indexed+2,key->ptr,keylen);

View File

@ -345,7 +345,7 @@ NULL
restartServer(flags,delay);
addReplyError(c,"failed to restart the server. Check server logs.");
} else if (!strcasecmp(c->argv[1]->ptr,"oom")) {
void *ptr = zmalloc(ULONG_MAX); /* Should trigger an out of memory. */
void *ptr = zmalloc(ULONG_MAX, MALLOC_LOCAL); /* Should trigger an out of memory. */
zfree(ptr);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"assert")) {

View File

@ -72,8 +72,8 @@ void* activeDefragAlloc(void *ptr) {
/* move this allocation to a new allocation.
* make sure not to use the thread cache. so that we don't get back the same
* pointers we try to free */
size = zmalloc_size(ptr);
newptr = zmalloc_no_tcache(size);
size = zmalloc_size(ptr, MALLOC_LOCAL);
newptr = zmalloc_no_tcache(size, MALLOC_LOCAL);
memcpy(newptr, ptr, size);
zfree_no_tcache(ptr);
return newptr;

View File

@ -111,7 +111,7 @@ static void _dictReset(dictht *ht)
dict *dictCreate(dictType *type,
void *privDataPtr)
{
dict *d = zmalloc(sizeof(*d));
dict *d = zmalloc(sizeof(*d), MALLOC_SHARED);
_dictInit(d,type,privDataPtr);
return d;
@ -160,7 +160,7 @@ int dictExpand(dict *d, unsigned long size)
/* Allocate the new hash table and initialize all pointers to NULL */
n.size = realsize;
n.sizemask = realsize-1;
n.table = zcalloc(realsize*sizeof(dictEntry*));
n.table = zcalloc(realsize*sizeof(dictEntry*), MALLOC_SHARED);
n.used = 0;
/* Is this the first initialization? If so it's not really a rehashing
@ -307,7 +307,7 @@ dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing)
* system it is more likely that recently added entries are accessed
* more frequently. */
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
entry = zmalloc(sizeof(*entry));
entry = zmalloc(sizeof(*entry), MALLOC_SHARED);
entry->next = ht->table[index];
ht->table[index] = entry;
ht->used++;
@ -541,7 +541,7 @@ long long dictFingerprint(dict *d) {
dictIterator *dictGetIterator(dict *d)
{
dictIterator *iter = zmalloc(sizeof(*iter));
dictIterator *iter = zmalloc(sizeof(*iter), MALLOC_LOCAL);
iter->d = d;
iter->table = 0;

View File

@ -140,7 +140,7 @@ void evictionPoolAlloc(void) {
struct evictionPoolEntry *ep;
int j;
ep = zmalloc(sizeof(*ep)*EVPOOL_SIZE);
ep = zmalloc(sizeof(*ep)*EVPOOL_SIZE, MALLOC_LOCAL);
for (j = 0; j < EVPOOL_SIZE; j++) {
ep[j].idle = 0;
ep[j].key = NULL;

View File

@ -51,7 +51,7 @@ int zslValueLteMax(double value, zrangespec *spec);
/* Create a new array of geoPoints. */
geoArray *geoArrayCreate(void) {
geoArray *ga = zmalloc(sizeof(*ga));
geoArray *ga = zmalloc(sizeof(*ga), MALLOC_SHARED);
/* It gets allocated on first geoArrayAppend() call. */
ga->array = NULL;
ga->buckets = 0;
@ -413,7 +413,7 @@ void geoaddCommand(client *c) {
int elements = (c->argc - 2) / 3;
int argc = 2+elements*2; /* ZADD key score ele ... */
robj **argv = zcalloc(argc*sizeof(robj*));
robj **argv = zcalloc(argc*sizeof(robj*), MALLOC_LOCAL);
argv[0] = createRawStringObject("zadd",4);
argv[1] = c->argv[1]; /* key */
incrRefCount(argv[1]);

View File

@ -95,7 +95,7 @@ static void _intsetSet(intset *is, int pos, int64_t value) {
/* Create an empty intset. */
intset *intsetNew(void) {
intset *is = zmalloc(sizeof(intset));
intset *is = zmalloc(sizeof(intset), MALLOC_SHARED);
is->encoding = intrev32ifbe(INTSET_ENC_INT16);
is->length = 0;
return is;

View File

@ -102,7 +102,7 @@ void latencyAddSample(char *event, mstime_t latency) {
/* Create the time series if it does not exist. */
if (ts == NULL) {
ts = zmalloc(sizeof(*ts));
ts = zmalloc(sizeof(*ts), MALLOC_SHARED);
ts->idx = 0;
ts->max = 0;
memset(ts->samples,0,sizeof(ts->samples));

View File

@ -39,7 +39,7 @@
#ifndef LISTPACK_ALLOC_H
#define LISTPACK_ALLOC_H
#include "zmalloc.h"
#define lp_malloc zmalloc
#define lp_malloc(size) zmalloc(size, MALLOC_SHARED)
#define lp_realloc zrealloc
#define lp_free zfree
#endif

View File

@ -71,10 +71,10 @@ void lwTranslatePixelsGroup(int byte, char *output) {
/* Allocate and return a new canvas of the specified size. */
lwCanvas *lwCreateCanvas(int width, int height) {
lwCanvas *canvas = zmalloc(sizeof(*canvas));
lwCanvas *canvas = zmalloc(sizeof(*canvas), MALLOC_SHARED);
canvas->width = width;
canvas->height = height;
canvas->pixels = zmalloc(width*height);
canvas->pixels = zmalloc(width*height, MALLOC_SHARED);
memset(canvas->pixels,0,width*height);
return canvas;
}

View File

@ -280,7 +280,7 @@ void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d);
* and in general is taken into account as memory allocated by Redis.
* You should avoid using malloc(). */
void *RM_Alloc(size_t bytes) {
return zmalloc(bytes);
return zmalloc(bytes, MALLOC_LOCAL);
}
/* Use like calloc(). Memory allocated with this function is reported in
@ -288,7 +288,7 @@ void *RM_Alloc(size_t bytes) {
* and in general is taken into account as memory allocated by Redis.
* You should avoid using calloc() directly. */
void *RM_Calloc(size_t nmemb, size_t size) {
return zcalloc(nmemb*size);
return zcalloc(nmemb*size, MALLOC_LOCAL);
}
/* Use like realloc() for memory obtained with RedisModule_Alloc(). */
@ -354,7 +354,7 @@ void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) {
if (left < bytes) {
size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE;
if (blocksize < bytes) blocksize = bytes;
b = zmalloc(sizeof(*b) + blocksize);
b = zmalloc(sizeof(*b) + blocksize, MALLOC_LOCAL);
b->size = blocksize;
b->used = 0;
b->next = ctx->pa_head;
@ -668,10 +668,10 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
*
* Note that we use the Redis command table 'getkeys_proc' in order to
* pass a reference to the command proxy structure. */
cp = zmalloc(sizeof(*cp));
cp = zmalloc(sizeof(*cp), MALLOC_LOCAL);
cp->module = ctx->module;
cp->func = cmdfunc;
cp->rediscmd = zmalloc(sizeof(*rediscmd));
cp->rediscmd = zmalloc(sizeof(*rediscmd), MALLOC_LOCAL);
cp->rediscmd->name = cmdname;
cp->rediscmd->proc = RedisModuleCommandDispatcher;
cp->rediscmd->arity = -1;
@ -695,7 +695,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
RedisModule *module;
if (ctx->module != NULL) return;
module = zmalloc(sizeof(*module));
module = zmalloc(sizeof(*module), MALLOC_LOCAL);
module->name = sdsnew((char*)name);
module->ver = ver;
module->apiver = apiver;
@ -1470,7 +1470,7 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
}
/* Setup the key handle. */
kp = zmalloc(sizeof(*kp));
kp = zmalloc(sizeof(*kp), MALLOC_LOCAL);
kp->ctx = ctx;
kp->db = ctx->client->db;
kp->key = keyname;
@ -2392,7 +2392,7 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) {
* is processed as needed. Initially we just make sure to set the right
* reply type, which is extremely cheap to do. */
RedisModuleCallReply *moduleCreateCallReplyFromProto(RedisModuleCtx *ctx, sds proto) {
RedisModuleCallReply *reply = zmalloc(sizeof(*reply));
RedisModuleCallReply *reply = zmalloc(sizeof(*reply), MALLOC_LOCAL);
reply->ctx = ctx;
reply->proto = proto;
reply->protolen = sdslen(proto);
@ -2482,7 +2482,7 @@ void moduleParseCallReply_Array(RedisModuleCallReply *reply) {
return;
}
reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen);
reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen, MALLOC_LOCAL);
reply->len = arraylen;
for (j = 0; j < arraylen; j++) {
RedisModuleCallReply *ele = reply->val.array+j;
@ -2996,7 +2996,7 @@ moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver,
moduleTypeFreeFunc free;
} *tms = (struct typemethods*) typemethods_ptr;
moduleType *mt = zcalloc(sizeof(*mt));
moduleType *mt = zcalloc(sizeof(*mt), MALLOC_LOCAL);
mt->id = id;
mt->module = ctx->module;
mt->rdb_load = tms->rdb_load;
@ -3393,7 +3393,7 @@ void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) {
RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) {
if (io->ctx) return io->ctx; /* Can't have more than one... */
RedisModuleCtx ctxtemplate = REDISMODULE_CTX_INIT;
io->ctx = zmalloc(sizeof(RedisModuleCtx));
io->ctx = zmalloc(sizeof(RedisModuleCtx), MALLOC_LOCAL);
*(io->ctx) = ctxtemplate;
io->ctx->module = io->type->module;
io->ctx->client = NULL;
@ -3530,7 +3530,7 @@ RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc
int islua = c->flags & CLIENT_LUA;
int ismulti = c->flags & CLIENT_MULTI;
c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient));
c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient), MALLOC_LOCAL);
RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
/* We need to handle the invalid operation of calling modules blocking
@ -3780,7 +3780,7 @@ int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) {
* TODO: thread safe contexts do not inherit the blocked client
* selected database. */
RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) {
RedisModuleCtx *ctx = zmalloc(sizeof(*ctx));
RedisModuleCtx *ctx = zmalloc(sizeof(*ctx), MALLOC_LOCAL);
RedisModuleCtx empty = REDISMODULE_CTX_INIT;
memcpy(ctx,&empty,sizeof(empty));
if (bc) {
@ -3880,7 +3880,7 @@ void moduleReleaseGIL(void) {
* See https://redis.io/topics/notifications for more information.
*/
int RM_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc callback) {
RedisModuleKeyspaceSubscriber *sub = zmalloc(sizeof(*sub));
RedisModuleKeyspaceSubscriber *sub = zmalloc(sizeof(*sub), MALLOC_LOCAL);
sub->module = ctx->module;
sub->event_mask = types;
sub->notify_callback = callback;
@ -4017,7 +4017,7 @@ void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisM
/* Not found, let's add it. */
if (callback) {
r = zmalloc(sizeof(*r));
r = zmalloc(sizeof(*r), MALLOC_LOCAL);
r->module_id = module_id;
r->module = ctx->module;
r->callback = callback;
@ -4069,14 +4069,14 @@ char **RM_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes) {
if (!server.cluster_enabled) return NULL;
size_t count = dictSize(server.cluster->nodes);
char **ids = zmalloc((count+1)*REDISMODULE_NODE_ID_LEN);
char **ids = zmalloc((count+1)*REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL);
dictIterator *di = dictGetIterator(server.cluster->nodes);
dictEntry *de;
int j = 0;
while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de);
if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue;
ids[j] = zmalloc(REDISMODULE_NODE_ID_LEN);
ids[j] = zmalloc(REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL);
memcpy(ids[j],node->name,REDISMODULE_NODE_ID_LEN);
j++;
}
@ -4269,7 +4269,7 @@ int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *client
* the specified function using `data` as argument. The returned timer ID can be
* used to get information from the timer or to stop it before it fires. */
RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data) {
RedisModuleTimer *timer = zmalloc(sizeof(*timer));
RedisModuleTimer *timer = zmalloc(sizeof(*timer), MALLOC_LOCAL);
timer->module = ctx->module;
timer->callback = callback;
timer->data = data;
@ -4367,7 +4367,7 @@ int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remain
* Next / Prev dictionary iterator calls.
*/
RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) {
struct RedisModuleDict *d = zmalloc(sizeof(*d));
struct RedisModuleDict *d = zmalloc(sizeof(*d), MALLOC_LOCAL);
d->rax = raxNew();
if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d);
return d;
@ -4467,7 +4467,7 @@ int RM_DictDel(RedisModuleDict *d, RedisModuleString *key, void *oldval) {
* REDISMODULE_ERR at the first call, otherwise they'll produce elements.
*/
RedisModuleDictIter *RM_DictIteratorStartC(RedisModuleDict *d, const char *op, void *key, size_t keylen) {
RedisModuleDictIter *di = zmalloc(sizeof(*di));
RedisModuleDictIter *di = zmalloc(sizeof(*di), MALLOC_LOCAL);
di->dict = d;
raxStart(&di->ri,d->rax);
raxSeek(&di->ri,op,key,keylen);

View File

@ -63,7 +63,7 @@ void queueMultiCommand(client *c) {
mc = c->mstate.commands+c->mstate.count;
mc->cmd = c->cmd;
mc->argc = c->argc;
mc->argv = zmalloc(sizeof(robj*)*c->argc);
mc->argv = zmalloc(sizeof(robj*)*c->argc, MALLOC_LOCAL);
memcpy(mc->argv,c->argv,sizeof(robj*)*c->argc);
for (j = 0; j < c->argc; j++)
incrRefCount(mc->argv[j]);
@ -253,7 +253,7 @@ void watchForKey(client *c, robj *key) {
}
listAddNodeTail(clients,c);
/* Add the new key to the list of keys watched by this client */
wk = zmalloc(sizeof(*wk));
wk = zmalloc(sizeof(*wk), MALLOC_SHARED);
wk->key = key;
wk->db = c->db;
incrRefCount(key);

View File

@ -57,7 +57,7 @@ size_t getStringObjectSdsUsedMemory(robj *o) {
/* Client.reply list dup and free methods. */
void *dupClientReplyValue(void *o) {
clientReplyBlock *old = o;
clientReplyBlock *buf = zmalloc(sizeof(clientReplyBlock) + old->size);
clientReplyBlock *buf = zmalloc(sizeof(clientReplyBlock) + old->size, MALLOC_LOCAL);
memcpy(buf, o, sizeof(clientReplyBlock) + old->size);
return buf;
}
@ -83,7 +83,7 @@ void linkClient(client *c) {
}
client *createClient(int fd) {
client *c = zmalloc(sizeof(client));
client *c = zmalloc(sizeof(client), MALLOC_LOCAL);
/* passing -1 as fd it is possible to create a non connected client.
* This is useful since all the commands needs to be executed
@ -281,7 +281,7 @@ void _addReplyProtoToList(client *c, const char *s, size_t len) {
/* Create a new node, make sure it is allocated to at
* least PROTO_REPLY_CHUNK_BYTES */
size_t size = len < PROTO_REPLY_CHUNK_BYTES? PROTO_REPLY_CHUNK_BYTES: len;
tail = zmalloc(size + sizeof(clientReplyBlock));
tail = zmalloc(size + sizeof(clientReplyBlock), MALLOC_LOCAL);
/* take over the allocation's internal fragmentation */
tail->size = zmalloc_usable(tail) - sizeof(clientReplyBlock);
tail->used = len;
@ -460,7 +460,7 @@ void setDeferredAggregateLen(client *c, void *node, long length, char prefix) {
listDelNode(c->reply,ln);
} else {
/* Create a new node */
clientReplyBlock *buf = zmalloc(lenstr_len + sizeof(clientReplyBlock));
clientReplyBlock *buf = zmalloc(lenstr_len + sizeof(clientReplyBlock), MALLOC_LOCAL);
/* Take over the allocation's internal fragmentation */
buf->size = zmalloc_usable(buf) - sizeof(clientReplyBlock);
buf->used = lenstr_len;
@ -1333,7 +1333,7 @@ int processInlineBuffer(client *c) {
/* Setup argv array on client structure */
if (argc) {
if (c->argv) zfree(c->argv);
c->argv = zmalloc(sizeof(robj*)*argc);
c->argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
}
/* Create redis objects for all arguments. */
@ -1345,7 +1345,7 @@ int processInlineBuffer(client *c) {
sdsfree(argv[j]);
}
}
zfree(argv);
sds_free(argv);
return C_OK;
}
@ -1431,7 +1431,7 @@ int processMultibulkBuffer(client *c) {
/* Setup argv array on client structure */
if (c->argv) zfree(c->argv);
c->argv = zmalloc(sizeof(robj*)*c->multibulklen);
c->argv = zmalloc(sizeof(robj*)*c->multibulklen, MALLOC_LOCAL);
}
serverAssertWithInfo(c,NULL,c->multibulklen > 0);
@ -2123,7 +2123,7 @@ void rewriteClientCommandVector(client *c, int argc, ...) {
int j;
robj **argv; /* The new argument vector */
argv = zmalloc(sizeof(robj*)*argc);
argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
va_start(ap,argc);
for (j = 0; j < argc; j++) {
robj *a;

View File

@ -39,7 +39,7 @@
/* ===================== Creation and parsing of objects ==================== */
robj *createObject(int type, void *ptr) {
robj *o = zmalloc(sizeof(*o));
robj *o = salloc_obj(); //zmalloc(sizeof(*o), MALLOC_SHARED);
o->type = type;
o->encoding = OBJ_ENCODING_RAW;
o->ptr = ptr;
@ -82,7 +82,7 @@ robj *createRawStringObject(const char *ptr, size_t len) {
* an object where the sds string is actually an unmodifiable string
* allocated in the same chunk as the object itself. */
robj *createEmbeddedStringObject(const char *ptr, size_t len) {
robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1);
robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1, MALLOC_SHARED);
struct sdshdr8 *sh = (void*)(o+1);
o->type = OBJ_STRING;
@ -247,7 +247,7 @@ robj *createHashObject(void) {
}
robj *createZsetObject(void) {
zset *zs = zmalloc(sizeof(*zs));
zset *zs = zmalloc(sizeof(*zs), MALLOC_SHARED);
robj *o;
zs->dict = dictCreate(&zsetDictType,NULL);
@ -272,7 +272,7 @@ robj *createStreamObject(void) {
}
robj *createModuleObject(moduleType *mt, void *value) {
moduleValue *mv = zmalloc(sizeof(*mv));
moduleValue *mv = zmalloc(sizeof(*mv), MALLOC_SHARED);
mv->type = mt;
mv->value = value;
return createObject(OBJ_MODULE,mv);
@ -362,7 +362,10 @@ void decrRefCount(robj *o) {
case OBJ_STREAM: freeStreamObject(o); break;
default: serverPanic("Unknown object type"); break;
}
zfree(o);
if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_EMBSTR)
zfree(o);
else
sfree_obj(o);
} else {
if (o->refcount <= 0) serverPanic("decrRefCount against refcount <= 0");
if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount--;
@ -945,7 +948,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
size_t mem_total = 0;
size_t mem = 0;
size_t zmalloc_used = zmalloc_used_memory();
struct redisMemOverhead *mh = zcalloc(sizeof(*mh));
struct redisMemOverhead *mh = zcalloc(sizeof(*mh), MALLOC_LOCAL);
mh->total_allocated = zmalloc_used;
mh->startup_allocated = server.initial_memory_usage;

View File

@ -209,7 +209,7 @@ int pubsubSubscribePattern(client *c, robj *pattern) {
pubsubPattern *pat;
listAddNodeTail(c->pubsub_patterns,pattern);
incrRefCount(pattern);
pat = zmalloc(sizeof(*pat));
pat = zmalloc(sizeof(*pat), MALLOC_LOCAL);
pat->pattern = getDecodedObject(pattern);
pat->client = c;
listAddNodeTail(server.pubsub_patterns,pat);

View File

@ -94,7 +94,7 @@ static const size_t optimization_level[] = {4096, 8192, 16384, 32768, 65536};
quicklist *quicklistCreate(void) {
struct quicklist *quicklist;
quicklist = zmalloc(sizeof(*quicklist));
quicklist = zmalloc(sizeof(*quicklist), MALLOC_SHARED);
quicklist->head = quicklist->tail = NULL;
quicklist->len = 0;
quicklist->count = 0;
@ -137,7 +137,7 @@ quicklist *quicklistNew(int fill, int compress) {
REDIS_STATIC quicklistNode *quicklistCreateNode(void) {
quicklistNode *node;
node = zmalloc(sizeof(*node));
node = zmalloc(sizeof(*node), MALLOC_SHARED);
node->zl = NULL;
node->count = 0;
node->sz = 0;
@ -184,7 +184,7 @@ REDIS_STATIC int __quicklistCompressNode(quicklistNode *node) {
if (node->sz < MIN_COMPRESS_BYTES)
return 0;
quicklistLZF *lzf = zmalloc(sizeof(*lzf) + node->sz);
quicklistLZF *lzf = zmalloc(sizeof(*lzf) + node->sz, MALLOC_SHARED);
/* Cancel if compression fails or doesn't compress small enough */
if (((lzf->sz = lzf_compress(node->zl, node->sz, lzf->compressed,
@ -217,7 +217,7 @@ REDIS_STATIC int __quicklistDecompressNode(quicklistNode *node) {
node->attempted_compress = 0;
#endif
void *decompressed = zmalloc(node->sz);
void *decompressed = zmalloc(node->sz, MALLOC_SHARED);
quicklistLZF *lzf = (quicklistLZF *)node->zl;
if (lzf_decompress(lzf->compressed, lzf->sz, decompressed, node->sz) == 0) {
/* Someone requested decompress, but we can't decompress. Not good. */
@ -799,7 +799,7 @@ REDIS_STATIC quicklistNode *_quicklistSplitNode(quicklistNode *node, int offset,
size_t zl_sz = node->sz;
quicklistNode *new_node = quicklistCreateNode();
new_node->zl = zmalloc(zl_sz);
new_node->zl = zmalloc(zl_sz, MALLOC_SHARED);
/* Copy original ziplist so we can split it */
memcpy(new_node->zl, node->zl, zl_sz);
@ -1048,7 +1048,7 @@ int quicklistCompare(unsigned char *p1, unsigned char *p2, int p2_len) {
quicklistIter *quicklistGetIterator(const quicklist *quicklist, int direction) {
quicklistIter *iter;
iter = zmalloc(sizeof(*iter));
iter = zmalloc(sizeof(*iter), MALLOC_LOCAL);
if (direction == AL_START_HEAD) {
iter->current = quicklist->head;
@ -1195,10 +1195,10 @@ quicklist *quicklistDup(quicklist *orig) {
if (current->encoding == QUICKLIST_NODE_ENCODING_LZF) {
quicklistLZF *lzf = (quicklistLZF *)current->zl;
size_t lzf_sz = sizeof(*lzf) + lzf->sz;
node->zl = zmalloc(lzf_sz);
node->zl = zmalloc(lzf_sz, MALLOC_SHARED);
memcpy(node->zl, current->zl, lzf_sz);
} else if (current->encoding == QUICKLIST_NODE_ENCODING_RAW) {
node->zl = zmalloc(current->sz);
node->zl = zmalloc(current->sz, MALLOC_SHARED);
memcpy(node->zl, current->zl, current->sz);
}
@ -1372,7 +1372,7 @@ int quicklistPopCustom(quicklist *quicklist, int where, unsigned char **data,
REDIS_STATIC void *_quicklistSaver(unsigned char *data, unsigned int sz) {
unsigned char *vstr;
if (data) {
vstr = zmalloc(sz);
vstr = zmalloc(sz, MALLOC_SHARED);
memcpy(vstr, data, sz);
return vstr;
}

View File

@ -38,7 +38,7 @@
#ifndef RAX_ALLOC_H
#define RAX_ALLOC_H
#include "zmalloc.h"
#define rax_malloc zmalloc
#define rax_malloc(size) zmalloc(size, MALLOC_SHARED)
#define rax_realloc zrealloc
#define rax_free zfree
#endif

View File

@ -32,6 +32,7 @@
#include "zipmap.h"
#include "endianconv.h"
#include "stream.h"
#include "storage.h"
#include <math.h>
#include <sys/types.h>
@ -284,7 +285,7 @@ void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags, size_t *lenptr) {
char buf[LONG_STR_SIZE], *p;
int len = ll2string(buf,sizeof(buf),val);
if (lenptr) *lenptr = len;
p = plain ? zmalloc(len) : sdsnewlen(SDS_NOINIT,len);
p = plain ? zmalloc(len, MALLOC_SHARED) : sdsnewlen(SDS_NOINIT,len);
memcpy(p,buf,len);
return p;
} else if (encode) {
@ -345,7 +346,7 @@ ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
/* We require at least four bytes compression for this to be worth it */
if (len <= 4) return 0;
outlen = len-4;
if ((out = zmalloc(outlen+1)) == NULL) return 0;
if ((out = zmalloc(outlen+1, MALLOC_LOCAL)) == NULL) return 0;
comprlen = lzf_compress(s, len, out, outlen);
if (comprlen == 0) {
zfree(out);
@ -368,11 +369,11 @@ void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr) {
if ((clen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
if ((c = zmalloc(clen)) == NULL) goto err;
if ((c = zmalloc(clen, MALLOC_SHARED)) == NULL) goto err;
/* Allocate our target according to the uncompressed size. */
if (plain) {
val = zmalloc(len);
val = zmalloc(len, MALLOC_SHARED);
} else {
val = sdsnewlen(SDS_NOINIT,len);
}
@ -501,7 +502,7 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) {
if (len == RDB_LENERR) return NULL;
if (plain || sds) {
void *buf = plain ? zmalloc(len) : sdsnewlen(SDS_NOINIT,len);
void *buf = plain ? zmalloc(len, MALLOC_SHARED) : sdsnewlen(SDS_NOINIT,len);
if (lenptr) *lenptr = len;
if (len && rioRead(rdb,buf,len) == 0) {
if (plain)
@ -1290,10 +1291,12 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
openChildInfoPipe();
start = ustime();
handle_prefork();
if ((childpid = fork()) == 0) {
int retval;
/* Child */
handle_postfork(0);
closeListeningSockets(0);
redisSetProcTitle("redis-rdb-bgsave");
retval = rdbSave(filename,rsi);
@ -1312,6 +1315,7 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
exitFromChild((retval == C_OK) ? 0 : 1);
} else {
/* Parent */
handle_postfork(childpid);
server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
@ -2141,7 +2145,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
* If the process returned an error, consider the list of slaves that
* can continue to be empty, so that it's just a special case of the
* normal code path. */
ok_slaves = zmalloc(sizeof(uint64_t)); /* Make space for the count. */
ok_slaves = zmalloc(sizeof(uint64_t), MALLOC_LOCAL); /* Make space for the count. */
ok_slaves[0] = 0;
if (!bysignal && exitcode == 0) {
int readlen = sizeof(uint64_t);
@ -2258,11 +2262,11 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
/* Collect the file descriptors of the slaves we want to transfer
* the RDB to, which are i WAIT_BGSAVE_START state. */
fds = zmalloc(sizeof(int)*listLength(server.slaves));
fds = zmalloc(sizeof(int)*listLength(server.slaves), MALLOC_LOCAL);
/* We also allocate an array of corresponding client IDs. This will
* be useful for the child process in order to build the report
* (sent via unix pipe) that will be sent to the parent. */
clientids = zmalloc(sizeof(uint64_t)*listLength(server.slaves));
clientids = zmalloc(sizeof(uint64_t)*listLength(server.slaves), MALLOC_LOCAL);
numfds = 0;
listRewind(server.slaves,&li);
@ -2326,7 +2330,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
* can match the report with a specific slave, and 'error' is
* set to 0 if the replication process terminated with a success
* or the error code if an error occurred. */
void *msg = zmalloc(sizeof(uint64_t)*(1+2*numfds));
void *msg = zmalloc(sizeof(uint64_t)*(1+2*numfds), MALLOC_LOCAL);
uint64_t *len = msg;
uint64_t *ids = len+1;
int j, msglen;

View File

@ -45,6 +45,7 @@
#include "hiredis.h"
#include "adlist.h"
#include "zmalloc.h"
#include "storage.h"
#define UNUSED(V) ((void) V)
#define RANDPTR_INITIAL_SIZE 8
@ -315,7 +316,7 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
* Even when cloning another client, prefix commands are applied if needed.*/
static client createClient(char *cmd, size_t len, client from) {
int j;
client c = zmalloc(sizeof(struct _client));
client c = zmalloc(sizeof(struct _client), MALLOC_LOCAL);
if (config.hostsocket == NULL) {
c->context = redisConnectNonBlock(config.hostip,config.hostport);
@ -379,7 +380,7 @@ static client createClient(char *cmd, size_t len, client from) {
if (from) {
c->randlen = from->randlen;
c->randfree = 0;
c->randptr = zmalloc(sizeof(char*)*c->randlen);
c->randptr = zmalloc(sizeof(char*)*c->randlen, MALLOC_LOCAL);
/* copy the offsets. */
for (j = 0; j < (int)c->randlen; j++) {
c->randptr[j] = c->obuf + (from->randptr[j]-from->obuf);
@ -391,7 +392,7 @@ static client createClient(char *cmd, size_t len, client from) {
c->randlen = 0;
c->randfree = RANDPTR_INITIAL_SIZE;
c->randptr = zmalloc(sizeof(char*)*c->randfree);
c->randptr = zmalloc(sizeof(char*)*c->randfree, MALLOC_LOCAL);
while ((p = strstr(p,"__rand_int__")) != NULL) {
if (c->randfree == 0) {
c->randptr = zrealloc(c->randptr,sizeof(char*)*c->randlen*2);
@ -652,6 +653,8 @@ int main(int argc, const char **argv) {
client c;
storage_init();
srandom(time(NULL));
signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
@ -684,7 +687,7 @@ int main(int argc, const char **argv) {
argc -= i;
argv += i;
config.latency = zmalloc(sizeof(long long)*config.requests);
config.latency = zmalloc(sizeof(long long)*config.requests, MALLOC_LOCAL);
if (config.keepalive == 0) {
printf("WARNING: keepalive disabled, you probably need 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse' for Linux and 'sudo sysctl -w net.inet.tcp.msl=1000' for Mac OS X in order to use a lot of clients/requests\n");
@ -716,7 +719,7 @@ int main(int argc, const char **argv) {
}
/* Run default benchmark suite. */
data = zmalloc(config.datasize+1);
data = zmalloc(config.datasize+1, MALLOC_LOCAL);
do {
memset(data,'x',config.datasize);
data[config.datasize] = '\0';

View File

@ -82,7 +82,7 @@ int readString(FILE *fp, char** target) {
/* Increase length to also consume \r\n */
len += 2;
*target = (char*)zmalloc(len);
*target = (char*)zmalloc(len, MALLOC_LOCAL);
if (!readBytes(fp,*target,len)) {
return 0;
}

View File

@ -55,6 +55,7 @@
#include "help.h"
#include "anet.h"
#include "ae.h"
#include "storage.h"
#define UNUSED(V) ((void) V)
@ -477,11 +478,11 @@ static void cliInitHelp(void) {
helpEntry tmp;
helpEntriesLen = len = commandslen+groupslen;
helpEntries = zmalloc(sizeof(helpEntry)*len);
helpEntries = zmalloc(sizeof(helpEntry)*len, MALLOC_LOCAL);
for (i = 0; i < groupslen; i++) {
tmp.argc = 1;
tmp.argv = zmalloc(sizeof(sds));
tmp.argv = zmalloc(sizeof(sds), MALLOC_LOCAL);
tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",commandGroups[i]);
tmp.full = tmp.argv[0];
tmp.type = CLI_HELP_GROUP;
@ -532,13 +533,13 @@ static void cliIntegrateHelp(void) {
helpEntry *new = helpEntries+(helpEntriesLen-1);
new->argc = 1;
new->argv = zmalloc(sizeof(sds));
new->argv = zmalloc(sizeof(sds), MALLOC_LOCAL);
new->argv[0] = sdsnew(cmdname);
new->full = new->argv[0];
new->type = CLI_HELP_COMMAND;
sdstoupper(new->argv[0]);
struct commandHelp *ch = zmalloc(sizeof(*ch));
struct commandHelp *ch = zmalloc(sizeof(*ch), MALLOC_LOCAL);
ch->name = new->argv[0];
ch->params = sdsempty();
int args = llabs(entry->element[1]->integer);
@ -1171,7 +1172,7 @@ static int cliSendCommand(int argc, char **argv, long repeat) {
}
/* Setup argument length */
argvlen = zmalloc(argc*sizeof(size_t));
argvlen = zmalloc(argc*sizeof(size_t), MALLOC_LOCAL);
for (j = 0; j < argc; j++)
argvlen[j] = sdslen(argv[j]);
@ -1590,7 +1591,7 @@ static int confirmWithYes(char *msg) {
/* Turn the plain C strings into Sds strings */
static char **convertToSds(int count, char** args) {
int j;
char **sds = zmalloc(sizeof(char*)*count);
char **sds = zmalloc(sizeof(char*)*count, MALLOC_LOCAL);
for(j = 0; j < count; j++)
sds[j] = sdsnew(args[j]);
@ -1872,7 +1873,7 @@ static int evalMode(int argc, char **argv) {
}
/* Create our argument vector */
argv2 = zmalloc(sizeof(sds)*(argc+3));
argv2 = zmalloc(sizeof(sds)*(argc+3), MALLOC_LOCAL);
argv2[0] = sdsnew("EVAL");
argv2[1] = script;
for (j = 0; j < argc; j++) {
@ -2193,7 +2194,7 @@ static void freeClusterManager(void) {
}
static clusterManagerNode *clusterManagerNewNode(char *ip, int port) {
clusterManagerNode *node = zmalloc(sizeof(*node));
clusterManagerNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL);
node->context = NULL;
node->name = NULL;
node->ip = ip;
@ -2228,7 +2229,7 @@ static int clusterManagerCheckRedisReply(clusterManagerNode *n,
if (!r || (is_err = (r->type == REDIS_REPLY_ERROR))) {
if (is_err) {
if (err != NULL) {
*err = zmalloc((r->len + 1) * sizeof(char));
*err = zmalloc((r->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, r->str);
} else CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, r->str);
}
@ -2374,7 +2375,7 @@ static redisReply *clusterManagerGetNodeRedisInfo(clusterManagerNode *node,
if (info == NULL) return NULL;
if (info->type == REDIS_REPLY_ERROR) {
if (err != NULL) {
*err = zmalloc((info->len + 1) * sizeof(char));
*err = zmalloc((info->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, info->str);
}
freeReplyObject(info);
@ -2451,7 +2452,7 @@ static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes,
int node_len = cluster_manager.nodes->len;
clusterManagerNode **offending_p = NULL;
if (offending != NULL) {
*offending = zcalloc(node_len * sizeof(clusterManagerNode*));
*offending = zcalloc(node_len * sizeof(clusterManagerNode*), MALLOC_LOCAL);
offending_p = *offending;
}
/* For each set of nodes in the same host, split by
@ -2541,7 +2542,7 @@ static void clusterManagerOptimizeAntiAffinity(clusterManagerNodeArray *ipnodes,
clusterManagerNode *first = offenders[rand_idx],
*second = NULL;
clusterManagerNode **other_replicas = zcalloc((node_len - 1) *
sizeof(*other_replicas));
sizeof(*other_replicas), MALLOC_LOCAL);
int other_replicas_count = 0;
listIter li;
listNode *ln;
@ -2769,8 +2770,8 @@ static int clusterManagerAddSlots(clusterManagerNode *node, char**err)
int success = 1;
/* First two args are used for the command itself. */
int argc = node->slots_count + 2;
sds *argv = zmalloc(argc * sizeof(*argv));
size_t *argvlen = zmalloc(argc * sizeof(*argvlen));
sds *argv = zmalloc(argc * sizeof(*argv), MALLOC_LOCAL);
size_t *argvlen = zmalloc(argc * sizeof(*argvlen), MALLOC_LOCAL);
argv[0] = "CLUSTER";
argv[1] = "ADDSLOTS";
argvlen[0] = 7;
@ -2869,7 +2870,7 @@ static int clusterManagerSetSlot(clusterManagerNode *node1,
if (reply->type == REDIS_REPLY_ERROR) {
success = 0;
if (err != NULL) {
*err = zmalloc((reply->len + 1) * sizeof(char));
*err = zmalloc((reply->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, reply->str);
} else CLUSTER_MANAGER_PRINT_REPLY_ERROR(node1, reply->str);
goto cleanup;
@ -2983,8 +2984,8 @@ static int clusterManagerCompareKeysValues(clusterManagerNode *n1,
{
size_t i, argc = keys_reply->elements + 2;
static const char *hash_zero = "0000000000000000000000000000000000000000";
char **argv = zcalloc(argc * sizeof(char *));
size_t *argv_len = zcalloc(argc * sizeof(size_t));
char **argv = zcalloc(argc * sizeof(char *), MALLOC_LOCAL);
size_t *argv_len = zcalloc(argc * sizeof(size_t), MALLOC_LOCAL);
argv[0] = "DEBUG";
argv_len[0] = 5;
argv[1] = "DIGEST-VALUE";
@ -3051,8 +3052,8 @@ static redisReply *clusterManagerMigrateKeysInReply(clusterManagerNode *source,
if (config.auth) c += 2;
size_t argc = c + reply->elements;
size_t i, offset = 6; // Keys Offset
argv = zcalloc(argc * sizeof(char *));
argv_len = zcalloc(argc * sizeof(size_t));
argv = zcalloc(argc * sizeof(char *), MALLOC_LOCAL);
argv_len = zcalloc(argc * sizeof(size_t), MALLOC_LOCAL);
char portstr[255];
char timeoutstr[255];
snprintf(portstr, 10, "%d", target->port);
@ -3130,7 +3131,7 @@ static int clusterManagerMigrateKeysInSlot(clusterManagerNode *source,
if (reply->type == REDIS_REPLY_ERROR) {
success = 0;
if (err != NULL) {
*err = zmalloc((reply->len + 1) * sizeof(char));
*err = zmalloc((reply->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, reply->str);
CLUSTER_MANAGER_PRINT_REPLY_ERROR(source, *err);
}
@ -3142,7 +3143,7 @@ static int clusterManagerMigrateKeysInSlot(clusterManagerNode *source,
freeReplyObject(reply);
break;
}
if (verbose) dots = zmalloc((count+1) * sizeof(char));
if (verbose) dots = zmalloc((count+1) * sizeof(char), MALLOC_LOCAL);
/* Calling MIGRATE command. */
migrate_reply = clusterManagerMigrateKeysInReply(source, target,
reply, 0, timeout,
@ -3242,7 +3243,7 @@ static int clusterManagerMigrateKeysInSlot(clusterManagerNode *source,
if (!success) {
if (migrate_reply != NULL) {
if (err) {
*err = zmalloc((migrate_reply->len + 1) * sizeof(char));
*err = zmalloc((migrate_reply->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, migrate_reply->str);
}
printf("\n");
@ -3318,7 +3319,7 @@ static int clusterManagerMoveSlot(clusterManagerNode *source,
if (r->type == REDIS_REPLY_ERROR) {
success = 0;
if (err != NULL) {
*err = zmalloc((r->len + 1) * sizeof(char));
*err = zmalloc((r->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, r->str);
CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, *err);
}
@ -3347,7 +3348,7 @@ static int clusterManagerFlushNodeConfig(clusterManagerNode *node, char **err) {
node->replicate);
if (reply == NULL || (is_err = (reply->type == REDIS_REPLY_ERROR))) {
if (is_err && err != NULL) {
*err = zmalloc((reply->len + 1) * sizeof(char));
*err = zmalloc((reply->len + 1) * sizeof(char), MALLOC_LOCAL);
strcpy(*err, reply->str);
}
success = 0;
@ -3715,7 +3716,7 @@ static sds clusterManagerGetConfigSignature(clusterManagerNode *node) {
zrealloc(node_configs, (node_count * sizeof(char *)));
/* Make room for '|' separators. */
tot_size += (sizeof(char) * (c - 1));
char *cfg = zmalloc((sizeof(char) * tot_size) + 1);
char *cfg = zmalloc((sizeof(char) * tot_size) + 1, MALLOC_LOCAL);
memcpy(cfg, nodename, name_len);
char *sp = cfg + name_len;
*(sp++) = ':';
@ -4641,7 +4642,7 @@ static clusterManagerNode *clusterNodeForResharding(char *id,
static list *clusterManagerComputeReshardTable(list *sources, int numslots) {
list *moved = listCreate();
int src_count = listLength(sources), i = 0, tot_slots = 0, j;
clusterManagerNode **sorted = zmalloc(src_count * sizeof(*sorted));
clusterManagerNode **sorted = zmalloc(src_count * sizeof(*sorted), MALLOC_LOCAL);
listIter li;
listNode *ln;
listRewind(sources, &li);
@ -4662,7 +4663,7 @@ static list *clusterManagerComputeReshardTable(list *sources, int numslots) {
int slot = node->slots[j];
if (!slot) continue;
if (count >= max || (int)listLength(moved) >= numslots) break;
clusterManagerReshardTableItem *item = zmalloc(sizeof(*item));
clusterManagerReshardTableItem *item = zmalloc(sizeof(*item), MALLOC_LOCAL);
item->source = node;
item->slot = j;
listAddNodeTail(moved, item);
@ -4720,7 +4721,7 @@ static void clusterManagerLog(int level, const char* fmt, ...) {
static void clusterManagerNodeArrayInit(clusterManagerNodeArray *array,
int alloc_len)
{
array->nodes = zcalloc(alloc_len * sizeof(clusterManagerNode*));
array->nodes = zcalloc(alloc_len * sizeof(clusterManagerNode*), MALLOC_LOCAL);
array->alloc = array->nodes;
array->len = alloc_len;
array->count = 0;
@ -4861,9 +4862,9 @@ static int clusterManagerCommandCreate(int argc, char **argv) {
clusterManagerLogInfo(">>> Performing hash slots allocation "
"on %d nodes...\n", node_len);
int interleaved_len = 0, ip_count = 0;
clusterManagerNode **interleaved = zcalloc(node_len*sizeof(**interleaved));
char **ips = zcalloc(node_len * sizeof(char*));
clusterManagerNodeArray *ip_nodes = zcalloc(node_len * sizeof(*ip_nodes));
clusterManagerNode **interleaved = zcalloc(node_len*sizeof(**interleaved), MALLOC_LOCAL);
char **ips = zcalloc(node_len * sizeof(char*), MALLOC_LOCAL);
clusterManagerNodeArray *ip_nodes = zcalloc(node_len * sizeof(*ip_nodes), MALLOC_LOCAL);
listIter li;
listNode *ln;
listRewind(cluster_manager.nodes, &li);
@ -5500,7 +5501,7 @@ static int clusterManagerCommandRebalance(int argc, char **argv) {
nodes_involved++;
listAddNodeTail(involved, n);
}
weightedNodes = zmalloc(nodes_involved * sizeof(clusterManagerNode *));
weightedNodes = zmalloc(nodes_involved * sizeof(clusterManagerNode *), MALLOC_LOCAL);
if (weightedNodes == NULL) goto cleanup;
/* Check cluster, only proceed if it looks sane. */
clusterManagerCheckCluster(1);
@ -5845,7 +5846,7 @@ static int clusterManagerCommandCall(int argc, char **argv) {
if (!clusterManagerLoadInfoFromNode(refnode, 0)) return 0;
argc--;
argv++;
size_t *argvlen = zmalloc(argc*sizeof(size_t));
size_t *argvlen = zmalloc(argc*sizeof(size_t), MALLOC_LOCAL);
clusterManagerLogInfo(">>> Calling");
for (i = 0; i < argc; i++) {
argvlen[i] = strlen(argv[i]);
@ -6841,7 +6842,7 @@ static char *getInfoField(char *info, char *field) {
n1 = strchr(p,'\r');
n2 = strchr(p,',');
if (n2 && n2 < n1) n1 = n2;
result = zmalloc(sizeof(char)*(n1-p)+1);
result = zmalloc(sizeof(char)*(n1-p)+1, MALLOC_LOCAL);
memcpy(result,p,(n1-p));
result[n1-p] = '\0';
return result;
@ -7175,6 +7176,7 @@ static void intrinsicLatencyMode(void) {
int main(int argc, char **argv) {
int firstarg;
storage_init();
config.hostip = sdsnew("127.0.0.1");
config.hostport = 6379;
config.hostsocket = NULL;

View File

@ -76,7 +76,7 @@ char *replicationGetSlaveName(client *c) {
void createReplicationBacklog(void) {
serverAssert(server.repl_backlog == NULL);
server.repl_backlog = zmalloc(server.repl_backlog_size);
server.repl_backlog = zmalloc(server.repl_backlog_size, MALLOC_LOCAL);
server.repl_backlog_histlen = 0;
server.repl_backlog_idx = 0;
@ -105,7 +105,7 @@ void resizeReplicationBacklog(long long newsize) {
* worse often we need to alloc additional space before freeing the
* old buffer. */
zfree(server.repl_backlog);
server.repl_backlog = zmalloc(server.repl_backlog_size);
server.repl_backlog = zmalloc(server.repl_backlog_size, MALLOC_LOCAL);
server.repl_backlog_histlen = 0;
server.repl_backlog_idx = 0;
/* Next byte we have is... the next since the buffer is empty. */

View File

@ -267,8 +267,8 @@ void rioInitWithFdset(rio *r, int *fds, int numfds) {
int j;
*r = rioFdsetIO;
r->io.fdset.fds = zmalloc(sizeof(int)*numfds);
r->io.fdset.state = zmalloc(sizeof(int)*numfds);
r->io.fdset.fds = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL);
r->io.fdset.state = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL);
memcpy(r->io.fdset.fds,fds,sizeof(int)*numfds);
for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0;
r->io.fdset.numfds = numfds;

View File

@ -1866,7 +1866,7 @@ sds *ldbReplParseCommand(int *argcp) {
if (*argcp <= 0 || *argcp > 1024) goto protoerr;
/* Parse each argument. */
argv = zmalloc(sizeof(sds)*(*argcp));
argv = zmalloc(sizeof(sds)*(*argcp), MALLOC_LOCAL);
argc = 0;
while(argc < *argcp) {
if (*p != '$') goto protoerr;

View File

@ -96,7 +96,7 @@ sds sdsnewlen(const void *init, size_t initlen) {
int hdrlen = sdsHdrSize(type);
unsigned char *fp; /* flags pointer. */
sh = s_malloc(hdrlen+initlen+1);
sh = s_malloc(hdrlen+initlen+1, MALLOC_SHARED);
if (init==SDS_NOINIT)
init = NULL;
else if (!init)
@ -234,7 +234,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
} else {
/* Since the header size changes, need to move the string forward,
* and can't use realloc */
newsh = s_malloc(hdrlen+newlen+1);
newsh = s_malloc(hdrlen+newlen+1, MALLOC_SHARED);
if (newsh == NULL) return NULL;
memcpy((char*)newsh+hdrlen, s, len+1);
s_free(sh);
@ -273,7 +273,7 @@ sds sdsRemoveFreeSpace(sds s) {
if (newsh == NULL) return NULL;
s = (char*)newsh+oldhdrlen;
} else {
newsh = s_malloc(hdrlen+len+1);
newsh = s_malloc(hdrlen+len+1, MALLOC_SHARED);
if (newsh == NULL) return NULL;
memcpy((char*)newsh+hdrlen, s, len+1);
s_free(sh);
@ -523,7 +523,7 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
/* We try to start using a static buffer for speed.
* If not possible we revert to heap allocation. */
if (buflen > sizeof(staticbuf)) {
buf = s_malloc(buflen);
buf = s_malloc(buflen, MALLOC_SHARED);
if (buf == NULL) return NULL;
} else {
buflen = sizeof(staticbuf);
@ -539,7 +539,7 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
if (buf[buflen-2] != '\0') {
if (buf != staticbuf) s_free(buf);
buflen *= 2;
buf = s_malloc(buflen);
buf = s_malloc(buflen, MALLOC_SHARED);
if (buf == NULL) return NULL;
continue;
}
@ -816,7 +816,7 @@ sds *sdssplitlen(const char *s, ssize_t len, const char *sep, int seplen, int *c
if (seplen < 1 || len < 0) return NULL;
tokens = s_malloc(sizeof(sds)*slots);
tokens = s_malloc(sizeof(sds)*slots, MALLOC_SHARED);
if (tokens == NULL) return NULL;
if (len == 0) {
@ -1044,7 +1044,7 @@ sds *sdssplitargs(const char *line, int *argc) {
current = NULL;
} else {
/* Even on empty input string return something not NULL. */
if (vector == NULL) vector = s_malloc(sizeof(void*));
if (vector == NULL) vector = s_malloc(sizeof(void*), MALLOC_SHARED);
return vector;
}
}
@ -1111,7 +1111,7 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
* the overhead of function calls. Here we define these wrappers only for
* the programs SDS is linked to, if they want to touch the SDS internals
* even if they use a different allocator. */
void *sds_malloc(size_t size) { return s_malloc(size); }
void *sds_malloc(size_t size) { return s_malloc(size, MALLOC_SHARED); }
void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
void sds_free(void *ptr) { s_free(ptr); }

View File

@ -37,6 +37,10 @@
* to use the default libc allocator). */
#include "zmalloc.h"
#define s_malloc zmalloc
#define s_realloc zrealloc
#define s_free zfree
#include "storage.h"
//#define s_malloc zmalloc
#define s_malloc salloc
//#define s_realloc zrealloc
#define s_realloc srealloc
//#define s_free zfree
#define s_free sfree

View File

@ -341,7 +341,7 @@ static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
return C_ERR;
/* Create container for context and r/w events */
e = (redisAeEvents*)zmalloc(sizeof(*e));
e = (redisAeEvents*)zmalloc(sizeof(*e), MALLOC_LOCAL);
e->context = ac;
e->loop = loop;
e->fd = c->fd;
@ -549,7 +549,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
errno = ENOENT;
return NULL;
}
sa = zmalloc(sizeof(*sa));
sa = zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(ip);
sa->port = port;
return sa;
@ -559,7 +559,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
sentinelAddr *dupSentinelAddr(sentinelAddr *src) {
sentinelAddr *sa;
sa = zmalloc(sizeof(*sa));
sa = zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(src->ip);
sa->port = src->port;
return sa;
@ -703,10 +703,10 @@ void sentinelScheduleScriptExecution(char *path, ...) {
va_end(ap);
argv[0] = sdsnew(path);
sj = zmalloc(sizeof(*sj));
sj = zmalloc(sizeof(*sj), MALLOC_LOCAL);
sj->flags = SENTINEL_SCRIPT_NONE;
sj->retry_num = 0;
sj->argv = zmalloc(sizeof(char*)*(argc+1));
sj->argv = zmalloc(sizeof(char*)*(argc+1), MALLOC_LOCAL);
sj->start_time = 0;
sj->pid = 0;
memcpy(sj->argv,argv,sizeof(char*)*(argc+1));
@ -950,7 +950,7 @@ void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, cha
/* Create a not yet connected link object. */
instanceLink *createInstanceLink(void) {
instanceLink *link = zmalloc(sizeof(*link));
instanceLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL);
link->refcount = 1;
link->disconnected = 1;
@ -1200,7 +1200,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
}
/* Create the instance object. */
ri = zmalloc(sizeof(*ri));
ri = zmalloc(sizeof(*ri), MALLOC_LOCAL);
/* Note that all the instances are started in the disconnected state,
* the event loop will take care of connecting them. */
ri->flags = flags;
@ -4091,7 +4091,7 @@ int compareSlavesForPromotion(const void *a, const void *b) {
sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
sentinelRedisInstance **instance =
zmalloc(sizeof(instance[0])*dictSize(master->slaves));
zmalloc(sizeof(instance[0])*dictSize(master->slaves), MALLOC_LOCAL);
sentinelRedisInstance *selected = NULL;
int instances = 0;
dictIterator *di;

View File

@ -33,6 +33,7 @@
#include "bio.h"
#include "latency.h"
#include "atomicvar.h"
#include "storage.h"
#include <time.h>
#include <signal.h>
@ -2729,7 +2730,7 @@ void initServer(void) {
strerror(errno));
exit(1);
}
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
server.db = zmalloc(sizeof(redisDb)*server.dbnum, MALLOC_LOCAL);
/* Open the TCP listening socket for the user commands. */
if (server.port != 0 &&
@ -3066,7 +3067,7 @@ void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc,
if (server.loading) return; /* No propagation during loading. */
argvcopy = zmalloc(sizeof(robj*)*argc);
argvcopy = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
for (j = 0; j < argc; j++) {
argvcopy[j] = argv[j];
incrRefCount(argv[j]);
@ -4481,7 +4482,7 @@ void usage(void) {
void redisAsciiArt(void) {
#include "asciilogo.h"
char *buf = zmalloc(1024*16);
char *buf = zmalloc(1024*16, MALLOC_LOCAL);
char *mode;
if (server.cluster_enabled) mode = "cluster";
@ -4739,6 +4740,8 @@ int main(int argc, char **argv) {
struct timeval tv;
int j;
storage_init();
#ifdef REDIS_TEST
if (argc == 3 && !strcasecmp(argv[1], "test")) {
if (!strcasecmp(argv[2], "ziplist")) {
@ -4789,7 +4792,7 @@ int main(int argc, char **argv) {
/* Store the executable path and arguments in a safe place in order
* to be able to restart the server later. */
server.executable = getAbsolutePath(argv[0]);
server.exec_argv = zmalloc(sizeof(char*)*(argc+1));
server.exec_argv = zmalloc(sizeof(char*)*(argc+1), MALLOC_LOCAL);
server.exec_argv[argc] = NULL;
for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]);

View File

@ -46,12 +46,12 @@
* Incrementing the ref count of all the objects retained is up to
* this function. */
slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) {
slowlogEntry *se = zmalloc(sizeof(*se));
slowlogEntry *se = zmalloc(sizeof(*se), MALLOC_LOCAL);
int j, slargc = argc;
if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
se->argc = slargc;
se->argv = zmalloc(sizeof(robj*)*slargc);
se->argv = zmalloc(sizeof(robj*)*slargc, MALLOC_LOCAL);
for (j = 0; j < slargc; j++) {
/* Logging too many arguments is a useless memory waste, so we stop
* at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify

View File

@ -36,7 +36,7 @@
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
redisSortOperation *createSortOperation(int type, robj *pattern) {
redisSortOperation *so = zmalloc(sizeof(*so));
redisSortOperation *so = zmalloc(sizeof(*so), MALLOC_LOCAL);
so->type = type;
so->pattern = pattern;
return so;
@ -340,7 +340,7 @@ void sortCommand(client *c) {
}
/* Load the sorting vector with all the objects to sort */
vector = zmalloc(sizeof(redisSortObject)*vectorlen);
vector = zmalloc(sizeof(redisSortObject)*vectorlen, MALLOC_LOCAL);
j = 0;
if (sortval->type == OBJ_LIST && dontsort) {

View File

@ -55,7 +55,7 @@ static int label_margin_top = 1;
/* Create a new sequence. */
struct sequence *createSparklineSequence(void) {
struct sequence *seq = zmalloc(sizeof(*seq));
struct sequence *seq = zmalloc(sizeof(*seq), MALLOC_LOCAL);
seq->length = 0;
seq->samples = NULL;
return seq;
@ -99,7 +99,7 @@ sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset,
double relmax = seq->max - seq->min;
int steps = charset_len*rows;
int row = 0;
char *chars = zmalloc(len);
char *chars = zmalloc(len, MALLOC_LOCAL);
int loop = 1;
int opt_fill = flags & SPARKLINE_FILL;
int opt_log = flags & SPARKLINE_LOG_SCALE;

155
src/storage.c Normal file
View File

@ -0,0 +1,155 @@
#include "server.h"
#include <stdlib.h>
#include <stdio.h>
#include <memkind.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <unistd.h>
#include <inttypes.h>
#include "storage.h"
struct memkind *mkdisk = NULL;
static char *PMEM_DIR = "/mnt/btrfs_scratch/";
#define OBJECT_PAGE_BUFFER_SIZE 8192 //(size in objs)
struct object_page
{
uint64_t allocmap[OBJECT_PAGE_BUFFER_SIZE/(8*sizeof(uint64_t))];
robj rgobj[OBJECT_PAGE_BUFFER_SIZE];
struct object_page *pnext;
};
#define OBJ_PAGE_BITS_PER_WORD 64
struct object_page *headObjpage = NULL;
void storage_init()
{
int errv = memkind_create_pmem(PMEM_DIR, 0, &mkdisk);
if (errv)
{
fprintf(stderr, "Memory pool creation failed: %d\n", errv);
exit(EXIT_FAILURE);
}
headObjpage = memkind_calloc(MEMKIND_HUGETLB, 1, sizeof(struct object_page));
}
int IdxAllocObject(struct object_page *page)
{
for (size_t iword = 0; iword < OBJ_PAGE_BITS_PER_WORD; ++iword)
{
if ((page->allocmap[iword] + 1) != 0)
{
int ibit = 0;
uint64_t bitword = page->allocmap[iword];
while (bitword & 1)
{
bitword >>= 1;
++ibit;
}
page->allocmap[iword] |= 1 << ibit;
return (iword * OBJ_PAGE_BITS_PER_WORD) + ibit;
}
}
return -1;
}
struct redisObject *salloc_obj()
{
struct object_page *cur = headObjpage;
for (;;)
{
int idx = IdxAllocObject(cur);
if (idx >= 0)
{
return &cur->rgobj[idx];
}
if (cur->pnext == NULL)
{
cur->pnext = memkind_calloc(MEMKIND_HUGETLB, 1, sizeof(struct object_page));
}
cur = cur->pnext;
}
}
void sfree_obj(struct redisObject *obj)
{
struct object_page *cur = headObjpage;
for (;;)
{
if (obj >= cur->rgobj && (obj < (cur->rgobj + OBJECT_PAGE_BUFFER_SIZE)))
{
// Its on this page
int idx = obj - cur->rgobj;
cur->allocmap[idx / OBJ_PAGE_BITS_PER_WORD] &= ~(1 << (idx % OBJ_PAGE_BITS_PER_WORD));
break;
}
cur = cur->pnext;
}
return;
}
void *salloc(size_t cb, enum MALLOC_CLASS class)
{
switch (class)
{
case MALLOC_SHARED:
return memkind_malloc(mkdisk, cb);
default:
return memkind_malloc(MEMKIND_DEFAULT, cb);
}
return NULL;
}
void *scalloc(size_t cb, size_t c, enum MALLOC_CLASS class)
{
switch (class)
{
case MALLOC_SHARED:
return memkind_calloc(mkdisk, cb, c);
default:
return memkind_calloc(MEMKIND_DEFAULT, cb, c);
}
return NULL;
}
void sfree(void *pv)
{
memkind_free(NULL, pv);
}
void *srealloc(void *pv, size_t cb)
{
memkind_t kind = mkdisk;
return memkind_realloc(kind, pv, cb);
}
int fdNew = -1;
void handle_prefork()
{
memkind_tmpfile(PMEM_DIR, &fdNew);
if (ioctl(fdNew, FICLONE, memkind_fd(mkdisk)) == -1)
{
perror("failed to fork file");
exit(EXIT_FAILURE);
}
}
void handle_postfork(int pid)
{
if (pid != 0)
{
// Parent, close fdNew
close(fdNew);
fdNew = -1;
}
else
{
int fdOriginal = memkind_fd(mkdisk);
memkind_pmem_remapfd(mkdisk, fdNew);
close(fdOriginal);
}
}

23
src/storage.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __STORAGE_H__
#define __STORAGE_H__
enum MALLOC_CLASS
{
MALLOC_LOCAL,
MALLOC_SHARED,
};
void storage_init(void);
struct redisObject *salloc_obj();
void sfree_obj(struct redisObject *obj);
void *salloc(size_t cb, enum MALLOC_CLASS class);
void *scalloc(size_t cb, size_t c, enum MALLOC_CLASS class);
void sfree(void*);
void *srealloc(void *pv, size_t cb);
void handle_prefork();
void handle_postfork(int pid);
#endif

View File

@ -322,7 +322,7 @@ unsigned long hashTypeLength(const robj *o) {
}
hashTypeIterator *hashTypeInitIterator(robj *subject) {
hashTypeIterator *hi = zmalloc(sizeof(hashTypeIterator));
hashTypeIterator *hi = zmalloc(sizeof(hashTypeIterator), MALLOC_LOCAL);
hi->subject = subject;
hi->encoding = subject->encoding;

View File

@ -82,7 +82,7 @@ unsigned long listTypeLength(const robj *subject) {
/* Initialize an iterator at the specified index. */
listTypeIterator *listTypeInitIterator(robj *subject, long index,
unsigned char direction) {
listTypeIterator *li = zmalloc(sizeof(listTypeIterator));
listTypeIterator *li = zmalloc(sizeof(listTypeIterator), MALLOC_LOCAL);
li->subject = subject;
li->encoding = subject->encoding;
li->direction = direction;

View File

@ -119,7 +119,7 @@ int setTypeIsMember(robj *subject, sds value) {
}
setTypeIterator *setTypeInitIterator(robj *subject) {
setTypeIterator *si = zmalloc(sizeof(setTypeIterator));
setTypeIterator *si = zmalloc(sizeof(setTypeIterator), MALLOC_LOCAL);
si->subject = subject;
si->encoding = subject->encoding;
if (si->encoding == OBJ_ENCODING_HT) {
@ -791,7 +791,7 @@ int qsortCompareSetsByRevCardinality(const void *s1, const void *s2) {
void sinterGenericCommand(client *c, robj **setkeys,
unsigned long setnum, robj *dstkey) {
robj **sets = zmalloc(sizeof(robj*)*setnum);
robj **sets = zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
setTypeIterator *si;
robj *dstset = NULL;
sds elesds;
@ -930,7 +930,7 @@ void sinterstoreCommand(client *c) {
void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
robj *dstkey, int op) {
robj **sets = zmalloc(sizeof(robj*)*setnum);
robj **sets = zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
setTypeIterator *si;
robj *dstset = NULL;
sds ele;

View File

@ -50,7 +50,7 @@ size_t streamReplyWithRangeFromConsumerPEL(client *c, stream *s, streamID *start
/* Create a new stream data structure. */
stream *streamNew(void) {
stream *s = zmalloc(sizeof(*s));
stream *s = zmalloc(sizeof(*s), MALLOC_SHARED);
s->rax = raxNew();
s->length = 0;
s->last_id.ms = 0;
@ -1402,8 +1402,8 @@ void xreadCommand(client *c) {
/* Parse the IDs and resolve the group name. */
if (streams_count > STREAMID_STATIC_VECTOR_LEN)
ids = zmalloc(sizeof(streamID)*streams_count);
if (groupname) groups = zmalloc(sizeof(streamCG*)*streams_count);
ids = zmalloc(sizeof(streamID)*streams_count, MALLOC_SHARED);
if (groupname) groups = zmalloc(sizeof(streamCG*)*streams_count, MALLOC_SHARED);
for (int i = streams_arg + streams_count; i < c->argc; i++) {
/* Specifying "$" as last-known-id means that the client wants to be
@ -1595,7 +1595,7 @@ cleanup: /* Cleanup. */
* time to the current time. The NACK consumer will be set to the one
* specified as argument of the function. */
streamNACK *streamCreateNACK(streamConsumer *consumer) {
streamNACK *nack = zmalloc(sizeof(*nack));
streamNACK *nack = zmalloc(sizeof(*nack), MALLOC_SHARED);
nack->delivery_time = mstime();
nack->delivery_count = 1;
nack->consumer = consumer;
@ -1628,7 +1628,7 @@ streamCG *streamCreateCG(stream *s, char *name, size_t namelen, streamID *id) {
if (raxFind(s->cgroups,(unsigned char*)name,namelen) != raxNotFound)
return NULL;
streamCG *cg = zmalloc(sizeof(*cg));
streamCG *cg = zmalloc(sizeof(*cg), MALLOC_SHARED);
cg->pel = raxNew();
cg->consumers = raxNew();
cg->last_id = *id;
@ -1661,7 +1661,7 @@ streamConsumer *streamLookupConsumer(streamCG *cg, sds name, int create) {
sdslen(name));
if (consumer == raxNotFound) {
if (!create) return NULL;
consumer = zmalloc(sizeof(*consumer));
consumer = zmalloc(sizeof(*consumer), MALLOC_SHARED);
consumer->name = sdsdup(name);
consumer->pel = raxNew();
raxInsert(cg->consumers,(unsigned char*)name,sdslen(name),

View File

@ -70,7 +70,7 @@ int zslLexValueLteMax(sds value, zlexrangespec *spec);
* The SDS string 'ele' is referenced by the node after the call. */
zskiplistNode *zslCreateNode(int level, double score, sds ele) {
zskiplistNode *zn =
zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));
zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel), MALLOC_SHARED);
zn->score = score;
zn->ele = ele;
return zn;
@ -81,7 +81,7 @@ zskiplist *zslCreate(void) {
int j;
zskiplist *zsl;
zsl = zmalloc(sizeof(*zsl));
zsl = zmalloc(sizeof(*zsl), MALLOC_SHARED);
zsl->level = 1;
zsl->length = 0;
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
@ -1182,7 +1182,7 @@ void zsetConvert(robj *zobj, int encoding) {
if (encoding != OBJ_ENCODING_SKIPLIST)
serverPanic("Unknown target encoding");
zs = zmalloc(sizeof(*zs));
zs = zmalloc(sizeof(*zs), MALLOC_SHARED);
zs->dict = dictCreate(&zsetDictType,NULL);
zs->zsl = zslCreate();
@ -1590,7 +1590,7 @@ void zaddGenericCommand(client *c, int flags) {
/* Start parsing all the scores, we need to emit any syntax error
* before executing additions to the sorted set, as the command should
* either execute fully or nothing at all. */
scores = zmalloc(sizeof(double)*elements);
scores = zmalloc(sizeof(double)*elements, MALLOC_SHARED);
for (j = 0; j < elements; j++) {
if (getDoubleFromObjectOrReply(c,c->argv[scoreidx+j*2],&scores[j],NULL)
!= C_OK) goto cleanup;
@ -2203,7 +2203,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
}
/* read keys to be used for input */
src = zcalloc(sizeof(zsetopsrc) * setnum);
src = zcalloc(sizeof(zsetopsrc) * setnum, MALLOC_SHARED);
for (i = 0, j = 3; i < setnum; i++, j++) {
robj *obj = lookupKeyWrite(c->db,c->argv[j]);
if (obj != NULL) {

View File

@ -577,7 +577,7 @@ void zipEntry(unsigned char *p, zlentry *e) {
/* Create a new empty ziplist. */
unsigned char *ziplistNew(void) {
unsigned int bytes = ZIPLIST_HEADER_SIZE+1;
unsigned char *zl = zmalloc(bytes);
unsigned char *zl = zmalloc(bytes, MALLOC_SHARED);
ZIPLIST_BYTES(zl) = intrev32ifbe(bytes);
ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE);
ZIPLIST_LENGTH(zl) = 0;

View File

@ -94,7 +94,7 @@
/* Create a new empty zipmap. */
unsigned char *zipmapNew(void) {
unsigned char *zm = zmalloc(2);
unsigned char *zm = zmalloc(2, MALLOC_SHARED);
zm[0] = 0; /* Length */
zm[1] = ZIPMAP_END;

View File

@ -70,6 +70,16 @@ void zlibc_free(void *ptr) {
#define mallocx(size,flags) je_mallocx(size,flags)
#define dallocx(ptr,flags) je_dallocx(ptr,flags)
#endif
#include "storage.h"
#undef malloc
#undef calloc
#undef realloc
#undef free
#define malloc(size, type) salloc(size, type)
#define calloc(count, size, type) scalloc(count, size, type)
#define realloc(ptr, size) srealloc(ptr, size)
#define free(ptr) sfree(ptr)
//#define zmalloc_size(ptr) (sizeof(ptr))
#define update_zmalloc_stat_alloc(__n) do { \
size_t _n = (__n); \
@ -95,8 +105,8 @@ static void zmalloc_default_oom(size_t size) {
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
void *zmalloc(size_t size) {
void *ptr = malloc(size+PREFIX_SIZE);
void *zmalloc(size_t size, enum MALLOC_CLASS class) {
void *ptr = malloc(size+PREFIX_SIZE, class);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
@ -127,8 +137,8 @@ void zfree_no_tcache(void *ptr) {
}
#endif
void *zcalloc(size_t size) {
void *ptr = calloc(1, size+PREFIX_SIZE);
void *zcalloc(size_t size, enum MALLOC_CLASS class) {
void *ptr = calloc(1, size+PREFIX_SIZE, class);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
@ -148,7 +158,7 @@ void *zrealloc(void *ptr, size_t size) {
size_t oldsize;
void *newptr;
if (ptr == NULL) return zmalloc(size);
if (ptr == NULL) return zmalloc(size, MALLOC_SHARED);
#ifdef HAVE_MALLOC_SIZE
oldsize = zmalloc_size(ptr);
newptr = realloc(ptr,size);
@ -207,7 +217,7 @@ void zfree(void *ptr) {
char *zstrdup(const char *s) {
size_t l = strlen(s)+1;
char *p = zmalloc(l);
char *p = zmalloc(l, MALLOC_SHARED);
memcpy(p,s,l);
return p;

View File

@ -35,7 +35,12 @@
#define __xstr(s) __str(s)
#define __str(s) #s
#if defined(USE_TCMALLOC)
#if 1
#define ZMALLOC_LIB ("custom")
#include "storage.h"
#undef USE_JEMALLOC
#define USE_MALLOC_CLASS 1
#elif defined(USE_TCMALLOC)
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h>
#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
@ -77,8 +82,8 @@
#define HAVE_DEFRAG
#endif
void *zmalloc(size_t size);
void *zcalloc(size_t size);
void *zmalloc(size_t size, enum MALLOC_CLASS class);
void *zcalloc(size_t size, enum MALLOC_CLASS class);
void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr);
char *zstrdup(const char *s);

View File

@ -71,7 +71,7 @@ int sortPointers(const void *a, const void *b) {
void stressGetKeys(dict *d, int times, int *perfect_run, int *approx_run) {
int j;
dictEntry **des = zmalloc(sizeof(dictEntry*)*dictSize(d));
dictEntry **des = zmalloc(sizeof(dictEntry*)*dictSize(d), MALLOC_SHARED);
for (j = 0; j < times; j++) {
int requested = rand() % (dictSize(d)+1);
int returned = dictGetSomeKeys(d, des, requested);