1
#include "util/easy_mod_stat.h"
4
typedef struct alloc_stat_header_t {
9
#define MOD_STAT_COUNT (1<<16)
10
mod_stat_t global_mod_stat_table[MOD_STAT_COUNT];
11
__thread mod_stat_t* easy_cur_mod_stat;
12
extern void *easy_pool_default_realloc(void *ptr, size_t size);
13
void* (*realloc_lowlevel)(void*, size_t) = easy_pool_default_realloc;
15
static uint64_t rand64(uint64_t h)
18
h *= 0xff51afd7ed558ccd;
20
h *= 0xc4ceb9fe1a85ec53;
25
static int try_set_slot(mod_stat_t* st, uint64_t id)
27
uint64_t cur_id = __atomic_load_n(&st->id, __ATOMIC_SEQ_CST);
32
return __sync_bool_compare_and_swap(&st->id, cur_id, id);
35
static mod_stat_t* get_mod_stat(uint64_t id)
38
uint64_t h = rand64(id);
40
for (i = 0; i < MOD_STAT_COUNT; i++) {
41
mod_stat_t* stat = global_mod_stat_table + ((h + i) % MOD_STAT_COUNT);
42
if (try_set_slot(stat, id)) {
49
static mod_stat_t* mod_stat_decode_header(alloc_stat_header_t* h, int64_t* size)
55
static mod_stat_t* mod_stat_encode_header(alloc_stat_header_t* h, mod_stat_t* stat, int64_t size)
58
return h->mod_stat = stat;
61
static void update_mod_stat(mod_stat_t* stat, int64_t count_inc, int64_t size_inc)
64
__sync_fetch_and_add(&stat->count, count_inc);
65
__sync_fetch_and_add(&stat->size, size_inc);
69
void* realloc_with_mod_stat(void* ptr, size_t size)
71
const int64_t header_size = sizeof(alloc_stat_header_t);
72
mod_stat_t* stat = NULL;
75
ptr = (char*)ptr - header_size;
76
stat = mod_stat_decode_header((alloc_stat_header_t*)ptr, &old_size);
77
update_mod_stat(stat, -1, -old_size);
79
ptr = realloc_lowlevel(ptr, size > 0 ? size + header_size : 0);
81
stat = mod_stat_encode_header((alloc_stat_header_t*)ptr, easy_cur_mod_stat, size);
82
update_mod_stat(stat, 1, size);
83
ptr = (char*)ptr + header_size;
88
mod_stat_t* easy_fetch_mod_stat(uint64_t id)
90
return get_mod_stat(id);