oceanbase

Форк
0
/
easy_mod_stat.c 
91 строка · 2.3 Кб
1
#include "util/easy_mod_stat.h"
2
#include <string.h>
3

4
typedef struct alloc_stat_header_t {
5
    mod_stat_t* mod_stat;
6
    int64_t size;
7
} alloc_stat_header_t;
8

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;
14

15
static uint64_t rand64(uint64_t h)
16
{
17
    h ^= h >> 33;
18
    h *= 0xff51afd7ed558ccd;
19
    h ^= h >> 33;
20
    h *= 0xc4ceb9fe1a85ec53;
21
    h ^= h >> 33;
22
    return h;
23
}
24

25
static int try_set_slot(mod_stat_t* st, uint64_t id)
26
{
27
    uint64_t cur_id = __atomic_load_n(&st->id, __ATOMIC_SEQ_CST);
28

29
    if (cur_id != 0) {
30
        return cur_id == id;
31
    }
32
    return __sync_bool_compare_and_swap(&st->id, cur_id, id);
33
}
34

35
static mod_stat_t* get_mod_stat(uint64_t id)
36
{
37
    uint64_t i;
38
    uint64_t h = rand64(id);
39

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)) {
43
            return stat;
44
        }
45
    }
46
    return NULL;
47
}
48

49
static mod_stat_t* mod_stat_decode_header(alloc_stat_header_t* h, int64_t* size)
50
{
51
    *size = h->size;
52
    return h->mod_stat;
53
}
54

55
static mod_stat_t* mod_stat_encode_header(alloc_stat_header_t* h, mod_stat_t* stat, int64_t size)
56
{
57
    h->size = size;
58
    return h->mod_stat = stat;
59
}
60

61
static void update_mod_stat(mod_stat_t* stat, int64_t count_inc, int64_t size_inc)
62
{
63
    if (stat) {
64
        __sync_fetch_and_add(&stat->count, count_inc);
65
        __sync_fetch_and_add(&stat->size, size_inc);
66
    }
67
}
68

69
void* realloc_with_mod_stat(void* ptr, size_t size)
70
{
71
    const int64_t header_size = sizeof(alloc_stat_header_t);
72
    mod_stat_t* stat = NULL;
73
    if (ptr) {
74
        int64_t old_size = 0;
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);
78
    }
79
    ptr = realloc_lowlevel(ptr, size > 0 ? size + header_size : 0);
80
    if (ptr) {
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;
84
    }
85
    return ptr;
86
}
87

88
mod_stat_t* easy_fetch_mod_stat(uint64_t id)
89
{
90
    return get_mod_stat(id);
91
}
92

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.