Merge pull request #91 from cloudwu/jemalloc

Use macro for memory hook
This commit is contained in:
云风
2014-04-18 23:42:06 +08:00
23 changed files with 142 additions and 81 deletions

View File

@@ -20,7 +20,6 @@ $(LUA_STATICLIB) :
JEMALLOC_STATICLIB := 3rd/jemalloc/lib/libjemalloc_pic.a
JEMALLOC_INC := 3rd/jemalloc/include/jemalloc
NOBUILDIN_MALLOC := -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free -fno-builtin-memalign
all : jemalloc
.PHONY : jemalloc
@@ -28,10 +27,10 @@ all : jemalloc
$(JEMALLOC_STATICLIB) : 3rd/jemalloc/Makefile
cd 3rd/jemalloc && $(MAKE) CC=$(CC)
3rd/jemalloc :
3rd/jemalloc/autogen.sh :
git submodule update --init
3rd/jemalloc/Makefile : | 3rd/jemalloc
3rd/jemalloc/Makefile : | 3rd/jemalloc/autogen.sh
cd 3rd/jemalloc && ./autogen.sh --with-jemalloc-prefix=je_ --disable-valgrind
jemalloc : $(JEMALLOC_STATICLIB)
@@ -52,7 +51,7 @@ all : \
$(foreach v, $(LUA_CLIB), $(LUA_CLIB_PATH)/$(v).so)
$(SKYNET_BUILD_PATH)/skynet : $(foreach v, $(SKYNET_SRC), skynet-src/$(v)) $(LUA_LIB) $(JEMALLOC_STATICLIB)
$(CC) $(CFLAGS) $(NOBUILDIN_MALLOC) -o $@ $^ -Iskynet-src -I$(JEMALLOC_INC) $(LDFLAGS) $(EXPORT) $(LIBS)
$(CC) $(CFLAGS) -o $@ $^ -Iskynet-src -I$(JEMALLOC_INC) $(LDFLAGS) $(EXPORT) $(LIBS)
$(LUA_CLIB_PATH) :
mkdir $(LUA_CLIB_PATH)
@@ -77,10 +76,10 @@ $(LUA_CLIB_PATH)/int64.so : 3rd/lua-int64/int64.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(LUA_CLIB_PATH)/bson.so : lualib-src/lua-bson.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
$(LUA_CLIB_PATH)/mongo.so : lualib-src/lua-mongo.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
$(LUA_CLIB_PATH)/md5.so : 3rd/lua-md5/md5.c 3rd/lua-md5/md5lib.c 3rd/lua-md5/compat-5.2.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -I3rd/lua-md5 $^ -o $@

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include <lua.h>
#include <lauxlib.h>

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include <lua.h>
#include <lauxlib.h>

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include <lua.h>
#include <lauxlib.h>

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_socket.h"
#include <lua.h>

View File

@@ -2,6 +2,9 @@
https://github.com/cloudwu/lua-serialize
*/
// include skynet.h first for malloc hook
#include "skynet.h"
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

View File

@@ -586,14 +586,14 @@ harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) {
char local_addr[sz];
int harbor_id = 0;
sscanf(args,"%s %s %d",master_addr, local_addr, &harbor_id);
h->master_addr = strdup(master_addr);
h->master_addr = skynet_strdup(master_addr);
h->id = harbor_id;
h->master_fd = _connect_to(h, master_addr, true);
if (h->master_fd == -1) {
fprintf(stderr, "Harbor: Connect to master failed\n");
exit(1);
}
h->local_addr = strdup(local_addr);
h->local_addr = skynet_strdup(local_addr);
_launch_gate(ctx, local_addr);
skynet_callback(ctx, h, _mainloop);

View File

@@ -267,7 +267,7 @@ struct snlua *
snlua_create(void) {
struct snlua * l = malloc(sizeof(*l));
memset(l,0,sizeof(*l));
l->L = luaL_newstate();
l->L = lua_newstate(skynet_lalloc, NULL);
l->init = _init;
return l;
}

View File

@@ -3,36 +3,37 @@
#include <assert.h>
#include "malloc_hook.h"
#include "jemalloc.h"
#include "skynet.h"
static size_t _used_memory = 0;
static size_t _memory_block = 0;
typedef struct _mem_data {
uint32_t handle;
size_t allocated;
ssize_t allocated;
} mem_data;
#define SLOT_SIZE 0xffff
#define SLOT_SIZE 0x10000
#define PREFIX_SIZE sizeof(uint32_t)
static mem_data mem_stats[SLOT_SIZE];
static void _init() {
memset(mem_stats, 0, sizeof(mem_stats));
}
static size_t*
get_allocated_field(handle) {
int h = (handle & SLOT_SIZE) - 1;
get_allocated_field(uint32_t handle) {
int h = (int)(handle & (SLOT_SIZE - 1));
mem_data *data = &mem_stats[h];
if(data->handle == 0 || data->allocated == 0) {
__sync_synchronize();
if(!__sync_bool_compare_and_swap(&data->handle, 0, handle)) {
return 0;
}
uint32_t old_handle = data->handle;
ssize_t old_alloc = data->allocated;
if(old_handle == 0 || old_alloc <= 0) {
// data->allocated may less than zero, because it may not count at start.
if(!__sync_bool_compare_and_swap(&data->handle, old_handle, handle)) {
return 0;
}
if (old_alloc < 0) {
__sync_bool_compare_and_swap(&data->allocated, old_alloc, 0);
}
}
if(data->handle != handle) {
return 0;
@@ -73,8 +74,7 @@ fill_prefix(char* ptr) {
inline static void*
clean_prefix(char* ptr) {
uint32_t* rawptr = (uint32_t*)ptr - 1;
size_t size = je_malloc_usable_size(rawptr);
size_t size = je_malloc_usable_size(ptr);
uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t));
uint32_t handle;
memcpy(&handle, p, sizeof(handle));
@@ -89,50 +89,6 @@ static void malloc_oom(size_t size) {
abort();
}
// hook : malloc, realloc, memalign, free, calloc
void *
malloc(size_t size) {
void* ptr = je_malloc(size + PREFIX_SIZE);
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
void *
realloc(void *ptr, size_t size) {
if (ptr == NULL) return malloc(size);
void* rawptr = clean_prefix(ptr);
void *newptr = je_realloc(rawptr, size+PREFIX_SIZE);
if(!newptr) malloc_oom(size);
return fill_prefix(newptr);
}
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
void *
memalign(size_t alignment, size_t size) {
void *ptr = je_memalign(alignment, size+PREFIX_SIZE);
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
#endif
void
free(void *ptr) {
if (ptr == NULL) return;
void* rawptr = clean_prefix(ptr);
je_free(rawptr);
}
void *
calloc(size_t nmemb,size_t size) {
void* ptr = je_calloc(nmemb + ((PREFIX_SIZE+size-1)/size), size );
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
size_t
malloc_used_memory(void) {
return _used_memory;
@@ -191,10 +147,54 @@ dump_c_mem() {
printf("+total: %zdkb\n",total >> 10);
}
/*
* init
*/
void __attribute__ ((constructor)) malloc_hook_init(void){
_init();
// hook : malloc, realloc, memalign, free, calloc
void *
skynet_malloc(size_t size) {
void* ptr = je_malloc(size + PREFIX_SIZE);
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
void *
skynet_realloc(void *ptr, size_t size) {
if (ptr == NULL) return malloc(size);
void* rawptr = clean_prefix(ptr);
void *newptr = je_realloc(rawptr, size+PREFIX_SIZE);
if(!newptr) malloc_oom(size);
return fill_prefix(newptr);
}
void
skynet_free(void *ptr) {
if (ptr == NULL) return;
void* rawptr = clean_prefix(ptr);
je_free(rawptr);
}
void *
skynet_calloc(size_t nmemb,size_t size) {
void* ptr = je_calloc(nmemb + ((PREFIX_SIZE+size-1)/size), size );
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
char *
skynet_strdup(const char *str) {
size_t sz = strlen(str);
char * ret = skynet_malloc(sz+1);
memcpy(ret, str, sz+1);
return ret;
}
void *
skynet_lalloc(void *ud, void *ptr, size_t osize, size_t nsize) {
if (nsize == 0) {
skynet_free(ptr);
return NULL;
} else {
return skynet_realloc(ptr, nsize);
}
}

View File

@@ -1,5 +1,6 @@
#ifndef __MALLOC_HOOK_H
#define __MALLOC_HOOK_H
#include <stdlib.h>
extern size_t malloc_used_memory(void);

View File

@@ -1,6 +1,8 @@
#ifndef SKYNET_H
#define SKYNET_H
#include "skynet_malloc.h"
#include <stddef.h>
#include <stdint.h>

View File

@@ -1,3 +1,5 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_env.h"
#include <lua.h>

View File

@@ -29,7 +29,7 @@ skynet_error(struct skynet_context * context, const char *msg, ...) {
int len = vsnprintf(tmp, LOG_MESSAGE_SIZE, msg, ap);
va_end(ap);
if (len < LOG_MESSAGE_SIZE) {
data = strdup(tmp);
data = skynet_strdup(tmp);
} else {
int max_size = LOG_MESSAGE_SIZE;
for (;;) {

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_handle.h"
#include "skynet_server.h"
#include "rwlock.h"
@@ -204,7 +207,7 @@ _insert_name(struct handle_storage *s, const char * name, uint32_t handle) {
end = mid - 1;
}
}
char * result = strdup(name);
char * result = skynet_strdup(name);
_insert_name_before(s, result, handle, begin);

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_imp.h"
#include "skynet_env.h"

View File

@@ -0,0 +1,18 @@
#ifndef skynet_malloc_h
#define skynet_malloc_h
#include <stddef.h>
#define malloc skynet_malloc
#define calloc skynet_calloc
#define realloc skynet_realloc
#define free skynet_free
void * skynet_malloc(size_t sz);
void * skynet_calloc(size_t nmemb,size_t size);
void * skynet_realloc(void *ptr, size_t size);
void skynet_free(void *ptr);
char * skynet_strdup(const char *str);
void * skynet_lalloc(void *ud, void *ptr, size_t osize, size_t nsize); // use for lua
#endif

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_module.h"
#include <assert.h>
@@ -103,7 +106,7 @@ skynet_module_query(const char * name) {
M->m[index].module = dl;
if (_open_sym(&M->m[index]) == 0) {
M->m[index].name = strdup(name);
M->m[index].name = skynet_strdup(name);
M->count ++;
result = &M->m[index];
}
@@ -152,7 +155,7 @@ void
skynet_module_init(const char *path) {
struct modules *m = malloc(sizeof(*m));
m->count = 0;
m->path = strdup(path);
m->path = skynet_strdup(path);
m->lock = 0;
M = m;

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_monitor.h"
#include "skynet_server.h"
#include "skynet.h"

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_server.h"
#include "skynet_module.h"
#include "skynet_handle.h"
@@ -5,7 +8,6 @@
#include "skynet_timer.h"
#include "skynet_harbor.h"
#include "skynet_env.h"
#include "skynet.h"
#include "skynet_monitor.h"
#include <string.h>

View File

@@ -1,9 +1,11 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_socket.h"
#include "socket_server.h"
#include "skynet_server.h"
#include "skynet_mq.h"
#include "skynet_harbor.h"
#include "skynet.h"
#include <assert.h>
#include <stdlib.h>

View File

@@ -1,8 +1,10 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "skynet_timer.h"
#include "skynet_mq.h"
#include "skynet_server.h"
#include "skynet_handle.h"
#include "skynet.h"
#include <time.h>
#include <assert.h>

View File

@@ -1,3 +1,6 @@
// include skynet.h first for malloc hook
#include "skynet.h"
#include "socket_server.h"
#include "socket_poll.h"