-
Notifications
You must be signed in to change notification settings - Fork 9
/
Pool.c
92 lines (79 loc) · 2.38 KB
/
Pool.c
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
#include "Prototypes.h"
/*{
#define POOL_FREELIST_RATE 100
#define POOL_CHUNKLIST_RATE 10
#define POOL_CHUNK_SIZE 200
struct Pool_ {
int objectSize;
char* chunk;
int used;
char** freeList;
int freeListSize;
int freeListUsed;
char** chunkList;
int chunkListSize;
int chunkListUsed;
bool destroying;
};
}*/
static inline void Pool_addChunk(Pool* this) {
this->chunk = malloc(POOL_CHUNK_SIZE * this->objectSize);
this->chunkList[this->chunkListUsed++] = this->chunk;
this->used = 0;
}
Pool* Pool_new(ObjectClass* type) {
Pool* this = (Pool*) malloc(sizeof(Pool));
this->objectSize = type->size;
this->chunkListUsed = 0;
this->freeList = malloc(sizeof(void*) * POOL_FREELIST_RATE);
this->freeListSize = POOL_FREELIST_RATE;
this->freeListUsed = 0;
this->chunkListSize = POOL_CHUNKLIST_RATE;
this->chunkList = malloc(sizeof(void*) * this->chunkListSize);
this->destroying = false;
Pool_addChunk(this);
return this;
}
void Pool_initiateDestruction(Pool* this) {
this->destroying = true;
}
static inline void* Pool_allocateInChunk(Pool* this) {
void* result = this->chunk + (this->objectSize * this->used);
this->used++;
return result;
}
void* Pool_allocate(Pool* this) {
if (this->freeListUsed > 0)
return this->freeList[--this->freeListUsed];
if (this->used < POOL_CHUNK_SIZE)
return Pool_allocateInChunk(this);
else if (this->chunkListUsed < this->chunkListSize) {
Pool_addChunk(this);
return Pool_allocateInChunk(this);
} else {
this->chunkListSize += POOL_CHUNKLIST_RATE;
this->chunkList = realloc(this->chunkList, sizeof(void*) * this->chunkListSize);
Pool_addChunk(this);
return Pool_allocateInChunk(this);
}
}
inline void* Pool_allocateClear(Pool* this) {
return memset(Pool_allocate(this), 0, this->objectSize);
}
void Pool_free(Pool* this, void* item) {
if (this->destroying)
return;
assert(!(this->freeListUsed > this->freeListSize));
if (this->freeListUsed == this->freeListSize) {
this->freeListSize += POOL_FREELIST_RATE;
this->freeList = realloc(this->freeList, sizeof(void*) * this->freeListSize);
}
this->freeList[this->freeListUsed++] = item;
}
void Pool_delete(Pool* this) {
free(this->freeList);
for (int i = 0; i < this->chunkListUsed; i++)
free(this->chunkList[i]);
free(this->chunkList);
free(this);
}