source: git/omalloc/omAllocPrivate.h @ 8291be

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