-
Notifications
You must be signed in to change notification settings - Fork 0
/
mem_pool.c
149 lines (144 loc) · 3.93 KB
/
mem_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
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
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdlib.h>
#include "mem_pool.h"
#define USED 0x80000000
#define MASK 0x7fffffff
void MPool_Init(MPool* pool,void* block,uint32_t length){
pool->tpool=block;
pool->tlength=length/4;
pool->curcur=0;
pool->tpool[0]=(pool->tlength)&MASK;
}
void *MPool_Allocate(MPool* pool,uint32_t length){
uint32_t curcur,lng,plen;
lng = (length+7)/4; // (length/4 with round up always) +1
curcur=pool->curcur;
while(curcur<pool->tlength){
plen=(pool->tpool[curcur]);
if(!(plen&USED))
if(plen>=lng)
{
if(plen>lng){
pool->tpool[curcur+lng]=plen-lng;
pool->tpool[curcur]=lng;
pool->curcur=curcur+lng;
}else{
pool->curcur=curcur+plen;
}
pool->tpool[curcur]|=USED;
return &(pool->tpool[curcur+1]);
}
curcur+=((pool->tpool[curcur])&MASK);
}
return NULL;
}
void MPool_Free(MPool* pool,void* buf){
uint32_t* unit=buf;
unit[-1]&=MASK;
}
void MPool_Collectfree(MPool* pool){
uint32_t cur,first,nwcc;
char ok,nwcc_set;
pool->curcur=0;
cur=0;
first=0;
ok=0;
nwcc=0; // new curcur
nwcc_set=0;
while(cur<(pool->tlength)){
if(pool->tpool[cur]&USED){
ok=0;
}else{
if(!nwcc_set){nwcc_set=1;nwcc=cur;}
if(ok){
pool->tpool[first] =
(pool->tpool[first]&MASK) +
(pool->tpool[cur]&MASK);
}else{ ok=1; first=cur; }
}
cur+=(pool->tpool[cur]&MASK);
}
pool->curcur=nwcc;
}
// Ex api - Advanced features for Advanced users
void MPool_Ex_Tryshrink(MPool* pool,void* buf,uint32_t nlength){
uint32_t nlng,skip;
//uint32_t* last = &(pool->tpool[pool->tlength]);
uint32_t* unit = buf;
nlng = (nlength+7)/4; // (length/4 with round up always) +1
unit--;
skip = (*unit)&MASK;
if( (skip-nlng)>2 ){
*unit = nlng|USED;
unit[nlng]=(skip-nlng)&MASK;
}
}
char MPool_Ex_Trygrow(MPool* pool,void* buf,uint32_t nlength){
uint32_t nlng,skip;
uint32_t* last = &(pool->tpool[pool->tlength]);
uint32_t* unit = buf;
nlng = (nlength+7)/4; // (length/4 with round up always) +1
unit--;
skip = (*unit)&MASK;
while((skip<nlng)){
if((&unit[skip])>=last)return 0;
if(unit[skip]&USED)return 0;
skip+=(unit[skip]&MASK);
}
if( (skip-nlng)>2 ){
*unit = nlng|USED;
unit[nlng]=(skip-nlng)&MASK;
}else{
*unit=skip|USED;
}
return 255;
}
void MPool_Ex_FreeCleanup(MPool* pool,void* buf){
uint32_t skip;
uint32_t* last = &(pool->tpool[pool->tlength]);
uint32_t* unit = buf;
unit--;
*unit &= MASK;
skip = *unit;
for(;;){
if((&unit[skip])>=last)break;
if(unit[skip]&USED)break;
skip+=(unit[skip]&MASK);
}
*unit=skip;
}
void *MPool_Ex_AllocJoin(MPool* pool,uint32_t length){
uint32_t curcur,lng,plen;
uint32_t i;
lng = (length+7)/4; // (length/4 with round up always) +1
curcur=pool->curcur;
while(curcur<pool->tlength){
plen=(pool->tpool[curcur]);
if(!(plen&USED))
{
i=curcur+plen;
while(i<pool->tlength){
if(pool->tpool[i]&USED)break;
if((i-curcur)>=lng)break;
i+=pool->tpool[i];
}
plen=i-curcur;
if(plen>=lng){
if(plen>lng){
pool->tpool[curcur+lng]=plen-lng;
pool->tpool[curcur]=lng;
pool->curcur=curcur+lng;
}else{
pool->curcur=curcur+plen;
}
pool->tpool[curcur]|=USED;
return &(pool->tpool[curcur+1]);
}
}
curcur+=((pool->tpool[curcur])&MASK);
}
return NULL;
}
void MPool_Ex_ResetAllocCursor(MPool* pool){
pool->curcur=0;
}
// xxx