1 | /******************************************************************* |
---|
2 | * File: omAlloc.c |
---|
3 | * Purpose: implementation of main omalloc functions |
---|
4 | * Author: obachman@mathematik.uni-kl.de (Olaf Bachmann) |
---|
5 | * Created: 11/99 |
---|
6 | * Version: $Id: omAlloc.c,v 1.2 1999-11-22 18:12:57 obachman Exp $ |
---|
7 | *******************************************************************/ |
---|
8 | #ifndef OM_ALLOC_C |
---|
9 | #define OM_ALLOC_C |
---|
10 | #include <string.h> |
---|
11 | #include <stdio.h> |
---|
12 | |
---|
13 | #include "omConfig.h" |
---|
14 | #include "omPrivate.h" |
---|
15 | #include "omLocal.h" |
---|
16 | #include "omList.h" |
---|
17 | |
---|
18 | |
---|
19 | omBinPage_t om_ZeroPage[] = {{0, NULL, NULL, NULL, NULL}}; |
---|
20 | omBinPage_t om_CheckPage[] = {{0, NULL, NULL, NULL, NULL}}; |
---|
21 | omBinPage_t om_LargePage[] = {{0, NULL, NULL, NULL, NULL}}; |
---|
22 | omBin_t om_LargeBin[] = {{om_LargePage, NULL, NULL, 0, 0, 0}}; |
---|
23 | omBin_t om_CheckBin[] = {{om_CheckPage, NULL, NULL, 0, 0, 0}}; |
---|
24 | omSpecBin om_SpecBin = NULL; |
---|
25 | |
---|
26 | |
---|
27 | #include <stdlib.h> |
---|
28 | #define AllocSizeOf(x) _omAllocBlock(sizeof(x)) |
---|
29 | #define FreeSizeOf(addr, x) _omFreeBin(addr) |
---|
30 | |
---|
31 | /* Get new page and initialize */ |
---|
32 | static omBinPage omAllocNewBinPage(omBin bin) |
---|
33 | { |
---|
34 | omBinPage newpage; |
---|
35 | void* tmp; |
---|
36 | int i = 1; |
---|
37 | |
---|
38 | if (bin->max_blocks > 0) newpage = omGetPage(); |
---|
39 | else newpage = omVallocFromSystem(bin->sizeW * SIZEOF_LONG); |
---|
40 | |
---|
41 | omAssume(omIsAddrPageAligned((void*) newpage)); |
---|
42 | |
---|
43 | omSetTopBinAndStickyOfPage(newpage, bin, bin->sticky); |
---|
44 | newpage->used_blocks = -1; |
---|
45 | newpage->current = (void*) (((void*)newpage) + SIZEOF_OM_BIN_PAGE_HEADER); |
---|
46 | tmp = newpage->current; |
---|
47 | while (i < bin->max_blocks) |
---|
48 | { |
---|
49 | tmp = *((void**)tmp) = ((void**) tmp) + bin->sizeW; |
---|
50 | i++; |
---|
51 | } |
---|
52 | *((void**)tmp) = NULL; |
---|
53 | omAssume(omListLength(newpage->current) == |
---|
54 | (bin->max_blocks > 1 ? bin->max_blocks : 1)); |
---|
55 | return newpage; |
---|
56 | } |
---|
57 | |
---|
58 | OM_INLINE void omFreeBinPage(omBinPage page, omBin bin) |
---|
59 | { |
---|
60 | if (bin->max_blocks > 0) |
---|
61 | omFreePage(page); |
---|
62 | else |
---|
63 | omVfreeToSystem(page, bin->sizeW * SIZEOF_LONG); |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | /* primitives for handling of list of pages */ |
---|
68 | OM_INLINE void omTakeOutBinPage(omBinPage page, omBin bin) |
---|
69 | { |
---|
70 | if (bin->current_page == page) |
---|
71 | { |
---|
72 | if (page->next == NULL) |
---|
73 | { |
---|
74 | if (page->prev == NULL) |
---|
75 | { |
---|
76 | omAssume(bin->last_page == page); |
---|
77 | bin->last_page = NULL; |
---|
78 | bin->current_page = om_ZeroPage; |
---|
79 | return; |
---|
80 | } |
---|
81 | bin->current_page = page->prev; |
---|
82 | } |
---|
83 | else |
---|
84 | bin->current_page = page->next; |
---|
85 | } |
---|
86 | if (bin->last_page == page) |
---|
87 | { |
---|
88 | omAssume(page->prev != NULL && page->next == NULL); |
---|
89 | bin->last_page = page->prev; |
---|
90 | } |
---|
91 | else |
---|
92 | { |
---|
93 | page->next->prev = page->prev; |
---|
94 | } |
---|
95 | if (page->prev != NULL) page->prev->next = page->next; |
---|
96 | } |
---|
97 | |
---|
98 | OM_INLINE void omInsertBinPage(omBinPage after, omBinPage page, omBin bin) |
---|
99 | { |
---|
100 | if (bin->current_page == om_ZeroPage) |
---|
101 | { |
---|
102 | omAssume(bin->last_page == NULL); |
---|
103 | page->next = NULL; |
---|
104 | page->prev = NULL; |
---|
105 | bin->current_page = page; |
---|
106 | bin->last_page = page; |
---|
107 | } |
---|
108 | else |
---|
109 | { |
---|
110 | omAssume(after != NULL && bin->last_page != NULL); |
---|
111 | if (after == bin->last_page) |
---|
112 | { |
---|
113 | bin->last_page = page; |
---|
114 | } |
---|
115 | else |
---|
116 | { |
---|
117 | omAssume(after->next != NULL); |
---|
118 | after->next->prev = page; |
---|
119 | } |
---|
120 | page->next = after->next; |
---|
121 | after->next = page; |
---|
122 | page->prev = after; |
---|
123 | } |
---|
124 | } |
---|
125 | |
---|
126 | /* bin->current_page is empty, get new bin->current_page, return addr*/ |
---|
127 | void* omAllocBinFromFullPage(omBin bin) |
---|
128 | { |
---|
129 | void* addr; |
---|
130 | omBinPage newpage; |
---|
131 | omAssume(bin->current_page->current == NULL); |
---|
132 | |
---|
133 | if (bin->current_page != om_ZeroPage) |
---|
134 | { |
---|
135 | omAssume(bin->last_page != NULL); |
---|
136 | bin->current_page->used_blocks = 0; |
---|
137 | } |
---|
138 | |
---|
139 | if (bin->current_page->next != NULL) |
---|
140 | { |
---|
141 | omAssume(bin->current_page->next->current != NULL); |
---|
142 | newpage = bin->current_page->next; |
---|
143 | } |
---|
144 | else |
---|
145 | { |
---|
146 | // need to Allocate new page |
---|
147 | newpage = omAllocNewBinPage(bin); |
---|
148 | omInsertBinPage(bin->current_page, newpage, bin); |
---|
149 | } |
---|
150 | bin->current_page = newpage; |
---|
151 | |
---|
152 | omAssume(newpage != NULL && newpage != om_ZeroPage && |
---|
153 | newpage->current != NULL); |
---|
154 | __omTypeAllocFromPage(void*, addr, newpage); |
---|
155 | return addr; |
---|
156 | } |
---|
157 | |
---|
158 | |
---|
159 | /* page->used_blocks == 0, so, either free page or reallocate to |
---|
160 | the right of current_page */ |
---|
161 | /* |
---|
162 | * Now: there are three different strategies here, on what to do with |
---|
163 | * pages which were full and now have a free block: |
---|
164 | * 1.) Insert at the end (default) |
---|
165 | * 2.) Insert after current_page => #define PAGE_AFTER_CURRENT |
---|
166 | * 3.) Let it be new current_page => #define PAGE_BEFORE_CURRENT |
---|
167 | * Still need to try out which is best |
---|
168 | */ |
---|
169 | void omFreeToPageFault(omBinPage page, void* addr) |
---|
170 | { |
---|
171 | omBin bin; |
---|
172 | omAssume(page->used_blocks == 0); |
---|
173 | |
---|
174 | if (page == om_LargePage) |
---|
175 | { |
---|
176 | omFreeToSystem(addr); |
---|
177 | } |
---|
178 | else |
---|
179 | { |
---|
180 | bin = omGetBinOfPage(page); |
---|
181 | if (page->current != NULL || bin->max_blocks <= 1) |
---|
182 | { |
---|
183 | // all blocks of page are now collected |
---|
184 | omTakeOutBinPage(page, bin); |
---|
185 | // page can be freed |
---|
186 | omFreeBinPage(page, bin); |
---|
187 | } |
---|
188 | else |
---|
189 | { |
---|
190 | // page was full |
---|
191 | page->current = addr; |
---|
192 | page->used_blocks = bin->max_blocks - 2; |
---|
193 | *((void**)addr) = NULL; |
---|
194 | |
---|
195 | omTakeOutBinPage(page, bin); |
---|
196 | #if defined(PAGE_BEFORE_CURRENT) |
---|
197 | if (bin->current_page->prev != NULL) |
---|
198 | omInsertBinPage(bin->current_page->prev, page); |
---|
199 | else |
---|
200 | omInsertBinPage(bin->current_page, page, bin); |
---|
201 | bin->current_page = page; |
---|
202 | #elsif defined(PAGE_AFTER_CURRENT) |
---|
203 | omInsertBinPage(bin->current_page, page, bin); |
---|
204 | #else |
---|
205 | omInsertBinPage(bin->last_page, page, bin); |
---|
206 | #endif |
---|
207 | } |
---|
208 | } |
---|
209 | } |
---|
210 | |
---|
211 | /***************************************************************** |
---|
212 | * |
---|
213 | * SpecBin business |
---|
214 | * |
---|
215 | *****************************************************************/ |
---|
216 | omBin omGetSpecBin(size_t size) |
---|
217 | { |
---|
218 | omBin om_new_specBin; |
---|
219 | long max_blocks; |
---|
220 | long sizeW; |
---|
221 | |
---|
222 | |
---|
223 | size = OM_ALIGN_SIZE(size); |
---|
224 | |
---|
225 | if (size > SIZEOF_OM_BIN_PAGE) |
---|
226 | { |
---|
227 | /* need page header */ |
---|
228 | max_blocks = - (long) |
---|
229 | ((size+(SIZEOF_SYSTEM_PAGE-SIZEOF_OM_BIN_PAGE))+SIZEOF_SYSTEM_PAGE-1) |
---|
230 | / SIZEOF_SYSTEM_PAGE; |
---|
231 | sizeW = ((-max_blocks*SIZEOF_SYSTEM_PAGE) - |
---|
232 | (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE)) / SIZEOF_LONG; |
---|
233 | om_new_specBin = om_LargeBin; |
---|
234 | } |
---|
235 | else |
---|
236 | { |
---|
237 | max_blocks = SIZEOF_OM_BIN_PAGE / size; |
---|
238 | sizeW = (SIZEOF_OM_BIN_PAGE / max_blocks) / SIZEOF_LONG; |
---|
239 | om_new_specBin = omSize2Bin( size ); |
---|
240 | } |
---|
241 | |
---|
242 | if (om_new_specBin == om_LargeBin || |
---|
243 | om_new_specBin->max_blocks < max_blocks) |
---|
244 | { |
---|
245 | omSpecBin s_bin |
---|
246 | = omFindInSortedGList(om_SpecBin, next, max_blocks, max_blocks); |
---|
247 | |
---|
248 | if (s_bin != NULL) |
---|
249 | { |
---|
250 | (s_bin->ref)++; |
---|
251 | omAssume(s_bin->bin != NULL && |
---|
252 | s_bin->bin->max_blocks == s_bin->max_blocks && |
---|
253 | s_bin->bin->sizeW == sizeW); |
---|
254 | return s_bin->bin; |
---|
255 | } |
---|
256 | s_bin = (omSpecBin) AllocSizeOf(omSpecBin_t); |
---|
257 | s_bin->ref = 1; |
---|
258 | s_bin->next = NULL; |
---|
259 | s_bin->max_blocks = max_blocks; |
---|
260 | s_bin->bin = (omBin) AllocSizeOf(omBin_t); |
---|
261 | s_bin->bin->current_page = om_ZeroPage; |
---|
262 | s_bin->bin->last_page = NULL; |
---|
263 | s_bin->bin->next = NULL; |
---|
264 | s_bin->bin->sizeW = sizeW; |
---|
265 | s_bin->bin->max_blocks = max_blocks; |
---|
266 | s_bin->bin->sticky = 0; |
---|
267 | om_SpecBin = omInsertInSortedGList(om_SpecBin, next, max_blocks, s_bin); |
---|
268 | return s_bin->bin; |
---|
269 | } |
---|
270 | else |
---|
271 | { |
---|
272 | return om_new_specBin; |
---|
273 | } |
---|
274 | } |
---|
275 | |
---|
276 | int omIsStaticBin(omBin bin) |
---|
277 | { |
---|
278 | return ((unsigned long) bin >= ((unsigned long) &om_StaticBin[0]) && |
---|
279 | (unsigned long) bin <= ((unsigned long) &om_StaticBin[OM_MAX_BIN_INDEX])); |
---|
280 | } |
---|
281 | |
---|
282 | void omUnGetSpecBin(omBin *bin_p) |
---|
283 | { |
---|
284 | omBin bin = *bin_p; |
---|
285 | if (! omIsStaticBin(bin)) |
---|
286 | { |
---|
287 | omSpecBin s_bin |
---|
288 | = omFindInSortedGList(om_SpecBin, next, max_blocks, bin->max_blocks); |
---|
289 | omAssume(s_bin != NULL); |
---|
290 | if (s_bin != NULL) |
---|
291 | { |
---|
292 | (s_bin->ref)--; |
---|
293 | if (s_bin->ref == 0) |
---|
294 | { |
---|
295 | if(s_bin->bin->last_page == NULL) |
---|
296 | { |
---|
297 | om_SpecBin = omRemoveFromSortedGList(om_SpecBin, next, max_blocks, |
---|
298 | s_bin); |
---|
299 | FreeSizeOf(s_bin->bin, omBin_t); |
---|
300 | FreeSizeOf(s_bin, omSpecBin_t); |
---|
301 | } |
---|
302 | } |
---|
303 | } |
---|
304 | } |
---|
305 | *bin_p = NULL; |
---|
306 | } |
---|
307 | |
---|
308 | /***************************************************************** |
---|
309 | * |
---|
310 | * Statistics |
---|
311 | * |
---|
312 | *****************************************************************/ |
---|
313 | static void omGetBinStat(omBin bin, int *pages_p, int *used_blocks_p, |
---|
314 | int *free_blocks_p) |
---|
315 | { |
---|
316 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
317 | int where = 1; |
---|
318 | |
---|
319 | omBinPage page = bin->last_page; |
---|
320 | while (page != NULL) |
---|
321 | { |
---|
322 | pages++; |
---|
323 | if (where == 1) |
---|
324 | { |
---|
325 | used_blocks += page->used_blocks + 1; |
---|
326 | if (bin->max_blocks > 0) |
---|
327 | free_blocks += bin->max_blocks - page->used_blocks -1; |
---|
328 | } |
---|
329 | else |
---|
330 | { |
---|
331 | if (bin->max_blocks > 1) |
---|
332 | used_blocks += bin->max_blocks; |
---|
333 | else |
---|
334 | used_blocks++; |
---|
335 | } |
---|
336 | if (page == bin->current_page) where = -1; |
---|
337 | page = page->prev; |
---|
338 | } |
---|
339 | *pages_p = pages; |
---|
340 | *used_blocks_p = used_blocks; |
---|
341 | *free_blocks_p = free_blocks; |
---|
342 | } |
---|
343 | |
---|
344 | static void omGetTotalBinStat(omBin bin, int *pages_p, int *used_blocks_p, |
---|
345 | int *free_blocks_p) |
---|
346 | { |
---|
347 | int t_pages = 0, t_used_blocks = 0, t_free_blocks = 0; |
---|
348 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
349 | |
---|
350 | while (bin != NULL) |
---|
351 | { |
---|
352 | omGetBinStat(bin, &pages, &used_blocks, &free_blocks); |
---|
353 | t_pages += pages; |
---|
354 | t_used_blocks += used_blocks; |
---|
355 | t_free_blocks += free_blocks; |
---|
356 | bin = bin->next; |
---|
357 | } |
---|
358 | *pages_p = t_pages; |
---|
359 | *used_blocks_p = t_used_blocks; |
---|
360 | *free_blocks_p = t_free_blocks; |
---|
361 | } |
---|
362 | |
---|
363 | void omGetBinUsage() |
---|
364 | { |
---|
365 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
366 | size_t bytes; |
---|
367 | int i; |
---|
368 | omSpecBin s_bin = om_SpecBin; |
---|
369 | |
---|
370 | for(i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
371 | { |
---|
372 | omGetTotalBinStat(&om_StaticBin[i], &pages, &used_blocks, &free_blocks); |
---|
373 | bytes += used_blocks*om_StaticBin[i].sizeW*SIZEOF_LONG; |
---|
374 | } |
---|
375 | while(s_bin != NULL) |
---|
376 | { |
---|
377 | omGetTotalBinStat(s_bin->bin, &pages, &used_blocks, &free_blocks); |
---|
378 | bytes += s_bin->bin->sizeW*used_blocks*SIZEOF_LONG; |
---|
379 | s_bin = s_bin->next; |
---|
380 | } |
---|
381 | } |
---|
382 | |
---|
383 | void omPrintBinStat(FILE * fd, omBin bin) |
---|
384 | { |
---|
385 | int pages = 0, used_blocks = 0, free_blocks = 0; |
---|
386 | fprintf(fd, "%ld\t%ld\t", bin->sizeW, bin->max_blocks); |
---|
387 | omGetTotalBinStat(bin, &pages, &used_blocks, &free_blocks); |
---|
388 | fprintf(fd, "%d\t%d\t%d\n", pages, free_blocks, used_blocks); |
---|
389 | if (bin->next != NULL) |
---|
390 | { |
---|
391 | while (bin != NULL) |
---|
392 | { |
---|
393 | omGetBinStat(bin, &pages, &used_blocks, &free_blocks); |
---|
394 | fprintf(fd, " \t \t%d\t%d\t%d\t%d\n", pages, free_blocks, used_blocks, |
---|
395 | (int) bin->sticky); |
---|
396 | bin = bin->next; |
---|
397 | } |
---|
398 | } |
---|
399 | } |
---|
400 | |
---|
401 | void omPrintBinStats(FILE* fd) |
---|
402 | { |
---|
403 | int i; |
---|
404 | omSpecBin s_bin = om_SpecBin; |
---|
405 | |
---|
406 | fprintf(fd, "SizeW\tMBlocks\tUPages\tFBlocks\tUBlocks\tSticky\n"); |
---|
407 | fflush(fd); |
---|
408 | for(i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
409 | { |
---|
410 | omPrintBinStat(fd, &om_StaticBin[i]); |
---|
411 | } |
---|
412 | while(s_bin != NULL) |
---|
413 | { |
---|
414 | omPrintBinStat(fd, s_bin->bin); |
---|
415 | s_bin = s_bin->next; |
---|
416 | } |
---|
417 | } |
---|
418 | |
---|
419 | /***************************************************************** |
---|
420 | * |
---|
421 | * Sticky business |
---|
422 | * |
---|
423 | *****************************************************************/ |
---|
424 | #define omGetStickyBin(bin, sticky_tag) \ |
---|
425 | omFindInGList(bin, next, sticky, sticky_tag) |
---|
426 | |
---|
427 | static omBin omCreateStickyBin(omBin bin, unsigned long sticky) |
---|
428 | { |
---|
429 | omBin s_bin = (omBin) AllocSizeOf(omBin_t); |
---|
430 | s_bin->sticky = sticky; |
---|
431 | s_bin->current_page = om_ZeroPage; |
---|
432 | s_bin->last_page = NULL; |
---|
433 | s_bin->max_blocks = bin->max_blocks; |
---|
434 | s_bin->sizeW = bin->sizeW; |
---|
435 | s_bin->next = bin->next; |
---|
436 | bin->next = s_bin; |
---|
437 | return s_bin; |
---|
438 | } |
---|
439 | |
---|
440 | unsigned long omGetMaxStickyBinTag(omBin bin) |
---|
441 | { |
---|
442 | unsigned long sticky = 0; |
---|
443 | do |
---|
444 | { |
---|
445 | if (bin->sticky > sticky) sticky = bin->sticky; |
---|
446 | bin = bin->next; |
---|
447 | } |
---|
448 | while (bin != NULL); |
---|
449 | return sticky; |
---|
450 | } |
---|
451 | |
---|
452 | unsigned long omGetNewStickyBinTag(omBin bin) |
---|
453 | { |
---|
454 | unsigned long sticky = omGetMaxStickyBinTag(bin); |
---|
455 | if (sticky < BIT_SIZEOF_LONG - 2) |
---|
456 | { |
---|
457 | sticky++; |
---|
458 | omCreateStickyBin(bin, sticky); |
---|
459 | return sticky; |
---|
460 | } |
---|
461 | else |
---|
462 | { |
---|
463 | omAssume(sticky == BIT_SIZEOF_LONG - 1); |
---|
464 | } |
---|
465 | return sticky; |
---|
466 | } |
---|
467 | |
---|
468 | void omSetStickyBinTag(omBin bin, unsigned long sticky_tag) |
---|
469 | { |
---|
470 | omBin s_bin; |
---|
471 | s_bin = omGetStickyBin(bin, sticky_tag); |
---|
472 | |
---|
473 | if (s_bin != bin) |
---|
474 | { |
---|
475 | omBinPage tc, tl; |
---|
476 | unsigned long ts; |
---|
477 | |
---|
478 | if (s_bin == NULL) s_bin = omCreateStickyBin(bin, sticky_tag); |
---|
479 | ts = bin->sticky; |
---|
480 | tl = bin->last_page; |
---|
481 | tc = bin->current_page; |
---|
482 | bin->sticky = s_bin->sticky; |
---|
483 | bin->current_page = s_bin->current_page; |
---|
484 | bin->last_page = s_bin->last_page; |
---|
485 | s_bin->sticky = ts; |
---|
486 | s_bin->last_page = tl; |
---|
487 | s_bin->current_page = tc; |
---|
488 | } |
---|
489 | } |
---|
490 | |
---|
491 | void omUnSetStickyBinTag(omBin bin, unsigned long sticky) |
---|
492 | { |
---|
493 | omAssume(omGetStickyBin(bin, 0) != NULL); |
---|
494 | if (bin->sticky == sticky) |
---|
495 | omSetStickyBinTag(bin, 0); |
---|
496 | } |
---|
497 | |
---|
498 | static void omMergeStickyPages(omBin to_bin, omBin from_bin) |
---|
499 | { |
---|
500 | #ifdef HAVE_OM_ASSUME |
---|
501 | int length = omGListLength(to_bin->last_page, prev) + |
---|
502 | omGListLength(from_bin->last_page, prev); |
---|
503 | #endif |
---|
504 | |
---|
505 | omBinPage page = from_bin->last_page; |
---|
506 | omAssume(to_bin->sticky == 0); |
---|
507 | omAssume(to_bin->sizeW == from_bin->sizeW); |
---|
508 | omAssume(to_bin != from_bin); |
---|
509 | omAssume(omIsOnGList(to_bin->next, next, from_bin) |
---|
510 | || |
---|
511 | omIsOnGList(from_bin->next, next, to_bin)); |
---|
512 | |
---|
513 | if (page == NULL) return; |
---|
514 | do |
---|
515 | { |
---|
516 | omSetStickyOfPage(page, 0); |
---|
517 | if (page->prev == NULL) break; |
---|
518 | page = page->prev; |
---|
519 | } |
---|
520 | while(1); |
---|
521 | |
---|
522 | if (to_bin->last_page == NULL) |
---|
523 | { |
---|
524 | omAssume(to_bin->current_page == om_ZeroPage); |
---|
525 | to_bin->last_page = from_bin->last_page; |
---|
526 | to_bin->current_page = from_bin->current_page; |
---|
527 | return; |
---|
528 | } |
---|
529 | |
---|
530 | omAssume(to_bin->current_page != om_ZeroPage && |
---|
531 | to_bin->current_page != NULL); |
---|
532 | |
---|
533 | if (to_bin->current_page->current != NULL) |
---|
534 | { |
---|
535 | if (to_bin->current_page->prev == NULL) |
---|
536 | { |
---|
537 | from_bin->last_page->next = to_bin->current_page; |
---|
538 | to_bin->current_page->prev = from_bin->last_page; |
---|
539 | to_bin->current_page = from_bin->current_page; |
---|
540 | return; |
---|
541 | } |
---|
542 | to_bin->current_page = to_bin->current_page->prev; |
---|
543 | } |
---|
544 | else |
---|
545 | { |
---|
546 | /* need to reset this here, since new current_page is going to be |
---|
547 | from_bin->current_page, and only for current_page may we have |
---|
548 | used_blocks != 0 && current == NULL */ |
---|
549 | to_bin->current_page->used_blocks = 0; |
---|
550 | } |
---|
551 | |
---|
552 | |
---|
553 | omAssume(to_bin->current_page != NULL && |
---|
554 | to_bin->current_page->current == NULL && |
---|
555 | to_bin->current_page->used_blocks == 0); |
---|
556 | |
---|
557 | from_bin->last_page->next = to_bin->current_page->next; |
---|
558 | if (to_bin->current_page->next != NULL) |
---|
559 | to_bin->current_page->next->prev = from_bin->last_page; |
---|
560 | else |
---|
561 | { |
---|
562 | omAssume(to_bin->current_page == to_bin->last_page); |
---|
563 | to_bin->last_page = from_bin->last_page; |
---|
564 | } |
---|
565 | to_bin->current_page->next = page; |
---|
566 | page->prev = to_bin->current_page; |
---|
567 | to_bin->current_page = from_bin->current_page; |
---|
568 | |
---|
569 | #ifdef HAVE_OM_ASSUME |
---|
570 | omAssume(omGListLength(to_bin->last_page, prev) == length); |
---|
571 | #endif |
---|
572 | } |
---|
573 | |
---|
574 | #include "omDebug.h" |
---|
575 | |
---|
576 | void omDeleteStickyBinTag(omBin bin, unsigned long sticky) |
---|
577 | { |
---|
578 | omBin no_sticky_bin = NULL; |
---|
579 | omBin sticky_bin = NULL; |
---|
580 | |
---|
581 | omdCheckBin(bin, 10); |
---|
582 | if (sticky == 0) |
---|
583 | { |
---|
584 | omAssume(0); |
---|
585 | return; |
---|
586 | } |
---|
587 | |
---|
588 | sticky_bin = omGetStickyBin(bin, sticky); |
---|
589 | if (sticky_bin != NULL) |
---|
590 | { |
---|
591 | no_sticky_bin = omGetStickyBin(bin, 0); |
---|
592 | omAssume(no_sticky_bin != NULL && sticky_bin != no_sticky_bin); |
---|
593 | |
---|
594 | omMergeStickyPages(no_sticky_bin, sticky_bin); |
---|
595 | |
---|
596 | if (bin == sticky_bin) |
---|
597 | { |
---|
598 | sticky_bin = no_sticky_bin; |
---|
599 | omSetStickyBinTag(bin, 0); |
---|
600 | } |
---|
601 | bin->next = omRemoveFromGList(bin->next, next, sticky_bin); |
---|
602 | FreeSizeOf(sticky_bin, omBin_t); |
---|
603 | } |
---|
604 | omdCheckBin(bin, 10); |
---|
605 | } |
---|
606 | |
---|
607 | |
---|
608 | |
---|
609 | /***************************************************************** |
---|
610 | * |
---|
611 | * AllBin business |
---|
612 | * |
---|
613 | *****************************************************************/ |
---|
614 | unsigned long omGetNewStickyAllBinTag() |
---|
615 | { |
---|
616 | unsigned long sticky = 0, new_sticky; |
---|
617 | int i; |
---|
618 | omSpecBin s_bin; |
---|
619 | // first, find new sticky tag |
---|
620 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
621 | { |
---|
622 | new_sticky = omGetMaxStickyBinTag(&(om_StaticBin[i])); |
---|
623 | if (new_sticky > sticky) sticky = new_sticky; |
---|
624 | } |
---|
625 | s_bin = om_SpecBin; |
---|
626 | while (s_bin != NULL) |
---|
627 | { |
---|
628 | new_sticky = omGetMaxStickyBinTag(s_bin->bin); |
---|
629 | if (new_sticky > sticky) sticky = new_sticky; |
---|
630 | s_bin = s_bin->next; |
---|
631 | } |
---|
632 | if (sticky < BIT_SIZEOF_LONG - 2) |
---|
633 | { |
---|
634 | sticky++; |
---|
635 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
636 | { |
---|
637 | omCreateStickyBin(&(om_StaticBin[i]), sticky); |
---|
638 | } |
---|
639 | s_bin = om_SpecBin; |
---|
640 | while (s_bin != NULL) |
---|
641 | { |
---|
642 | omCreateStickyBin(s_bin->bin, sticky); |
---|
643 | s_bin = s_bin->next; |
---|
644 | } |
---|
645 | return sticky; |
---|
646 | } |
---|
647 | else |
---|
648 | { |
---|
649 | omBin bin; |
---|
650 | omAssume(sticky == BIT_SIZEOF_LONG - 1); |
---|
651 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
652 | { |
---|
653 | bin = &om_StaticBin[i]; |
---|
654 | if (omGetStickyBin(bin, BIT_SIZEOF_LONG -1) == NULL) |
---|
655 | omCreateStickyBin(bin, BIT_SIZEOF_LONG -1); |
---|
656 | } |
---|
657 | s_bin = om_SpecBin; |
---|
658 | while (s_bin != NULL) |
---|
659 | { |
---|
660 | if (omGetStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1) == NULL) |
---|
661 | omCreateStickyBin(s_bin->bin, BIT_SIZEOF_LONG -1); |
---|
662 | s_bin = s_bin->next; |
---|
663 | } |
---|
664 | return BIT_SIZEOF_LONG - 1; |
---|
665 | } |
---|
666 | } |
---|
667 | |
---|
668 | void omSetStickyAllBinTag(unsigned long sticky) |
---|
669 | { |
---|
670 | omSpecBin s_bin = om_SpecBin; |
---|
671 | int i; |
---|
672 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
673 | { |
---|
674 | omSetStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
675 | } |
---|
676 | while (s_bin != NULL) |
---|
677 | { |
---|
678 | omSetStickyBinTag(s_bin->bin, sticky); |
---|
679 | s_bin = s_bin->next; |
---|
680 | } |
---|
681 | } |
---|
682 | |
---|
683 | void omUnSetStickyAllBinTag(unsigned long sticky) |
---|
684 | { |
---|
685 | omSpecBin s_bin = om_SpecBin; |
---|
686 | int i; |
---|
687 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
688 | { |
---|
689 | omUnSetStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
690 | } |
---|
691 | while (s_bin != NULL) |
---|
692 | { |
---|
693 | omUnSetStickyBinTag(s_bin->bin, sticky); |
---|
694 | s_bin = s_bin->next; |
---|
695 | } |
---|
696 | } |
---|
697 | |
---|
698 | void omDeleteStickyAllBinTag(unsigned long sticky) |
---|
699 | { |
---|
700 | omSpecBin s_bin = om_SpecBin; |
---|
701 | int i; |
---|
702 | for (i=0; i<=OM_MAX_BIN_INDEX; i++) |
---|
703 | { |
---|
704 | omDeleteStickyBinTag(&(om_StaticBin[i]), sticky); |
---|
705 | } |
---|
706 | while (s_bin != NULL) |
---|
707 | { |
---|
708 | omDeleteStickyBinTag(s_bin->bin, sticky); |
---|
709 | s_bin = s_bin->next; |
---|
710 | } |
---|
711 | } |
---|
712 | |
---|
713 | #endif /* OM_ALLOC_C */ |
---|