My Project
Loading...
Searching...
No Matches
omBinPage.c
Go to the documentation of this file.
1/*******************************************************************
2 * File: omBinPage.c
3 * Purpose: implementation of routines for primitve BinPage managment
4 * Author: obachman (Olaf Bachmann)
5 * Created: 11/99
6 *******************************************************************/
7#include <limits.h>
8#include "omalloc.h"
9
10#ifdef HAVE_OMALLOC
11#include "omDefaultConfig.h"
12
13/*******************************************************************
14 *
15 * Local declarations
16 *
17 *******************************************************************/
18
19/* define if you want to keep regions approximately in order */
20#define OM_KEEP_REGIONS_ORDER
21
23{
24 void* current; /* linked list of free pages */
25 omBinPageRegion next; /* nex/prev pointer in ring of regions */
27 char* init_addr; /* pointer portion of inital chunk which is still free */
28 char* addr; /* addr returned by alloc */
29 int init_pages; /* number of pages still available in init_chunk */
30 int used_pages; /* number of used pages */
31 int pages; /* total size of region */
32};
33
34/* globale variable holding pointing int regions ring */
36unsigned long om_MaxBinPageIndex = 0;
37unsigned long om_MinBinPageIndex = ULONG_MAX;
38unsigned long *om_BinPageIndicies = NULL;
39
40/* declaration of local procs */
41static void* omTakeOutConsecutivePages(omBinPageRegion region, int how_many);
42static omBinPageRegion omAllocNewBinPagesRegion(int min_pages);
43static void omFreeBinPagesRegion(omBinPageRegion region);
44
45static void omBinPageIndexFault(unsigned long low_index, unsigned long high_index);
46static void omRegisterBinPages(void* low_addr, int pages);
47static void omUnregisterBinPages(void* low_addr, int pages);
48
49OM_INLINE_LOCAL void omTakeOutRegion(omBinPageRegion region)
50{
51 omAssume(region != NULL);
52
53 if (region->prev != NULL)
54 {
55 omAssume(region->prev != region && region->prev != region->next);
56 region->prev->next = region->next;
57 }
58
59 if (region->next != NULL)
60 {
61 omAssume(region->next != region && region->prev != region->next);
62 region->next->prev = region->prev;
63 }
64}
65
67{
68 omAssume(insert != NULL && after != NULL && insert != after);
69 insert->next = after->next;
70 insert->prev = after;
71 after->next = insert;
72 if (insert->next != NULL)
73 {
74 omAssume(insert->next != insert && insert->next != after);
75 insert->next->prev = insert;
76 }
77}
78
80{
81 omAssume(insert != NULL && before != NULL && insert != before);
82 insert->prev = before->prev;
83 insert->next = before;
84 before->prev = insert;
85 if (insert->prev != NULL)
86 insert->prev->next = insert;
87}
88
89
90/*******************************************************************
91 *
92 * Alloc/Free of BinPages
93 *
94 *******************************************************************/
95#define NEXT_PAGE(page) *((void**) page)
96#define OM_IS_EMPTY_REGION(region) ((region)->current == NULL && (region->init_addr == NULL))
97
99{
100 omBinPage bin_page;
101
104
105 while (1)
106 {
107 if (om_CurrentBinPageRegion->current != NULL)
108 {
109 bin_page = om_CurrentBinPageRegion->current;
110 om_CurrentBinPageRegion->current = NEXT_PAGE(bin_page);
111 goto Found;
112 }
113 if (om_CurrentBinPageRegion->init_pages > 0)
114 {
115 bin_page = (omBinPage)om_CurrentBinPageRegion->init_addr;
116 om_CurrentBinPageRegion->init_pages--;
117 if (om_CurrentBinPageRegion->init_pages > 0)
118 om_CurrentBinPageRegion->init_addr += SIZEOF_SYSTEM_PAGE;
119 else
120 om_CurrentBinPageRegion->init_addr = NULL;
121 goto Found;
122 }
123 if (om_CurrentBinPageRegion->next != NULL)
124 {
126 }
127 else
128 {
130 new_region->prev = om_CurrentBinPageRegion;
131 om_CurrentBinPageRegion->next = new_region;
132 om_CurrentBinPageRegion = new_region;
133 }
134 }
135
136 Found:
137 bin_page->region = om_CurrentBinPageRegion;
138 om_CurrentBinPageRegion->used_pages++;
139
140 om_Info.UsedPages++;
141 om_Info.AvailPages--;
142 if (om_Info.UsedPages > om_Info.MaxPages)
143 om_Info.MaxPages = om_Info.UsedPages;
144
145 OM_ALLOC_BINPAGE_HOOK;
146 return bin_page;
147}
148
150{
151 omBinPage bin_page;
152 omBinPageRegion region;
153
156
158 while (1)
159 {
160 if (region->init_pages >= how_many)
161 {
162 bin_page = (omBinPage)region->init_addr;
163 region->init_pages -= how_many;
164 if (region->init_pages)
165 region->init_addr += how_many*SIZEOF_SYSTEM_PAGE;
166 else
167 region->init_addr = NULL;
168 goto Found;
169 }
170 if ((bin_page = omTakeOutConsecutivePages(region, how_many)) != NULL)
171 {
172 goto Found;
173 }
174 if (region->next != NULL)
175 {
176 region = region->next;
177 }
178 else
179 {
180 omBinPageRegion new_region = omAllocNewBinPagesRegion(how_many);
181 region->next = new_region;
182 new_region->prev = region;
183 region = new_region;
184 }
185 }
186 /*while (1) */
187
188 Found:
189 bin_page->region = region;
190 region->used_pages += how_many;
191
192 if (region != om_CurrentBinPageRegion && OM_IS_EMPTY_REGION(region))
193 {
194 omTakeOutRegion(region);
196 }
197 om_Info.UsedPages += how_many;
198 om_Info.AvailPages -= how_many;
199 if (om_Info.UsedPages > om_Info.MaxPages)
200 om_Info.MaxPages = om_Info.UsedPages;
201
202 OM_ALLOC_BINPAGE_HOOK;
203 return bin_page;
204}
205
206void omFreeBinPages(omBinPage bin_page, int how_many)
207{
208 omBinPageRegion region = bin_page->region;
209
210 region->used_pages -= how_many;
211 if (region->used_pages == 0)
212 {
213 if (region == om_CurrentBinPageRegion)
214 {
215 if (region->next != NULL)
216 om_CurrentBinPageRegion = region->next;
217 else
218 om_CurrentBinPageRegion = region->prev;
219 }
220 omTakeOutRegion(region);
221 omFreeBinPagesRegion(region);
222 }
223 else
224 {
225 if (region != om_CurrentBinPageRegion && OM_IS_EMPTY_REGION(region))
226 {
227 omTakeOutRegion(region);
229 }
230 if (how_many > 1)
231 {
232 int i = how_many;
233 char* page = (char *)bin_page;
234
235 while (i > 1)
236 {
237 NEXT_PAGE(page) = page + SIZEOF_SYSTEM_PAGE;
238 page = NEXT_PAGE(page);
239 i--;
240 }
241 NEXT_PAGE(page) = region->current;
242 }
243 else
244 {
245 NEXT_PAGE(bin_page) = region->current;
246 }
247 region->current = (void*) bin_page;
248 }
249 om_Info.AvailPages += how_many;
250 om_Info.UsedPages -= how_many;
251 OM_FREE_BINPAGE_HOOK;
252}
253
254static void* omTakeOutConsecutivePages(omBinPageRegion region, int pages)
255{
256 void* current;
257 char* iter;
258 void* prev = NULL;
259 void* bin_page;
260 int found;
261 current = region->current;
262 while (current != NULL)
263 {
264 found = 1;
265 iter = current;
266 while (NEXT_PAGE(iter) == (iter + SIZEOF_SYSTEM_PAGE))
267 {
269 /* handle pathological case that iter + SIZEOF_SYSTEM_PAGE == 0 */
270 if (iter == NULL) return NULL;
271 found++;
272 if (found == pages)
273 {
274 bin_page = current;
275 if (current == region->current)
276 {
277 region->current = NEXT_PAGE(iter);
278 }
279 else
280 {
281 omAssume(prev != NULL);
282 NEXT_PAGE(prev) = NEXT_PAGE(iter);
283 }
284 return bin_page;
285 }
286 }
287 prev = iter;
288 current = NEXT_PAGE(iter);
289 }
290 return NULL;
291}
292
293/* Alloc a new region and insert into regions ring, set current to new region */
295{
296 omBinPageRegion region = omAllocFromSystem(sizeof(omBinPageRegion_t));
297 om_Info.InternalUsedBytesMalloc+=sizeof(omBinPageRegion_t);
298 void* addr;
299 int pages = (min_pages>om_Opts.PagesPerRegion ? min_pages : om_Opts.PagesPerRegion);
300 size_t size = ((size_t)pages)*SIZEOF_SYSTEM_PAGE;
301
302 addr = _omVallocFromSystem(size, 1);
303 if (addr == NULL)
304 {
305 pages = min_pages;
306 size = min_pages*SIZEOF_SYSTEM_PAGE;
307 addr = omVallocFromSystem(size);
308 }
309
310 omRegisterBinPages(addr, pages);
311 region->addr = addr;
312 region->pages = pages;
313 region->used_pages = 0;
314 region->init_addr = addr;
315 region->init_pages = pages;
316 region->current = NULL;
317 region->next = NULL;
318 region->prev = NULL;
319
320 om_Info.AvailPages += pages;
321
322 om_Info.CurrentRegionsAlloc++;
323 if (om_Info.CurrentRegionsAlloc > om_Info.MaxRegionsAlloc)
324 om_Info.MaxRegionsAlloc = om_Info.CurrentRegionsAlloc;
325
326 return region;
327}
328
329/* Free region */
331{
332 omAssume(region != NULL && region->used_pages == 0);
333
334 om_Info.AvailPages -= region->pages;
335 om_Info.CurrentRegionsAlloc--;
336
337 omUnregisterBinPages(region->addr, region->pages);
338 omVfreeToSystem(region->addr, region->pages*SIZEOF_SYSTEM_PAGE);
339 omFreeSizeToSystem(region, sizeof(omBinPageRegion_t));
340 om_Info.InternalUsedBytesMalloc-=sizeof(omBinPageRegion_t);
341}
342
343/*******************************************************************
344 *
345 * BinPage registration
346 *
347 *******************************************************************/
348
349static void omBinPageIndexFault(unsigned long low_index, unsigned long high_index)
350{
351 unsigned long index_diff = high_index - low_index;
352 omAssume(low_index <= high_index &&
353 (high_index > om_MaxBinPageIndex || low_index < om_MinBinPageIndex));
354
356 {
357 unsigned long i;
358 om_BinPageIndicies = (unsigned long*) omAllocFromSystem((index_diff + 1)*SIZEOF_LONG);
359 om_Info.InternalUsedBytesMalloc+=(index_diff + 1)*SIZEOF_LONG;
360 om_MaxBinPageIndex = high_index;
361 om_MinBinPageIndex = low_index;
362 for (i=0; i<=index_diff; i++) om_BinPageIndicies[i] = 0;
363 }
364 else
365 {
366 unsigned long old_length = om_MaxBinPageIndex - om_MinBinPageIndex + 1;
367 unsigned long new_length = (low_index < om_MinBinPageIndex ?
368 om_MaxBinPageIndex - low_index :
369 high_index - om_MinBinPageIndex) + 1;
370 om_BinPageIndicies = (unsigned long*) omReallocSizeFromSystem(om_BinPageIndicies, old_length*SIZEOF_LONG,
371 new_length*SIZEOF_LONG);
372 om_Info.InternalUsedBytesMalloc+= (new_length-old_length)*SIZEOF_LONG;
373 if (low_index < om_MinBinPageIndex)
374 {
375 long i;
376 unsigned long offset = new_length - old_length;
377 for (i=old_length - 1; i >= 0; i--) om_BinPageIndicies[i+offset] = om_BinPageIndicies[i];
378 for (i=offset-1; i>=0; i--) om_BinPageIndicies[i] = 0;
379 om_MinBinPageIndex = low_index;
380 }
381 else
382 {
383 unsigned long i;
384 for (i=old_length; i<new_length; i++) om_BinPageIndicies[i] = 0;
385 om_MaxBinPageIndex = high_index;
386 }
387 }
388}
389
390static void omRegisterBinPages(void* low_addr, int pages)
391{
392 unsigned long low_index = omGetPageIndexOfAddr(low_addr);
393 char* high_addr = (char *)low_addr + (pages-1)*SIZEOF_SYSTEM_PAGE;
394 unsigned long high_index = omGetPageIndexOfAddr(high_addr);
395 unsigned long shift;
396
397 if (low_index < om_MinBinPageIndex || high_index > om_MaxBinPageIndex)
398 omBinPageIndexFault(low_index, high_index);
399
400 shift = omGetPageShiftOfAddr(low_addr);
401 if (low_index < high_index)
402 {
403 if (shift == 0)
404 {
405 om_BinPageIndicies[low_index-om_MinBinPageIndex] = ULONG_MAX;
406 }
407 else
408 {
409 om_BinPageIndicies[low_index-om_MinBinPageIndex] |= ~ ((((unsigned long) 1) << shift) - 1);
410 }
411 for (shift = low_index+1; shift < high_index; shift++)
412 {
413 om_BinPageIndicies[shift-om_MinBinPageIndex] = ULONG_MAX;
414 }
415 shift = omGetPageShiftOfAddr(high_addr);
416 if (shift == BIT_SIZEOF_LONG - 1)
417 {
418 om_BinPageIndicies[high_index - om_MinBinPageIndex] = ULONG_MAX;
419 }
420 else
421 {
422 om_BinPageIndicies[high_index-om_MinBinPageIndex] |= ((((unsigned long) 1) << (shift + 1)) - 1);
423 }
424 }
425 else
426 {
427 high_index = omGetPageShiftOfAddr(high_addr);
428 while (high_index > shift)
429 {
430 om_BinPageIndicies[low_index-om_MinBinPageIndex] |= (((unsigned long) 1) << high_index);
431 high_index--;
432 }
433 om_BinPageIndicies[low_index-om_MinBinPageIndex] |= (((unsigned long) 1) << shift);
434 }
435}
436
437static void omUnregisterBinPages(void* low_addr, int pages)
438{
439 unsigned long low_index = omGetPageIndexOfAddr(low_addr);
440 char* high_addr = (char *)low_addr + (pages-1)*SIZEOF_SYSTEM_PAGE;
441 unsigned long high_index = omGetPageIndexOfAddr(high_addr);
442 unsigned long shift;
443
444 shift = omGetPageShiftOfAddr(low_addr);
445 if (low_index < high_index)
446 {
447 if (shift == 0)
448 {
450 }
451 else
452 {
453 om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ((((unsigned long) 1) << shift) - 1);
454 }
455 for (shift = low_index+1; shift < high_index; shift++)
456 {
458 }
459 shift = omGetPageShiftOfAddr(high_addr);
460 if (shift == BIT_SIZEOF_LONG - 1)
461 {
462 om_BinPageIndicies[high_index - om_MinBinPageIndex] = 0;
463 }
464 else
465 {
466 om_BinPageIndicies[high_index-om_MinBinPageIndex] &= ~ ((((unsigned long) 1) << (shift + 1)) - 1);
467 }
468 }
469 else
470 {
471 high_index = omGetPageShiftOfAddr(high_addr);
472 while (high_index > shift)
473 {
474 om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ~(((unsigned long) 1) << high_index);
475 high_index--;
476 }
477 om_BinPageIndicies[low_index-om_MinBinPageIndex] &= ~(((unsigned long) 1) << shift);
478 }
479}
480
481/***********************************************************************
482 *
483 * checking routines
484 *
485 *******************************************************************/
486#ifndef OM_NDEBUG
487#include "omDebug.h"
488
490{
492
493 if (region == NULL || iter == NULL) return 0;
495 do
496 {
497 if (region == iter) return 1;
498 iter = iter->next;
499 }
500 while (iter != NULL);
501 return 0;
502}
503
504
506{
507 if (level <= 0) return omError_NoError;
508
509 omCheckReturn(omCheckPtr(region, report, OM_FLR_VAL));
511 omCheckReturnCorrupted(! omIsAddrPageAligned(region->addr) || ! omIsAddrPageAligned(region->current));
512 omCheckReturnCorrupted(region->used_pages < 0);
513 omCheckReturnCorrupted(region->init_pages < 0 || region->init_pages > region->pages);
514
515 if (region->init_pages)
516 {
517 omCheckReturnCorrupted(! omIsAddrPageAligned(region->init_addr));
518 omCheckReturnCorrupted(! (region->init_addr >= region->addr
519 && region->init_addr <= region->addr + (region->pages -1)*SIZEOF_SYSTEM_PAGE));
520 omCheckReturnCorrupted(region->init_addr !=
521 region->addr + (region->pages - region->init_pages)*SIZEOF_SYSTEM_PAGE);
522 }
523
524 omCheckReturn(omCheckList(region->current, level, report, OM_FLR_VAL));
525 omCheckReturnCorrupted(region->current == NULL && region->used_pages + region->init_pages != region->pages);
527 omListLength(region->current)+region->used_pages+region->init_pages != region->pages);
528 return omError_NoError;
529}
530
532{
534
535 if (level <= 0) return omError_NoError;
536 if (iter == NULL) return omError_NoError;
537
542
543
544 if (level > 1)
545 {
548
549 omCheckReturn(omCheckGList(iter, next, level, report, OM_FLR_VAL));
550 omCheckReturn(omCheckGList(iter, prev, level, report, OM_FLR_VAL));
551
553 !=
554 omGListLength(next_last, prev));
555
557
559 while (iter)
560 {
562
563 omCheckReturn(omCheckBinPageRegion(iter, level - 1, report, OM_FLR_VAL));
564 iter = iter->next;
565 }
566
568 while (iter)
569 {
571 omCheckReturn(omCheckBinPageRegion(iter, level - 1, report, OM_FLR_VAL));
572 iter = iter->prev;
573 }
574 }
575 return omError_NoError;
576}
577
579{
581
582 if (region == NULL) return 0;
583 region = omGListLast(region, prev);
584 do
585 {
586 if ((char *)addr >= region->addr
587 && (char *)addr < region->addr + (region->pages)*SIZEOF_SYSTEM_PAGE)
588 return region;
589 region = region->next;
590 }
591 while (region != NULL);
592 return NULL;
593}
594
596{
597 char *c_addr=(char *)addr;
599
600 if (region == NULL) return 0;
601 do
602 {
603 if (c_addr > region->addr && c_addr < region->addr + (region->pages)*SIZEOF_SYSTEM_PAGE)
604 {
605 if (omIsOnList(region->current, omGetPageOfAddr(addr))) return 1;
606 return 0;
607 }
608 region = region->next;
609 }
610 while (region != NULL);
611 return 0;
612}
613
614#endif /* ! OM_NDEBUG */
615#endif /* HAVE_OMALLOC*/
#define BIT_SIZEOF_LONG
Definition: auxiliary.h:80
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
int level(const CanonicalForm &f)
int i
Definition: cfEzgcd.cc:132
CFFListIterator iter
Definition: facAbsBiFact.cc:53
result insert(CFAFactor(LcF, 1, 1))
bool found
Definition: facFactorize.cc:55
if(!FE_OPT_NO_SHELL_FLAG)(void) system(sys)
STATIC_VAR int offset
Definition: janet.cc:29
ListNode * next
Definition: janet.h:31
void * _omVallocFromSystem(size_t size, int fail)
void * omAllocFromSystem(size_t size)
void omVfreeToSystem(void *page, size_t size)
void omFreeSizeToSystem(void *addr, size_t size)
void * omReallocSizeFromSystem(void *addr, size_t oldsize, size_t newsize)
#define omVallocFromSystem(size)
Definition: omAllocSystem.h:28
omError_t omCheckBinPageRegions(int level, omError_t report, OM_FLR_DECL)
Definition: omBinPage.c:531
#define NEXT_PAGE(page)
Definition: omBinPage.c:95
unsigned long om_MaxBinPageIndex
Definition: omBinPage.c:36
char * init_addr
Definition: omBinPage.c:27
void omFreeBinPages(omBinPage bin_page, int how_many)
Definition: omBinPage.c:206
omBinPageRegion next
Definition: omBinPage.c:25
OM_INLINE_LOCAL void omInsertRegionAfter(omBinPageRegion insert, omBinPageRegion after)
Definition: omBinPage.c:66
#define OM_IS_EMPTY_REGION(region)
Definition: omBinPage.c:96
unsigned long om_MinBinPageIndex
Definition: omBinPage.c:37
static void omUnregisterBinPages(void *low_addr, int pages)
Definition: omBinPage.c:437
omBinPageRegion omFindRegionOfAddr(void *addr)
Definition: omBinPage.c:578
static omBinPageRegion om_CurrentBinPageRegion
Definition: omBinPage.c:35
static void omFreeBinPagesRegion(omBinPageRegion region)
Definition: omBinPage.c:330
int omIsKnownMemoryRegion(omBinPageRegion region)
Definition: omBinPage.c:489
omBinPage omAllocBinPages(int how_many)
Definition: omBinPage.c:149
omError_t omCheckBinPageRegion(omBinPageRegion region, int level, omError_t report, OM_FLR_DECL)
Definition: omBinPage.c:505
OM_INLINE_LOCAL void omInsertRegionBefore(omBinPageRegion insert, omBinPageRegion before)
Definition: omBinPage.c:79
static void omBinPageIndexFault(unsigned long low_index, unsigned long high_index)
Definition: omBinPage.c:349
static omBinPageRegion omAllocNewBinPagesRegion(int min_pages)
Definition: omBinPage.c:294
int omIsAddrOnFreeBinPage(void *addr)
Definition: omBinPage.c:595
omBinPage omAllocBinPage()
Definition: omBinPage.c:98
unsigned long * om_BinPageIndicies
Definition: omBinPage.c:38
static void * omTakeOutConsecutivePages(omBinPageRegion region, int how_many)
Definition: omBinPage.c:254
OM_INLINE_LOCAL void omTakeOutRegion(omBinPageRegion region)
Definition: omBinPage.c:49
omBinPageRegion prev
Definition: omBinPage.c:26
static void omRegisterBinPages(void *low_addr, int pages)
Definition: omBinPage.c:390
#define omIsAddrPageAligned(addr)
Definition: omBinPage.h:16
#define omGetPageOfAddr(addr)
Definition: omBinPage.h:19
#define omGetPageShiftOfAddr(addr)
Definition: omBinPage.h:60
#define omGetPageIndexOfAddr(addr)
Definition: omBinPage.h:63
omError_t omCheckPtr(const void *ptr, omError_t report, OM_FLR_DECL)
Definition: omDebugCheck.c:136
#define omCheckReturnError(cond, error)
Definition: omDebug.h:172
#define omCheckReturnCorrupted(cond)
Definition: omDebug.h:174
#define omCheckReturn(cond)
Definition: omDebug.h:170
#define omAssume(x)
Definition: omError.h:85
@ omError_InternalBug
Definition: omError.h:20
@ omError_NoError
Definition: omError.h:18
enum omError_e omError_t
Definition: omError.h:44
#define NULL
Definition: omList.c:12
#define omIsOnList(ptr, addr)
Definition: omList.h:68
#define omCheckGList(ptr, next, level, report, OM_FLR_VAL)
Definition: omList.h:115
#define omGListLength(ptr, next)
Definition: omList.h:94
#define omListLength(ptr)
Definition: omList.h:62
#define omGListLast(ptr, next)
Definition: omList.h:96
#define omCheckList(ptr, level, report, OM_FLR_VAL)
Definition: omList.h:83
omOpts_t om_Opts
Definition: omOpts.c:13
omInfo_t om_Info
Definition: omStats.c:16
omBinPage_t * omBinPage
Definition: omStructs.h:16
omBinPageRegion_t * omBinPageRegion
Definition: omStructs.h:20