omAllocPrivate.h
Go to the documentation of this file.
1 /*******************************************************************
2  * File: omAllocPrivate.h
3  * Purpose: declaration of "private" (but visible to the outside)
4  * routines for omalloc
5  * Author: obachman (Olaf Bachmann)
6  * Created: 11/99
7  *******************************************************************/
8 #ifndef OM_ALLOC_PRIVATE_H
9 #define OM_ALLOC_PRIVATE_H
10 
11 /*******************************************************************
12  *
13  * Definitions of structures we work with
14  *
15  *******************************************************************/
16 /* Need to define it here, has to be known to macros */
18 {
19  long used_blocks; /* number of used blocks of this page */
20  void* current; /* pointer to current freelist */
21  omBinPage next; /* next/prev pointer of pages */
23  void* bin_sticky; /* bin this page belongs to with
24  sticky tag of page hidden in ptr */
25  omBinPageRegion region; /* BinPageRegion of this page */
26 };
27 
28 /* Change this appropriately, if you change omBinPage */
29 /* However, make sure that omBinPage is a multiple of SIZEOF_MAX_TYPE */
30 #define SIZEOF_OM_BIN_PAGE_HEADER (5*SIZEOF_VOIDP + SIZEOF_LONG)
31 #define SIZEOF_OM_BIN_PAGE (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE_HEADER)
32 
33 /* keep all members of omBin_s a sizeof(long) type,
34  otherwise list operations will fail */
35 struct omBin_s
36 {
37  omBinPage current_page; /* page of current freelist */
38  omBinPage last_page; /* pointer to last page of freelist */
39  omBin next; /* sticky bins of the same size */
40  size_t sizeW; /* size in words */
41  long max_blocks; /* if > 0 # blocks in one page,
42  if < 0 # pages for one block */
43  unsigned long sticky; /* sticky tag */
44 };
45 
47 {
48  omSpecBin next; /* pointer to next bin */
49  omBin bin; /* pointer to bin itself */
50  long max_blocks; /* max_blocks of bin*/
51  long ref; /* ref count */
52 };
53 
54 extern omSpecBin om_SpecBin;
55 extern omBin om_StickyBins;
56 extern omBinPage_t om_ZeroPage[];
57 extern omBin om_Size2Bin[];
58 
59 /*******************************************************************
60  *
61  * Working with pages/bins
62  *
63  *******************************************************************/
64 #define omGetTopBinOfPage(page) \
65  ((omBin) ( ((unsigned long) ((page)->bin_sticky)) & ~((unsigned long)SIZEOF_VOIDP - 1)))
66 #define omGetStickyOfPage(page) \
67  (((unsigned long) ((page)->bin_sticky)) & ((unsigned long)SIZEOF_VOIDP-1))
68 #define omSetTopBinOfPage(page, bin) \
69  (page)->bin_sticky= (void*)((unsigned long)bin + omGetStickyOfPage(page))
70 #define omSetStickyOfPage(page, sticky) \
71  (page)->bin_sticky = (void*)(((unsigned long)sticky & ((unsigned long)SIZEOF_VOIDP-1)) + \
72  (unsigned long)omGetTopBinOfPage(page))
73 #define omSetTopBinAndStickyOfPage(page, bin, sticky) \
74  (page)->bin_sticky= (void*)(((unsigned long)sticky & (SIZEOF_VOIDP-1)) \
75  + (unsigned long)bin)
76 
77 #define omGetTopBinOfAddr(addr) \
78  omGetTopBinOfPage(((omBinPage) omGetPageOfAddr(addr)))
79 #define omGetBinOfAddr(addr) omGetBinOfPage(omGetBinPageOfAddr(addr))
80 
81 #ifndef OM_GENERATE_INC
82 extern omBin_t om_StaticBin[];
83 extern omBin om_Size2Bin[];
84 #ifdef OM_ALIGNMENT_NEEDS_WORK
85 extern omBin om_Size2AlignedBin[];
86 #endif
87 
88 /*******************************************************************
89  *
90  * SizeOfAddr
91  *
92  *******************************************************************/
93 #ifdef OM_INTERNAL_DEBUG
94 size_t omSizeOfBinAddr(void* addr);
95 #else
96 #define omSizeOfBinAddr(addr) _omSizeOfBinAddr(addr)
97 #endif
98 
99 #define omSizeWOfBin(bin_ptr) ((bin_ptr)->sizeW)
100 
101 #define _omSizeOfBinAddr(addr) ((omSizeWOfBinAddr(addr)) << LOG_SIZEOF_LONG)
102 #define omSizeWOfBinAddr(addr) ((omGetTopBinOfAddr(addr))->sizeW)
103 
104 /*******************************************************************
105  *
106  * lowest level alloc/free macros
107  *
108  *******************************************************************/
109 extern void* omAllocBinFromFullPage(omBin bin);
110 extern void omFreeToPageFault(omBinPage page, void* addr);
111 
112 /*******************************************************************/
113 /* Page */
114 #define __omTypeAllocFromNonEmptyPage(type, addr, page) \
115 do \
116 { \
117  ((page)->used_blocks)++; \
118  addr = (type)((page)->current); \
119  (page)->current = *((void**) (page)->current); \
120 } \
121 while (0)
122 
123 #define __omFreeToPage(addr, page) \
124 do \
125 { \
126  if ((page)->used_blocks > 0L) \
127  { \
128  *((void**) (addr)) = (page)->current; \
129  ((page)->used_blocks)--; \
130  (page)->current = (addr); \
131  } \
132  else \
133  { \
134  omFreeToPageFault(page, addr); \
135  } \
136 } \
137 while (0)
138 
139 
140 /*******************************************************************/
141 /* Bin */
142 #define __omTypeAllocBin(type, addr, bin) \
143 do \
144 { \
145  register omBinPage __om_page = (bin)->current_page; \
146  if (__om_page->current != NULL) \
147  __omTypeAllocFromNonEmptyPage(type, addr, __om_page); \
148  else \
149  addr = (type) omAllocBinFromFullPage(bin); \
150 } \
151 while (0)
152 
153 #define __omTypeAlloc0Bin(type, addr, bin) \
154 do \
155 { \
156  __omTypeAllocBin(type, addr, bin); \
157  omMemsetW(addr, 0, (bin)->sizeW); \
158 } \
159 while (0)
160 
161 
162 #define __omFreeBinAddr(addr) \
163 do \
164 { \
165  register void* __om_addr = (void*) (addr); \
166  register omBinPage __om_page = omGetBinPageOfAddr(__om_addr); \
167  __omFreeToPage(__om_addr, __om_page); \
168 } \
169 while (0)
170 
171 #define __omTypeReallocBin(old_addr, old_bin, new_type, new_addr, new_bin) \
172 do \
173 { \
174  if (old_bin != new_bin) \
175  { \
176  size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr)); \
177  __omTypeAllocBin(new_type, new_addr, new_bin); \
178  omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW)); \
179  __omFreeBinAddr(old_addr); \
180  } \
181  else \
182  { \
183  new_addr = (new_type) old_addr; \
184  } \
185 } \
186 while (0)
187 
188 
189 #define __omTypeRealloc0Bin(old_addr, old_bin, new_type, new_addr, new_bin) \
190 do \
191 { \
192  if (old_bin != new_bin) \
193  { \
194  size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr)); \
195  __omTypeAllocBin(new_type, new_addr, new_bin); \
196  omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW)); \
197  if (new_bin->sizeW > old_sizeW) \
198  omMemsetW((void**)new_addr + old_sizeW, 0, new_bin->sizeW - old_sizeW); \
199  __omFreeBinAddr(old_addr); \
200  } \
201  else \
202  { \
203  new_addr = (new_type) old_addr; \
204  } \
205 } \
206 while (0)
207 
208 /*******************************************************************/
209 /* Size */
210 #define omSmallSize2Bin(size) om_Size2Bin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
211 
212 #define __omTypeAlloc(type, addr, size) \
213 do \
214 { \
215  size_t __size = size; \
216  if (__size <= OM_MAX_BLOCK_SIZE) \
217  { \
218  omBin __om_bin = omSmallSize2Bin(__size); \
219  __omTypeAllocBin(type, addr, __om_bin); \
220  } \
221  else \
222  { \
223  addr = (type) omAllocLarge(__size); \
224  } \
225 } \
226 while(0)
227 
228 #define __omTypeAlloc0(type, addr, size) \
229 do \
230 { \
231  size_t __size = size; \
232  if (__size <= OM_MAX_BLOCK_SIZE) \
233  { \
234  omBin __om_bin = omSmallSize2Bin(__size); \
235  __omTypeAlloc0Bin(type, addr, __om_bin); \
236  } \
237  else \
238  { \
239  addr = (type) omAlloc0Large(__size); \
240  } \
241 } \
242 while (0)
243 
244 #ifdef OM_ALIGNMENT_NEEDS_WORK
245 #define omSmallSize2AlignedBin(size) om_Size2AlignedBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
246 
247 #define __omTypeAllocAligned(type, addr, size) \
248 do \
249 { \
250  size_t __size = size; \
251  if (__size <= OM_MAX_BLOCK_SIZE) \
252  { \
253  omBin __om_bin = omSmallSize2AlignedBin(__size); \
254  __omTypeAllocBin(type, addr, __om_bin); \
255  } \
256  else \
257  { \
258  addr = (type) omAllocLarge(__size); \
259  } \
260 } \
261 while(0)
262 
263 #define __omTypeAlloc0Aligned(type, addr, size) \
264 do \
265 { \
266  size_t __size = size; \
267  if (__size <= OM_MAX_BLOCK_SIZE) \
268  { \
269  omBin __om_bin = omSmallSize2AlignedBin(__size); \
270  __omTypeAlloc0Bin(type, addr, __om_bin); \
271  } \
272  else \
273  { \
274  addr = (type) omAlloc0Large(__size); \
275  } \
276 } \
277 while (0)
278 #else
279 #define __omTypeAllocAligned __omTypeAlloc
280 #define __omTypeAlloc0Aligned __omTypeAlloc0
281 #endif /* OM_ALIGNMENT_NEEDS_WORK */
282 
283 #define __omFreeSize(addr, size) \
284 do \
285 { \
286  if ((size <= OM_MAX_BLOCK_SIZE) || omIsBinPageAddr(addr)) \
287  { \
288  __omFreeBinAddr(addr); \
289  } \
290  else \
291  { \
292  omFreeLarge(addr); \
293  } \
294 } \
295 while (0)
296 
297 #define __omFree(addr) \
298 do \
299 { \
300  if (omIsBinPageAddr(addr)) \
301  { \
302  __omFreeBinAddr(addr); \
303  } \
304  else \
305  { \
306  omFreeLarge(addr); \
307  } \
308 } \
309 while (0)
310 
311 void* omDoRealloc(void* old_addr, size_t new_size, int flags);
312 
313 #define ___omTypeRealloc(old_addr, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags) \
314 do \
315 { \
316  size_t __new_size = new_size; \
317  if (__new_size <= OM_MAX_BLOCK_SIZE && omIsBinPageAddr(old_addr)) \
318  { \
319  omBin __old_bin = omGetBinOfAddr(old_addr); \
320  omBin __new_bin = SIZE_2_BIN(__new_size); \
321  REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin); \
322  } \
323  else \
324  { \
325  new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags); \
326  } \
327 } \
328 while (0)
329 
330 #define ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags) \
331 do \
332 { \
333  size_t __new_size = new_size; \
334  if (__new_size <= OM_MAX_BLOCK_SIZE && old_size <= OM_MAX_BLOCK_SIZE) \
335  { \
336  omBin __old_bin = omGetBinOfAddr(old_addr); \
337  omBin __new_bin = SIZE_2_BIN(__new_size); \
338  REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin); \
339  } \
340  else \
341  { \
342  new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags); \
343  } \
344 } \
345 while (0)
346 
347 #define __omTypeRealloc(old_addr, new_type, new_addr, new_size) \
348  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
349 #define __omTypeRealloc0(old_addr, new_type, new_addr, new_size) \
350  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)
351 #define __omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size) \
352  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
353 #define __omTypeRealloc0Size(old_addr, old_size, new_type, new_addr, new_size) \
354  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)
355 
356 #ifdef OM_ALIGNMENT_NEEDS_WORK
357 #define __omTypeReallocAligned(old_addr, new_type, new_addr, new_size) \
358  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
359 #define __omTypeRealloc0Aligned(old_addr, new_type, new_addr, new_size) \
360  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
361 #define __omTypeReallocAlignedSize(old_addr, old_size, new_type, new_addr, new_size) \
362  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
363 #define __omTypeRealloc0AlignedSize(old_addr, old_size, new_type, new_addr, new_size) \
364  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
365 #else
366 #define __omTypeReallocAligned __omTypeRealloc
367 #define __omTypeRealloc0Aligned __omTypeRealloc0
368 #define __omTypeReallocAlignedSize __omTypeReallocSize
369 #define __omTypeRealloc0AlignedSize __omTypeRealloc0Size
370 #endif
371 
372 #endif /* OM_GENERATE_INC */
373 #endif /* OM_ALLOC_PRIVATE_H */
omBin_t * omBin
Definition: omStructs.h:12
omBin om_Size2Bin[]
omBin_t om_StaticBin[]
void omFreeToPageFault(omBinPage page, void *addr)
Definition: om_Alloc.c:165
omBin next
void * omAllocBinFromFullPage(omBin bin)
Definition: om_Alloc.c:117
unsigned long sticky
omBinPage current_page
omBinPage_t om_ZeroPage[]
Definition: om_Alloc.c:17
omSpecBin_t * omSpecBin
Definition: omStructs.h:30
void * bin_sticky
omBin om_StickyBins
Definition: omBin.c:372
void * current
void * omDoRealloc(void *old_addr, size_t new_size, int flags)
Definition: om_Alloc.c:227
omBinPage prev
omBinPage next
omBinPage_t * omBinPage
Definition: omStructs.h:16
long max_blocks
omBinPageRegion_t * omBinPageRegion
Definition: omStructs.h:20
size_t sizeW
#define omSizeOfBinAddr(addr)
omBinPage last_page
int status int void size_t count int const void size_t count const char int flags
Definition: si_signals.h:73
omBinPageRegion region
omSpecBin next
omSpecBin om_SpecBin
Definition: om_Alloc.c:18