Merge branch 'master' into directwrite

This commit is contained in:
Cloud Wu
2017-06-27 16:15:45 +08:00
5 changed files with 118 additions and 31 deletions

View File

@@ -9,17 +9,31 @@
#include "skynet.h"
#include "atomic.h"
// turn on MEMORY_CHECK can do more memory check, such as double free
// #define MEMORY_CHECK
#define MEMORY_ALLOCTAG 0x20140605
#define MEMORY_FREETAG 0x0badf00d
static size_t _used_memory = 0;
static size_t _memory_block = 0;
typedef struct _mem_data {
struct mem_data {
uint32_t handle;
ssize_t allocated;
} mem_data;
};
struct mem_cookie {
uint32_t handle;
#ifdef MEMORY_CHECK
uint32_t dogtag;
#endif
};
#define SLOT_SIZE 0x10000
#define PREFIX_SIZE sizeof(uint32_t)
#define PREFIX_SIZE sizeof(struct mem_cookie)
static mem_data mem_stats[SLOT_SIZE];
static struct mem_data mem_stats[SLOT_SIZE];
#ifndef NOUSE_JEMALLOC
@@ -33,7 +47,7 @@ static mem_data mem_stats[SLOT_SIZE];
static ssize_t*
get_allocated_field(uint32_t handle) {
int h = (int)(handle & (SLOT_SIZE - 1));
mem_data *data = &mem_stats[h];
struct mem_data *data = &mem_stats[h];
uint32_t old_handle = data->handle;
ssize_t old_alloc = data->allocated;
if(old_handle == 0 || old_alloc <= 0) {
@@ -75,9 +89,12 @@ inline static void*
fill_prefix(char* ptr) {
uint32_t handle = skynet_current_handle();
size_t size = je_malloc_usable_size(ptr);
uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t));
memcpy(p, &handle, sizeof(handle));
struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie));
memcpy(&p->handle, &handle, sizeof(handle));
#ifdef MEMORY_CHECK
uint32_t dogtag = MEMORY_ALLOCTAG;
memcpy(&p->dogtag, &dogtag, sizeof(dogtag));
#endif
update_xmalloc_stat_alloc(handle, size);
return ptr;
}
@@ -85,9 +102,19 @@ fill_prefix(char* ptr) {
inline static void*
clean_prefix(char* ptr) {
size_t size = je_malloc_usable_size(ptr);
uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t));
struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie));
uint32_t handle;
memcpy(&handle, p, sizeof(handle));
memcpy(&handle, &p->handle, sizeof(handle));
#ifdef MEMORY_CHECK
uint32_t dogtag;
memcpy(&dogtag, &p->dogtag, sizeof(dogtag));
if (dogtag == MEMORY_FREETAG) {
fprintf(stderr, "xmalloc: double free in :%08x\n", handle);
}
assert(dogtag == MEMORY_ALLOCTAG); // memory out of bounds
dogtag = MEMORY_FREETAG;
memcpy(&p->dogtag, &dogtag, sizeof(dogtag));
#endif
update_xmalloc_stat_free(handle, size);
return ptr;
}
@@ -168,6 +195,13 @@ skynet_calloc(size_t nmemb,size_t size) {
return fill_prefix(ptr);
}
void *
skynet_memalign(size_t alignment, size_t size) {
void* ptr = je_memalign(alignment, size + PREFIX_SIZE);
if(!ptr) malloc_oom(size);
return fill_prefix(ptr);
}
#else
// for skynet_lalloc use
@@ -209,7 +243,7 @@ dump_c_mem() {
size_t total = 0;
skynet_error(NULL, "dump all service mem:");
for(i=0; i<SLOT_SIZE; i++) {
mem_data* data = &mem_stats[i];
struct mem_data* data = &mem_stats[i];
if(data->handle != 0 && data->allocated != 0) {
total += data->allocated;
skynet_error(NULL, "0x%x -> %zdkb", data->handle, data->allocated >> 10);
@@ -241,7 +275,7 @@ dump_mem_lua(lua_State *L) {
int i;
lua_newtable(L);
for(i=0; i<SLOT_SIZE; i++) {
mem_data* data = &mem_stats[i];
struct mem_data* data = &mem_stats[i];
if(data->handle != 0 && data->allocated != 0) {
lua_pushinteger(L, data->allocated);
lua_rawseti(L, -2, (lua_Integer)data->handle);
@@ -255,7 +289,7 @@ malloc_current_memory(void) {
uint32_t handle = skynet_current_handle();
int i;
for(i=0; i<SLOT_SIZE; i++) {
mem_data* data = &mem_stats[i];
struct mem_data* data = &mem_stats[i];
if(data->handle == (uint32_t)handle && data->allocated != 0) {
return (size_t) data->allocated;
}

View File

@@ -7,6 +7,7 @@
#define skynet_calloc calloc
#define skynet_realloc realloc
#define skynet_free free
#define skynet_memalign memalign
void * skynet_malloc(size_t sz);
void * skynet_calloc(size_t nmemb,size_t size);
@@ -14,5 +15,6 @@ void * skynet_realloc(void *ptr, size_t size);
void skynet_free(void *ptr);
char * skynet_strdup(const char *str);
void * skynet_lalloc(void *ptr, size_t osize, size_t nsize); // use for lua
void * skynet_memalign(size_t alignment, size_t size);
#endif