Custom flash heap

Former-commit-id: 5c86d2faa2e504d8ccfcafd5646717fef3d333cc
This commit is contained in:
John Sully 2019-01-29 18:10:46 -05:00
parent 0fac4c665f
commit 9b94405241
59 changed files with 443 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 else
# All the other OSes (notably Linux) # All the other OSes (notably Linux)
FINAL_LDFLAGS+= -rdynamic FINAL_LDFLAGS+= -rdynamic
FINAL_LIBS+=-ldl -pthread -lrt FINAL_LIBS+=-ldl -pthread -lrt -lmemkind
endif endif
endif endif
endif endif
@ -164,11 +164,11 @@ endif
REDIS_SERVER_NAME=redis-server REDIS_SERVER_NAME=redis-server
REDIS_SENTINEL_NAME=redis-sentinel 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_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_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_RDB_NAME=redis-check-rdb
REDIS_CHECK_AOF_NAME=redis-check-aof 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. */ * If the user with such name already exists NULL is returned. */
user *ACLCreateUser(const char *name, size_t namelen) { user *ACLCreateUser(const char *name, size_t namelen) {
if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL; 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->name = sdsnewlen(name,namelen);
u->flags = 0; u->flags = 0;
u->allowed_subcommands = NULL; 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. */ * this user, we have to allocate the subcommands array. */
if (u->allowed_subcommands == NULL) { if (u->allowed_subcommands == NULL) {
u->allowed_subcommands = zcalloc(USER_COMMAND_BITS_COUNT * u->allowed_subcommands = zcalloc(USER_COMMAND_BITS_COUNT *
sizeof(sds*)); sizeof(sds*), MALLOC_LOCAL);
} }
/* We also need to enlarge the allocation pointing to the /* We also need to enlarge the allocation pointing to the

View File

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

View File

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

View File

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

View File

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

View File

@ -42,7 +42,7 @@ static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState)); aeApiState *state = zmalloc(sizeof(aeApiState));
if (!state) return -1; 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) { if (!state->events) {
zfree(state); zfree(state);
return -1; return -1;

View File

@ -40,7 +40,7 @@ typedef struct aeApiState {
} aeApiState; } aeApiState;
static int aeApiCreate(aeEventLoop *eventLoop) { static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState)); aeApiState *state = zmalloc(sizeof(aeApiState), MALLOC_LOCAL);
if (!state) return -1; if (!state) return -1;
FD_ZERO(&state->rfds); 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. */ if (len) { /* First block to allocate, or need another block. */
int numblocks; int numblocks;
block = zmalloc(sizeof(*block)); block = zmalloc(sizeof(*block), MALLOC_LOCAL);
block->free = AOF_RW_BUF_BLOCK_SIZE; block->free = AOF_RW_BUF_BLOCK_SIZE;
block->used = 0; block->used = 0;
listAddNodeTail(server.aof_rewrite_buf_blocks,block); 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 /* 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. */ * order to load the append only file we need to create a fake client. */
struct client *createFakeClient(void) { struct client *createFakeClient(void) {
struct client *c = zmalloc(sizeof(*c)); struct client *c = zmalloc(sizeof(*c), MALLOC_LOCAL);
selectDb(c,0); selectDb(c,0);
c->fd = -1; c->fd = -1;
@ -752,7 +752,7 @@ int loadAppendOnlyFile(char *filename) {
argc = atoi(buf+1); argc = atoi(buf+1);
if (argc < 1) goto fmterr; if (argc < 1) goto fmterr;
argv = zmalloc(sizeof(robj*)*argc); argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
fakeClient->argc = argc; fakeClient->argc = argc;
fakeClient->argv = argv; fakeClient->argv = argv;

View File

@ -129,7 +129,7 @@ void bioInit(void) {
} }
void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) { 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->time = time(NULL);
job->arg1 = arg1; 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. */ /* Lookup keys, and store pointers to the string objects into an array. */
numkeys = c->argc - 3; numkeys = c->argc - 3;
src = zmalloc(sizeof(unsigned char*) * numkeys); src = zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL);
len = zmalloc(sizeof(long) * numkeys); len = zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL);
objects = zmalloc(sizeof(robj*) * numkeys); objects = zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL);
for (j = 0; j < numkeys; j++) { for (j = 0; j < numkeys; j++) {
o = lookupKeyRead(c->db,c->argv[j+3]); o = lookupKeyRead(c->db,c->argv[j+3]);
/* Handle non-existing keys as empty strings. */ /* 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. */ * is NULL for lists and sorted sets, or the stream ID for streams. */
void *key_data = NULL; void *key_data = NULL;
if (btype == BLOCKED_STREAM) { if (btype == BLOCKED_STREAM) {
key_data = zmalloc(sizeof(streamID)); key_data = zmalloc(sizeof(streamID), MALLOC_SHARED);
memcpy(key_data,ids+j,sizeof(streamID)); 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; if (dictFind(db->ready_keys,key) != NULL) return;
/* Ok, we need to queue this key into server.ready_keys. */ /* 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->key = key;
rl->db = db; rl->db = db;
incrRefCount(key); incrRefCount(key);

View File

@ -119,7 +119,7 @@ int clusterLoadConfig(char *filename) {
* *
* To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */ * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */
maxline = 1024+CLUSTER_SLOTS*128; maxline = 1024+CLUSTER_SLOTS*128;
line = zmalloc(maxline); line = zmalloc(maxline, MALLOC_LOCAL);
while(fgets(line,maxline,fp) != NULL) { while(fgets(line,maxline,fp) != NULL) {
int argc; int argc;
sds *argv; sds *argv;
@ -429,7 +429,7 @@ void clusterUpdateMyselfFlags(void) {
void clusterInit(void) { void clusterInit(void) {
int saveconf = 0; int saveconf = 0;
server.cluster = zmalloc(sizeof(clusterState)); server.cluster = zmalloc(sizeof(clusterState), MALLOC_LOCAL);
server.cluster->myself = NULL; server.cluster->myself = NULL;
server.cluster->currentEpoch = 0; server.cluster->currentEpoch = 0;
server.cluster->state = CLUSTER_FAIL; server.cluster->state = CLUSTER_FAIL;
@ -587,7 +587,7 @@ void clusterReset(int hard) {
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
clusterLink *createClusterLink(clusterNode *node) { clusterLink *createClusterLink(clusterNode *node) {
clusterLink *link = zmalloc(sizeof(*link)); clusterLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL);
link->ctime = mstime(); link->ctime = mstime();
link->sndbuf = sdsempty(); link->sndbuf = sdsempty();
link->rcvbuf = 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 * The node is created and returned to the user, but it is not automatically
* added to the nodes hash table. */ * added to the nodes hash table. */
clusterNode *createClusterNode(char *nodename, int flags) { clusterNode *createClusterNode(char *nodename, int flags) {
clusterNode *node = zmalloc(sizeof(*node)); clusterNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL);
if (nodename) if (nodename)
memcpy(node->name, nodename, CLUSTER_NAMELEN); memcpy(node->name, nodename, CLUSTER_NAMELEN);
@ -749,7 +749,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) {
} }
/* Otherwise create a new report. */ /* Otherwise create a new report. */
fr = zmalloc(sizeof(*fr)); fr = zmalloc(sizeof(*fr), MALLOC_LOCAL);
fr->node = sender; fr->node = sender;
fr->time = mstime(); fr->time = mstime();
listAddNodeTail(l,fr); listAddNodeTail(l,fr);
@ -2401,7 +2401,7 @@ void clusterSendPing(clusterLink *link, int type) {
/* Note: clusterBuildMessageHdr() expects the buffer to be always at least /* Note: clusterBuildMessageHdr() expects the buffer to be always at least
* sizeof(clusterMsg) or more. */ * sizeof(clusterMsg) or more. */
if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg); if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg);
buf = zcalloc(totlen); buf = zcalloc(totlen, MALLOC_LOCAL);
hdr = (clusterMsg*) buf; hdr = (clusterMsg*) buf;
/* Populate the header. */ /* Populate the header. */
@ -2538,7 +2538,7 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) {
if (totlen < sizeof(buf)) { if (totlen < sizeof(buf)) {
payload = buf; payload = buf;
} else { } else {
payload = zmalloc(totlen); payload = zmalloc(totlen, MALLOC_LOCAL);
memcpy(payload,hdr,sizeof(*hdr)); memcpy(payload,hdr,sizeof(*hdr));
hdr = (clusterMsg*) payload; hdr = (clusterMsg*) payload;
} }
@ -2607,7 +2607,7 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type,
if (totlen < sizeof(buf)) { if (totlen < sizeof(buf)) {
heapbuf = buf; heapbuf = buf;
} else { } else {
heapbuf = zmalloc(totlen); heapbuf = zmalloc(totlen, MALLOC_LOCAL);
memcpy(heapbuf,hdr,sizeof(*hdr)); memcpy(heapbuf,hdr,sizeof(*hdr));
hdr = (clusterMsg*) heapbuf; hdr = (clusterMsg*) heapbuf;
} }
@ -4277,7 +4277,7 @@ NULL
/* CLUSTER ADDSLOTS <slot> [slot] ... */ /* CLUSTER ADDSLOTS <slot> [slot] ... */
/* CLUSTER DELSLOTS <slot> [slot] ... */ /* CLUSTER DELSLOTS <slot> [slot] ... */
int j, 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"); int del = !strcasecmp(c->argv[1]->ptr,"delslots");
memset(slots,0,CLUSTER_SLOTS); memset(slots,0,CLUSTER_SLOTS);
@ -4546,7 +4546,7 @@ NULL
unsigned int keys_in_slot = countKeysInSlot(slot); unsigned int keys_in_slot = countKeysInSlot(slot);
if (maxkeys > keys_in_slot) maxkeys = keys_in_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); numkeys = getKeysInSlot(slot, keys, maxkeys);
addReplyArrayLen(c,numkeys); addReplyArrayLen(c,numkeys);
for (j = 0; j < numkeys; j++) { 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. */ /* Add to the cache and return it to the caller. */
cs = zmalloc(sizeof(*cs)); cs = zmalloc(sizeof(*cs), MALLOC_LOCAL);
cs->fd = fd; cs->fd = fd;
cs->last_dbid = -1; cs->last_dbid = -1;
cs->last_use_time = server.unixtime; 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). * 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" * We allocate num_keys+1 because the additional argument is for "DEL"
* command name itself. */ * 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++) { for (j = 0; j < num_keys; j++) {
if (syncReadLine(cs->fd, buf2, sizeof(buf2), timeout) <= 0) { 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; int i;
struct moduleLoadQueueEntry *loadmod; struct moduleLoadQueueEntry *loadmod;
loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry)); loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL);
loadmod->argv = zmalloc(sizeof(robj*)*argc); loadmod->argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
loadmod->path = sdsnew(path); loadmod->path = sdsnew(path);
loadmod->argc = argc; loadmod->argc = argc;
for (i = 0; i < argc; i++) { 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. */ * If the old file does not exist at all, an empty state is returned. */
struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
FILE *fp = fopen(path,"r"); 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]; char buf[CONFIG_MAX_LINE+1];
int linenum = -1; int linenum = -1;

1
src/core.REMOVED.git-id Normal file
View File

@ -0,0 +1 @@
f6027990a0231d80395d15f8f867d3a31eea285d

View File

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

View File

@ -345,7 +345,7 @@ NULL
restartServer(flags,delay); restartServer(flags,delay);
addReplyError(c,"failed to restart the server. Check server logs."); addReplyError(c,"failed to restart the server. Check server logs.");
} else if (!strcasecmp(c->argv[1]->ptr,"oom")) { } 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); zfree(ptr);
addReply(c,shared.ok); addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"assert")) { } 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. /* move this allocation to a new allocation.
* make sure not to use the thread cache. so that we don't get back the same * make sure not to use the thread cache. so that we don't get back the same
* pointers we try to free */ * pointers we try to free */
size = zmalloc_size(ptr); size = zmalloc_size(ptr, MALLOC_LOCAL);
newptr = zmalloc_no_tcache(size); newptr = zmalloc_no_tcache(size, MALLOC_LOCAL);
memcpy(newptr, ptr, size); memcpy(newptr, ptr, size);
zfree_no_tcache(ptr); zfree_no_tcache(ptr);
return newptr; return newptr;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -71,10 +71,10 @@ void lwTranslatePixelsGroup(int byte, char *output) {
/* Allocate and return a new canvas of the specified size. */ /* Allocate and return a new canvas of the specified size. */
lwCanvas *lwCreateCanvas(int width, int height) { lwCanvas *lwCreateCanvas(int width, int height) {
lwCanvas *canvas = zmalloc(sizeof(*canvas)); lwCanvas *canvas = zmalloc(sizeof(*canvas), MALLOC_SHARED);
canvas->width = width; canvas->width = width;
canvas->height = height; canvas->height = height;
canvas->pixels = zmalloc(width*height); canvas->pixels = zmalloc(width*height, MALLOC_SHARED);
memset(canvas->pixels,0,width*height); memset(canvas->pixels,0,width*height);
return canvas; 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. * and in general is taken into account as memory allocated by Redis.
* You should avoid using malloc(). */ * You should avoid using malloc(). */
void *RM_Alloc(size_t bytes) { 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 /* 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. * and in general is taken into account as memory allocated by Redis.
* You should avoid using calloc() directly. */ * You should avoid using calloc() directly. */
void *RM_Calloc(size_t nmemb, size_t size) { 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(). */ /* Use like realloc() for memory obtained with RedisModule_Alloc(). */
@ -354,7 +354,7 @@ void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) {
if (left < bytes) { if (left < bytes) {
size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE; size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE;
if (blocksize < bytes) blocksize = bytes; if (blocksize < bytes) blocksize = bytes;
b = zmalloc(sizeof(*b) + blocksize); b = zmalloc(sizeof(*b) + blocksize, MALLOC_LOCAL);
b->size = blocksize; b->size = blocksize;
b->used = 0; b->used = 0;
b->next = ctx->pa_head; 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 * Note that we use the Redis command table 'getkeys_proc' in order to
* pass a reference to the command proxy structure. */ * pass a reference to the command proxy structure. */
cp = zmalloc(sizeof(*cp)); cp = zmalloc(sizeof(*cp), MALLOC_LOCAL);
cp->module = ctx->module; cp->module = ctx->module;
cp->func = cmdfunc; cp->func = cmdfunc;
cp->rediscmd = zmalloc(sizeof(*rediscmd)); cp->rediscmd = zmalloc(sizeof(*rediscmd), MALLOC_LOCAL);
cp->rediscmd->name = cmdname; cp->rediscmd->name = cmdname;
cp->rediscmd->proc = RedisModuleCommandDispatcher; cp->rediscmd->proc = RedisModuleCommandDispatcher;
cp->rediscmd->arity = -1; cp->rediscmd->arity = -1;
@ -695,7 +695,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
RedisModule *module; RedisModule *module;
if (ctx->module != NULL) return; if (ctx->module != NULL) return;
module = zmalloc(sizeof(*module)); module = zmalloc(sizeof(*module), MALLOC_LOCAL);
module->name = sdsnew((char*)name); module->name = sdsnew((char*)name);
module->ver = ver; module->ver = ver;
module->apiver = apiver; module->apiver = apiver;
@ -1470,7 +1470,7 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
} }
/* Setup the key handle. */ /* Setup the key handle. */
kp = zmalloc(sizeof(*kp)); kp = zmalloc(sizeof(*kp), MALLOC_LOCAL);
kp->ctx = ctx; kp->ctx = ctx;
kp->db = ctx->client->db; kp->db = ctx->client->db;
kp->key = keyname; 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 * is processed as needed. Initially we just make sure to set the right
* reply type, which is extremely cheap to do. */ * reply type, which is extremely cheap to do. */
RedisModuleCallReply *moduleCreateCallReplyFromProto(RedisModuleCtx *ctx, sds proto) { RedisModuleCallReply *moduleCreateCallReplyFromProto(RedisModuleCtx *ctx, sds proto) {
RedisModuleCallReply *reply = zmalloc(sizeof(*reply)); RedisModuleCallReply *reply = zmalloc(sizeof(*reply), MALLOC_LOCAL);
reply->ctx = ctx; reply->ctx = ctx;
reply->proto = proto; reply->proto = proto;
reply->protolen = sdslen(proto); reply->protolen = sdslen(proto);
@ -2482,7 +2482,7 @@ void moduleParseCallReply_Array(RedisModuleCallReply *reply) {
return; return;
} }
reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen); reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen, MALLOC_LOCAL);
reply->len = arraylen; reply->len = arraylen;
for (j = 0; j < arraylen; j++) { for (j = 0; j < arraylen; j++) {
RedisModuleCallReply *ele = reply->val.array+j; RedisModuleCallReply *ele = reply->val.array+j;
@ -2996,7 +2996,7 @@ moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver,
moduleTypeFreeFunc free; moduleTypeFreeFunc free;
} *tms = (struct typemethods*) typemethods_ptr; } *tms = (struct typemethods*) typemethods_ptr;
moduleType *mt = zcalloc(sizeof(*mt)); moduleType *mt = zcalloc(sizeof(*mt), MALLOC_LOCAL);
mt->id = id; mt->id = id;
mt->module = ctx->module; mt->module = ctx->module;
mt->rdb_load = tms->rdb_load; 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) { RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) {
if (io->ctx) return io->ctx; /* Can't have more than one... */ if (io->ctx) return io->ctx; /* Can't have more than one... */
RedisModuleCtx ctxtemplate = REDISMODULE_CTX_INIT; RedisModuleCtx ctxtemplate = REDISMODULE_CTX_INIT;
io->ctx = zmalloc(sizeof(RedisModuleCtx)); io->ctx = zmalloc(sizeof(RedisModuleCtx), MALLOC_LOCAL);
*(io->ctx) = ctxtemplate; *(io->ctx) = ctxtemplate;
io->ctx->module = io->type->module; io->ctx->module = io->type->module;
io->ctx->client = NULL; io->ctx->client = NULL;
@ -3530,7 +3530,7 @@ RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc
int islua = c->flags & CLIENT_LUA; int islua = c->flags & CLIENT_LUA;
int ismulti = c->flags & CLIENT_MULTI; 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; RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
/* We need to handle the invalid operation of calling modules blocking /* 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 * TODO: thread safe contexts do not inherit the blocked client
* selected database. */ * selected database. */
RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) { RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) {
RedisModuleCtx *ctx = zmalloc(sizeof(*ctx)); RedisModuleCtx *ctx = zmalloc(sizeof(*ctx), MALLOC_LOCAL);
RedisModuleCtx empty = REDISMODULE_CTX_INIT; RedisModuleCtx empty = REDISMODULE_CTX_INIT;
memcpy(ctx,&empty,sizeof(empty)); memcpy(ctx,&empty,sizeof(empty));
if (bc) { if (bc) {
@ -3880,7 +3880,7 @@ void moduleReleaseGIL(void) {
* See https://redis.io/topics/notifications for more information. * See https://redis.io/topics/notifications for more information.
*/ */
int RM_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc callback) { 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->module = ctx->module;
sub->event_mask = types; sub->event_mask = types;
sub->notify_callback = callback; sub->notify_callback = callback;
@ -4017,7 +4017,7 @@ void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisM
/* Not found, let's add it. */ /* Not found, let's add it. */
if (callback) { if (callback) {
r = zmalloc(sizeof(*r)); r = zmalloc(sizeof(*r), MALLOC_LOCAL);
r->module_id = module_id; r->module_id = module_id;
r->module = ctx->module; r->module = ctx->module;
r->callback = callback; r->callback = callback;
@ -4069,14 +4069,14 @@ char **RM_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes) {
if (!server.cluster_enabled) return NULL; if (!server.cluster_enabled) return NULL;
size_t count = dictSize(server.cluster->nodes); 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); dictIterator *di = dictGetIterator(server.cluster->nodes);
dictEntry *de; dictEntry *de;
int j = 0; int j = 0;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = dictGetVal(de);
if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue; 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); memcpy(ids[j],node->name,REDISMODULE_NODE_ID_LEN);
j++; 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 * 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. */ * 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) { 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->module = ctx->module;
timer->callback = callback; timer->callback = callback;
timer->data = data; timer->data = data;
@ -4367,7 +4367,7 @@ int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remain
* Next / Prev dictionary iterator calls. * Next / Prev dictionary iterator calls.
*/ */
RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) { RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) {
struct RedisModuleDict *d = zmalloc(sizeof(*d)); struct RedisModuleDict *d = zmalloc(sizeof(*d), MALLOC_LOCAL);
d->rax = raxNew(); d->rax = raxNew();
if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d); if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d);
return 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. * 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 *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; di->dict = d;
raxStart(&di->ri,d->rax); raxStart(&di->ri,d->rax);
raxSeek(&di->ri,op,key,keylen); raxSeek(&di->ri,op,key,keylen);

View File

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

View File

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

View File

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

View File

@ -209,7 +209,7 @@ int pubsubSubscribePattern(client *c, robj *pattern) {
pubsubPattern *pat; pubsubPattern *pat;
listAddNodeTail(c->pubsub_patterns,pattern); listAddNodeTail(c->pubsub_patterns,pattern);
incrRefCount(pattern); incrRefCount(pattern);
pat = zmalloc(sizeof(*pat)); pat = zmalloc(sizeof(*pat), MALLOC_LOCAL);
pat->pattern = getDecodedObject(pattern); pat->pattern = getDecodedObject(pattern);
pat->client = c; pat->client = c;
listAddNodeTail(server.pubsub_patterns,pat); 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) { quicklist *quicklistCreate(void) {
struct quicklist *quicklist; struct quicklist *quicklist;
quicklist = zmalloc(sizeof(*quicklist)); quicklist = zmalloc(sizeof(*quicklist), MALLOC_SHARED);
quicklist->head = quicklist->tail = NULL; quicklist->head = quicklist->tail = NULL;
quicklist->len = 0; quicklist->len = 0;
quicklist->count = 0; quicklist->count = 0;
@ -137,7 +137,7 @@ quicklist *quicklistNew(int fill, int compress) {
REDIS_STATIC quicklistNode *quicklistCreateNode(void) { REDIS_STATIC quicklistNode *quicklistCreateNode(void) {
quicklistNode *node; quicklistNode *node;
node = zmalloc(sizeof(*node)); node = zmalloc(sizeof(*node), MALLOC_SHARED);
node->zl = NULL; node->zl = NULL;
node->count = 0; node->count = 0;
node->sz = 0; node->sz = 0;
@ -184,7 +184,7 @@ REDIS_STATIC int __quicklistCompressNode(quicklistNode *node) {
if (node->sz < MIN_COMPRESS_BYTES) if (node->sz < MIN_COMPRESS_BYTES)
return 0; 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 */ /* Cancel if compression fails or doesn't compress small enough */
if (((lzf->sz = lzf_compress(node->zl, node->sz, lzf->compressed, 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; node->attempted_compress = 0;
#endif #endif
void *decompressed = zmalloc(node->sz); void *decompressed = zmalloc(node->sz, MALLOC_SHARED);
quicklistLZF *lzf = (quicklistLZF *)node->zl; quicklistLZF *lzf = (quicklistLZF *)node->zl;
if (lzf_decompress(lzf->compressed, lzf->sz, decompressed, node->sz) == 0) { if (lzf_decompress(lzf->compressed, lzf->sz, decompressed, node->sz) == 0) {
/* Someone requested decompress, but we can't decompress. Not good. */ /* 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; size_t zl_sz = node->sz;
quicklistNode *new_node = quicklistCreateNode(); 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 */ /* Copy original ziplist so we can split it */
memcpy(new_node->zl, node->zl, zl_sz); 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 *quicklistGetIterator(const quicklist *quicklist, int direction) {
quicklistIter *iter; quicklistIter *iter;
iter = zmalloc(sizeof(*iter)); iter = zmalloc(sizeof(*iter), MALLOC_LOCAL);
if (direction == AL_START_HEAD) { if (direction == AL_START_HEAD) {
iter->current = quicklist->head; iter->current = quicklist->head;
@ -1195,10 +1195,10 @@ quicklist *quicklistDup(quicklist *orig) {
if (current->encoding == QUICKLIST_NODE_ENCODING_LZF) { if (current->encoding == QUICKLIST_NODE_ENCODING_LZF) {
quicklistLZF *lzf = (quicklistLZF *)current->zl; quicklistLZF *lzf = (quicklistLZF *)current->zl;
size_t lzf_sz = sizeof(*lzf) + lzf->sz; 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); memcpy(node->zl, current->zl, lzf_sz);
} else if (current->encoding == QUICKLIST_NODE_ENCODING_RAW) { } 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); 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) { REDIS_STATIC void *_quicklistSaver(unsigned char *data, unsigned int sz) {
unsigned char *vstr; unsigned char *vstr;
if (data) { if (data) {
vstr = zmalloc(sz); vstr = zmalloc(sz, MALLOC_SHARED);
memcpy(vstr, data, sz); memcpy(vstr, data, sz);
return vstr; return vstr;
} }

View File

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

View File

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

View File

@ -45,6 +45,7 @@
#include "hiredis.h" #include "hiredis.h"
#include "adlist.h" #include "adlist.h"
#include "zmalloc.h" #include "zmalloc.h"
#include "storage.h"
#define UNUSED(V) ((void) V) #define UNUSED(V) ((void) V)
#define RANDPTR_INITIAL_SIZE 8 #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.*/ * Even when cloning another client, prefix commands are applied if needed.*/
static client createClient(char *cmd, size_t len, client from) { static client createClient(char *cmd, size_t len, client from) {
int j; int j;
client c = zmalloc(sizeof(struct _client)); client c = zmalloc(sizeof(struct _client), MALLOC_LOCAL);
if (config.hostsocket == NULL) { if (config.hostsocket == NULL) {
c->context = redisConnectNonBlock(config.hostip,config.hostport); c->context = redisConnectNonBlock(config.hostip,config.hostport);
@ -379,7 +380,7 @@ static client createClient(char *cmd, size_t len, client from) {
if (from) { if (from) {
c->randlen = from->randlen; c->randlen = from->randlen;
c->randfree = 0; c->randfree = 0;
c->randptr = zmalloc(sizeof(char*)*c->randlen); c->randptr = zmalloc(sizeof(char*)*c->randlen, MALLOC_LOCAL);
/* copy the offsets. */ /* copy the offsets. */
for (j = 0; j < (int)c->randlen; j++) { for (j = 0; j < (int)c->randlen; j++) {
c->randptr[j] = c->obuf + (from->randptr[j]-from->obuf); 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->randlen = 0;
c->randfree = RANDPTR_INITIAL_SIZE; 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) { while ((p = strstr(p,"__rand_int__")) != NULL) {
if (c->randfree == 0) { if (c->randfree == 0) {
c->randptr = zrealloc(c->randptr,sizeof(char*)*c->randlen*2); c->randptr = zrealloc(c->randptr,sizeof(char*)*c->randlen*2);
@ -652,6 +653,8 @@ int main(int argc, const char **argv) {
client c; client c;
storage_init();
srandom(time(NULL)); srandom(time(NULL));
signal(SIGHUP, SIG_IGN); signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
@ -684,7 +687,7 @@ int main(int argc, const char **argv) {
argc -= i; argc -= i;
argv += 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) { 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"); 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. */ /* Run default benchmark suite. */
data = zmalloc(config.datasize+1); data = zmalloc(config.datasize+1, MALLOC_LOCAL);
do { do {
memset(data,'x',config.datasize); memset(data,'x',config.datasize);
data[config.datasize] = '\0'; data[config.datasize] = '\0';

View File

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

View File

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

View File

@ -76,7 +76,7 @@ char *replicationGetSlaveName(client *c) {
void createReplicationBacklog(void) { void createReplicationBacklog(void) {
serverAssert(server.repl_backlog == NULL); 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_histlen = 0;
server.repl_backlog_idx = 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 * worse often we need to alloc additional space before freeing the
* old buffer. */ * old buffer. */
zfree(server.repl_backlog); 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_histlen = 0;
server.repl_backlog_idx = 0; server.repl_backlog_idx = 0;
/* Next byte we have is... the next since the buffer is empty. */ /* 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; int j;
*r = rioFdsetIO; *r = rioFdsetIO;
r->io.fdset.fds = zmalloc(sizeof(int)*numfds); r->io.fdset.fds = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL);
r->io.fdset.state = zmalloc(sizeof(int)*numfds); r->io.fdset.state = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL);
memcpy(r->io.fdset.fds,fds,sizeof(int)*numfds); memcpy(r->io.fdset.fds,fds,sizeof(int)*numfds);
for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0; for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0;
r->io.fdset.numfds = numfds; r->io.fdset.numfds = numfds;

View File

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

View File

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

View File

@ -37,6 +37,10 @@
* to use the default libc allocator). */ * to use the default libc allocator). */
#include "zmalloc.h" #include "zmalloc.h"
#define s_malloc zmalloc #include "storage.h"
#define s_realloc zrealloc //#define s_malloc zmalloc
#define s_free zfree #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; return C_ERR;
/* Create container for context and r/w events */ /* Create container for context and r/w events */
e = (redisAeEvents*)zmalloc(sizeof(*e)); e = (redisAeEvents*)zmalloc(sizeof(*e), MALLOC_LOCAL);
e->context = ac; e->context = ac;
e->loop = loop; e->loop = loop;
e->fd = c->fd; e->fd = c->fd;
@ -549,7 +549,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
errno = ENOENT; errno = ENOENT;
return NULL; return NULL;
} }
sa = zmalloc(sizeof(*sa)); sa = zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(ip); sa->ip = sdsnew(ip);
sa->port = port; sa->port = port;
return sa; return sa;
@ -559,7 +559,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
sentinelAddr *dupSentinelAddr(sentinelAddr *src) { sentinelAddr *dupSentinelAddr(sentinelAddr *src) {
sentinelAddr *sa; sentinelAddr *sa;
sa = zmalloc(sizeof(*sa)); sa = zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(src->ip); sa->ip = sdsnew(src->ip);
sa->port = src->port; sa->port = src->port;
return sa; return sa;
@ -703,10 +703,10 @@ void sentinelScheduleScriptExecution(char *path, ...) {
va_end(ap); va_end(ap);
argv[0] = sdsnew(path); argv[0] = sdsnew(path);
sj = zmalloc(sizeof(*sj)); sj = zmalloc(sizeof(*sj), MALLOC_LOCAL);
sj->flags = SENTINEL_SCRIPT_NONE; sj->flags = SENTINEL_SCRIPT_NONE;
sj->retry_num = 0; 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->start_time = 0;
sj->pid = 0; sj->pid = 0;
memcpy(sj->argv,argv,sizeof(char*)*(argc+1)); 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. */ /* Create a not yet connected link object. */
instanceLink *createInstanceLink(void) { instanceLink *createInstanceLink(void) {
instanceLink *link = zmalloc(sizeof(*link)); instanceLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL);
link->refcount = 1; link->refcount = 1;
link->disconnected = 1; link->disconnected = 1;
@ -1200,7 +1200,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
} }
/* Create the instance object. */ /* 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, /* Note that all the instances are started in the disconnected state,
* the event loop will take care of connecting them. */ * the event loop will take care of connecting them. */
ri->flags = flags; ri->flags = flags;
@ -4091,7 +4091,7 @@ int compareSlavesForPromotion(const void *a, const void *b) {
sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) { sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
sentinelRedisInstance **instance = sentinelRedisInstance **instance =
zmalloc(sizeof(instance[0])*dictSize(master->slaves)); zmalloc(sizeof(instance[0])*dictSize(master->slaves), MALLOC_LOCAL);
sentinelRedisInstance *selected = NULL; sentinelRedisInstance *selected = NULL;
int instances = 0; int instances = 0;
dictIterator *di; dictIterator *di;

View File

@ -33,6 +33,7 @@
#include "bio.h" #include "bio.h"
#include "latency.h" #include "latency.h"
#include "atomicvar.h" #include "atomicvar.h"
#include "storage.h"
#include <time.h> #include <time.h>
#include <signal.h> #include <signal.h>
@ -2729,7 +2730,7 @@ void initServer(void) {
strerror(errno)); strerror(errno));
exit(1); 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. */ /* Open the TCP listening socket for the user commands. */
if (server.port != 0 && 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. */ 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++) { for (j = 0; j < argc; j++) {
argvcopy[j] = argv[j]; argvcopy[j] = argv[j];
incrRefCount(argv[j]); incrRefCount(argv[j]);
@ -4481,7 +4482,7 @@ void usage(void) {
void redisAsciiArt(void) { void redisAsciiArt(void) {
#include "asciilogo.h" #include "asciilogo.h"
char *buf = zmalloc(1024*16); char *buf = zmalloc(1024*16, MALLOC_LOCAL);
char *mode; char *mode;
if (server.cluster_enabled) mode = "cluster"; if (server.cluster_enabled) mode = "cluster";
@ -4739,6 +4740,8 @@ int main(int argc, char **argv) {
struct timeval tv; struct timeval tv;
int j; int j;
storage_init();
#ifdef REDIS_TEST #ifdef REDIS_TEST
if (argc == 3 && !strcasecmp(argv[1], "test")) { if (argc == 3 && !strcasecmp(argv[1], "test")) {
if (!strcasecmp(argv[2], "ziplist")) { 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 /* Store the executable path and arguments in a safe place in order
* to be able to restart the server later. */ * to be able to restart the server later. */
server.executable = getAbsolutePath(argv[0]); 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; server.exec_argv[argc] = NULL;
for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]); 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 * Incrementing the ref count of all the objects retained is up to
* this function. */ * this function. */
slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) { 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; int j, slargc = argc;
if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC; if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
se->argc = slargc; se->argc = slargc;
se->argv = zmalloc(sizeof(robj*)*slargc); se->argv = zmalloc(sizeof(robj*)*slargc, MALLOC_LOCAL);
for (j = 0; j < slargc; j++) { for (j = 0; j < slargc; j++) {
/* Logging too many arguments is a useless memory waste, so we stop /* Logging too many arguments is a useless memory waste, so we stop
* at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify * 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); zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
redisSortOperation *createSortOperation(int type, robj *pattern) { redisSortOperation *createSortOperation(int type, robj *pattern) {
redisSortOperation *so = zmalloc(sizeof(*so)); redisSortOperation *so = zmalloc(sizeof(*so), MALLOC_LOCAL);
so->type = type; so->type = type;
so->pattern = pattern; so->pattern = pattern;
return so; return so;
@ -340,7 +340,7 @@ void sortCommand(client *c) {
} }
/* Load the sorting vector with all the objects to sort */ /* Load the sorting vector with all the objects to sort */
vector = zmalloc(sizeof(redisSortObject)*vectorlen); vector = zmalloc(sizeof(redisSortObject)*vectorlen, MALLOC_LOCAL);
j = 0; j = 0;
if (sortval->type == OBJ_LIST && dontsort) { if (sortval->type == OBJ_LIST && dontsort) {

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ size_t streamReplyWithRangeFromConsumerPEL(client *c, stream *s, streamID *start
/* Create a new stream data structure. */ /* Create a new stream data structure. */
stream *streamNew(void) { stream *streamNew(void) {
stream *s = zmalloc(sizeof(*s)); stream *s = zmalloc(sizeof(*s), MALLOC_SHARED);
s->rax = raxNew(); s->rax = raxNew();
s->length = 0; s->length = 0;
s->last_id.ms = 0; s->last_id.ms = 0;
@ -1402,8 +1402,8 @@ void xreadCommand(client *c) {
/* Parse the IDs and resolve the group name. */ /* Parse the IDs and resolve the group name. */
if (streams_count > STREAMID_STATIC_VECTOR_LEN) if (streams_count > STREAMID_STATIC_VECTOR_LEN)
ids = zmalloc(sizeof(streamID)*streams_count); ids = zmalloc(sizeof(streamID)*streams_count, MALLOC_SHARED);
if (groupname) groups = zmalloc(sizeof(streamCG*)*streams_count); if (groupname) groups = zmalloc(sizeof(streamCG*)*streams_count, MALLOC_SHARED);
for (int i = streams_arg + streams_count; i < c->argc; i++) { for (int i = streams_arg + streams_count; i < c->argc; i++) {
/* Specifying "$" as last-known-id means that the client wants to be /* 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 * time to the current time. The NACK consumer will be set to the one
* specified as argument of the function. */ * specified as argument of the function. */
streamNACK *streamCreateNACK(streamConsumer *consumer) { streamNACK *streamCreateNACK(streamConsumer *consumer) {
streamNACK *nack = zmalloc(sizeof(*nack)); streamNACK *nack = zmalloc(sizeof(*nack), MALLOC_SHARED);
nack->delivery_time = mstime(); nack->delivery_time = mstime();
nack->delivery_count = 1; nack->delivery_count = 1;
nack->consumer = consumer; 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) if (raxFind(s->cgroups,(unsigned char*)name,namelen) != raxNotFound)
return NULL; return NULL;
streamCG *cg = zmalloc(sizeof(*cg)); streamCG *cg = zmalloc(sizeof(*cg), MALLOC_SHARED);
cg->pel = raxNew(); cg->pel = raxNew();
cg->consumers = raxNew(); cg->consumers = raxNew();
cg->last_id = *id; cg->last_id = *id;
@ -1661,7 +1661,7 @@ streamConsumer *streamLookupConsumer(streamCG *cg, sds name, int create) {
sdslen(name)); sdslen(name));
if (consumer == raxNotFound) { if (consumer == raxNotFound) {
if (!create) return NULL; if (!create) return NULL;
consumer = zmalloc(sizeof(*consumer)); consumer = zmalloc(sizeof(*consumer), MALLOC_SHARED);
consumer->name = sdsdup(name); consumer->name = sdsdup(name);
consumer->pel = raxNew(); consumer->pel = raxNew();
raxInsert(cg->consumers,(unsigned char*)name,sdslen(name), 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. */ * The SDS string 'ele' is referenced by the node after the call. */
zskiplistNode *zslCreateNode(int level, double score, sds ele) { zskiplistNode *zslCreateNode(int level, double score, sds ele) {
zskiplistNode *zn = zskiplistNode *zn =
zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel)); zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel), MALLOC_SHARED);
zn->score = score; zn->score = score;
zn->ele = ele; zn->ele = ele;
return zn; return zn;
@ -81,7 +81,7 @@ zskiplist *zslCreate(void) {
int j; int j;
zskiplist *zsl; zskiplist *zsl;
zsl = zmalloc(sizeof(*zsl)); zsl = zmalloc(sizeof(*zsl), MALLOC_SHARED);
zsl->level = 1; zsl->level = 1;
zsl->length = 0; zsl->length = 0;
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL); zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
@ -1182,7 +1182,7 @@ void zsetConvert(robj *zobj, int encoding) {
if (encoding != OBJ_ENCODING_SKIPLIST) if (encoding != OBJ_ENCODING_SKIPLIST)
serverPanic("Unknown target encoding"); serverPanic("Unknown target encoding");
zs = zmalloc(sizeof(*zs)); zs = zmalloc(sizeof(*zs), MALLOC_SHARED);
zs->dict = dictCreate(&zsetDictType,NULL); zs->dict = dictCreate(&zsetDictType,NULL);
zs->zsl = zslCreate(); 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 /* Start parsing all the scores, we need to emit any syntax error
* before executing additions to the sorted set, as the command should * before executing additions to the sorted set, as the command should
* either execute fully or nothing at all. */ * 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++) { for (j = 0; j < elements; j++) {
if (getDoubleFromObjectOrReply(c,c->argv[scoreidx+j*2],&scores[j],NULL) if (getDoubleFromObjectOrReply(c,c->argv[scoreidx+j*2],&scores[j],NULL)
!= C_OK) goto cleanup; != C_OK) goto cleanup;
@ -2203,7 +2203,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
} }
/* read keys to be used for input */ /* 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++) { for (i = 0, j = 3; i < setnum; i++, j++) {
robj *obj = lookupKeyWrite(c->db,c->argv[j]); robj *obj = lookupKeyWrite(c->db,c->argv[j]);
if (obj != NULL) { if (obj != NULL) {

View File

@ -577,7 +577,7 @@ void zipEntry(unsigned char *p, zlentry *e) {
/* Create a new empty ziplist. */ /* Create a new empty ziplist. */
unsigned char *ziplistNew(void) { unsigned char *ziplistNew(void) {
unsigned int bytes = ZIPLIST_HEADER_SIZE+1; 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_BYTES(zl) = intrev32ifbe(bytes);
ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE); ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE);
ZIPLIST_LENGTH(zl) = 0; ZIPLIST_LENGTH(zl) = 0;

View File

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

View File

@ -70,6 +70,16 @@ void zlibc_free(void *ptr) {
#define mallocx(size,flags) je_mallocx(size,flags) #define mallocx(size,flags) je_mallocx(size,flags)
#define dallocx(ptr,flags) je_dallocx(ptr,flags) #define dallocx(ptr,flags) je_dallocx(ptr,flags)
#endif #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 { \ #define update_zmalloc_stat_alloc(__n) do { \
size_t _n = (__n); \ 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; static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
void *zmalloc(size_t size) { void *zmalloc(size_t size, enum MALLOC_CLASS class) {
void *ptr = malloc(size+PREFIX_SIZE); void *ptr = malloc(size+PREFIX_SIZE, class);
if (!ptr) zmalloc_oom_handler(size); if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE #ifdef HAVE_MALLOC_SIZE
@ -127,8 +137,8 @@ void zfree_no_tcache(void *ptr) {
} }
#endif #endif
void *zcalloc(size_t size) { void *zcalloc(size_t size, enum MALLOC_CLASS class) {
void *ptr = calloc(1, size+PREFIX_SIZE); void *ptr = calloc(1, size+PREFIX_SIZE, class);
if (!ptr) zmalloc_oom_handler(size); if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE #ifdef HAVE_MALLOC_SIZE
@ -148,7 +158,7 @@ void *zrealloc(void *ptr, size_t size) {
size_t oldsize; size_t oldsize;
void *newptr; void *newptr;
if (ptr == NULL) return zmalloc(size); if (ptr == NULL) return zmalloc(size, MALLOC_SHARED);
#ifdef HAVE_MALLOC_SIZE #ifdef HAVE_MALLOC_SIZE
oldsize = zmalloc_size(ptr); oldsize = zmalloc_size(ptr);
newptr = realloc(ptr,size); newptr = realloc(ptr,size);
@ -207,7 +217,7 @@ void zfree(void *ptr) {
char *zstrdup(const char *s) { char *zstrdup(const char *s) {
size_t l = strlen(s)+1; size_t l = strlen(s)+1;
char *p = zmalloc(l); char *p = zmalloc(l, MALLOC_SHARED);
memcpy(p,s,l); memcpy(p,s,l);
return p; return p;

View File

@ -35,7 +35,12 @@
#define __xstr(s) __str(s) #define __xstr(s) __str(s)
#define __str(s) #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)) #define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h> #include <google/tcmalloc.h>
#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1) #if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
@ -77,8 +82,8 @@
#define HAVE_DEFRAG #define HAVE_DEFRAG
#endif #endif
void *zmalloc(size_t size); void *zmalloc(size_t size, enum MALLOC_CLASS class);
void *zcalloc(size_t size); void *zcalloc(size_t size, enum MALLOC_CLASS class);
void *zrealloc(void *ptr, size_t size); void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr); void zfree(void *ptr);
char *zstrdup(const char *s); 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) { void stressGetKeys(dict *d, int times, int *perfect_run, int *approx_run) {
int j; int j;
dictEntry **des = zmalloc(sizeof(dictEntry*)*dictSize(d)); dictEntry **des = zmalloc(sizeof(dictEntry*)*dictSize(d), MALLOC_SHARED);
for (j = 0; j < times; j++) { for (j = 0; j < times; j++) {
int requested = rand() % (dictSize(d)+1); int requested = rand() % (dictSize(d)+1);
int returned = dictGetSomeKeys(d, des, requested); int returned = dictGetSomeKeys(d, des, requested);