-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPool.h
137 lines (130 loc) · 4.2 KB
/
Pool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*!
* \file Pool.h
* \brief 固定長メモリプールからの動的メモリの確保と解放
* \author KATO Noriaki <[email protected]>
* \date 2006-03-22
*
* 必要ならば排他制御をすること。
*
* \par 使用例
*
* \code
* #include "Pool.h"
* Pool pool;
* int buf[256];
* #define malloc(s) Pool_malloc(&pool, s)
* #define realloc(p, s) Pool_realloc(&pool, p, s)
* #define free(p) Pool_free(&pool, p)
*
* int main(void)
* {
* int i;
* char *hoge;
* Pool_init(&pool, buf, sizeof buf, sizeof buf[0]);
* hoge = Pool_malloc(&pool, 16);
* for (i = 0; i < 16; i++) {
* hoge[i] = i;
* }
* Pool_free(&pool, hoge);
*
* hoge = malloc(64);
* for (i = 0; i < 64; i++) {
* hoge[i] = i;
* }
* hoge = realloc(hoge, 128);
* for (i = 64; i < 128; i++) {
* hoge[i] = i;
* }
* free(hoge);
*
* POOL_DUMP_LEAK(&pool, 1);
* return 0;
* }
* \endcode
*/
#ifndef POOL_H_INCLUDED
#define POOL_H_INCLUDED
#include <stddef.h>
/*
* POOL_SLISTをマクロ定義した場合(メモリブロックリストが単方向リスト)
* - メモリブロックヘッダのサイズがポインタ一つ分小さくなる。
* - freeの計算量がO(n)になる。
*
* POOL_SLISTをマクロ定義しない場合(メモリブロックリストが双方向リスト)
* - メモリブロックヘッダのサイズがポインタ一つ分大きくなる。
* - freeの計算量がO(1)になる。
*
* POOL_DEBUGをマクロ定義した場合、メモリリーク、バッファオーバーフロー、
* メモリ確保失敗、不正なポインタの解放などの検出ができる。
*/
/*!
* \brief メモリブロックヘッダ構造体
*/
struct BlockHeader {
#ifndef POOL_SLIST
struct BlockHeader *prev;
#endif
struct BlockHeader *next;
size_t size; /* ブロックのサイズ(ヘッダのサイズも含む) */
unsigned char occupied; /* 使用中フラグ */
unsigned char magic; /* マジックナンバー */
#ifdef POOL_DEBUG
const char *file; /* ファイル名 */
size_t line; /* ファイルの行番号 */
size_t alloc_size; /* ユーザが指定したサイズ */
#endif
};
/*!
* \brief メモリプール構造体
*
* メモリブロックヘッダのリストを持つ
*/
typedef struct Pool {
struct BlockHeader list_term; /* メモリブロックリストターミネータ */
struct BlockHeader *loop_p; /* ループ用ポインタ */
struct Pool *init_flag;
size_t align_size;
size_t header_size;
#ifdef POOL_DEBUG
size_t wall_size;
int fail_count;
#endif
} Pool;
#ifdef __cplusplus
extern "C" {
#endif
void Pool_init(Pool *self, void *buf, size_t size, size_t alignment);
#ifdef POOL_DEBUG
void *Pool_malloc_debug(Pool *self, size_t size, const char *file, size_t line);
void *Pool_realloc_debug(Pool *self, void *ptr, size_t newsize, const char *file, size_t line);
void Pool_free_debug(Pool *self, void *ptr, const char *file, size_t line);
void hex_dump(void *buf, size_t size);
size_t Pool_dump_leak(Pool *self, int dump);
void Pool_dump_block(Pool *self, void *ptr);
void Pool_dump_list(Pool *self);
int Pool_check_overflow(Pool *self, void *ptr);
void Pool_dump_overflow(Pool *self);
#define Pool_malloc(self, s) Pool_malloc_debug(self, s, __FILE__, __LINE__)
#define Pool_realloc(self, p, s) Pool_realloc_debug(self, p, s, __FILE__, __LINE__)
#define Pool_free(self, p) Pool_free_debug(self, p, __FILE__, __LINE__)
#define POOL_DUMP_LEAK(self, d) Pool_dump_leak(self, d)
#define POOL_DUMP_BLOCK(self, p) Pool_dump_block(self, p)
#define POOL_DUMP_LIST(self) Pool_dump_list(self)
#define POOL_DUMP_OVERFLOW(self) Pool_dump_overflow(self)
#define POOL_SET_FAIL_COUNT(self, c) (self)->fail_count = (c)
#define POOL_RESET_FAIL_COUNT(self) (self)->fail_count = -1
#else
void *Pool_malloc(Pool *self, size_t size);
void *Pool_realloc(Pool *self, void *ptr, size_t newsize);
void Pool_free(Pool *self, void *ptr);
#define POOL_DUMP_LEAK(self, d)
#define POOL_DUMP_BLOCK(self, p)
#define POOL_DUMP_LIST(self)
#define POOL_DUMP_OVERFLOW(self)
#define POOL_SET_FAIL_COUNT(self, c)
#define POOL_RESET_FAIL_COUNT(self)
#endif
#ifdef __cplusplus
}
#endif
#endif /* POOL_H_INCLUDED */