source: git/omalloc/om_Alloc.c @ bee06d

fieker-DuValspielwiese
Last change on this file since bee06d was 599326, checked in by Kai Krüger <krueger@…>, 14 years ago
Anne, Kai, Frank: - changes to #include "..." statements to allow cleaner build structure - affected directories: omalloc, kernel, Singular - not yet done: IntergerProgramming git-svn-id: file:///usr/local/Singular/svn/trunk@13032 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.5 KB
RevLine 
[e70e45]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
[341696]6 *  Version: $Id$
[e70e45]7 *******************************************************************/
8#ifndef OM_ALLOC_C
9#define OM_ALLOC_C
10
[599326]11#include <omalloc/om_Alloc.h>
[e70e45]12/*******************************************************************
[13fe1b]13 *
[e70e45]14 *  global variables
[13fe1b]15 *
[e70e45]16 *******************************************************************/
17
18omBinPage_t om_ZeroPage[] = {{0, NULL, NULL, NULL, NULL}};
19omSpecBin om_SpecBin = NULL;
20
[599326]21#include <omalloc/omTables.inc>
[e70e45]22
23
24/*******************************************************************
[13fe1b]25 *
[e70e45]26 *  Local stuff
[13fe1b]27 *
[e70e45]28 *******************************************************************/
29
30/* Get new page and initialize */
31static omBinPage omAllocNewBinPage(omBin bin)
32{
33  omBinPage newpage;
34  void* tmp;
35  int i = 1;
36
37  if (bin->max_blocks > 0) newpage = omAllocBinPage();
38  else newpage = omAllocBinPages(-bin->max_blocks);
39
40  omAssume(omIsAddrPageAligned((void*) newpage));
41
42  omSetTopBinAndStickyOfPage(newpage, bin, bin->sticky);
43  newpage->used_blocks = -1;
[13fe1b]44  newpage->current = (void*) (((char*)newpage) + SIZEOF_OM_BIN_PAGE_HEADER);
[e70e45]45  tmp = newpage->current;
46  while (i < bin->max_blocks)
47  {
48    tmp = *((void**)tmp) = ((void**) tmp) + bin->sizeW;
49    i++;
50  }
51  *((void**)tmp) = NULL;
[13fe1b]52  omAssume(omListLength(newpage->current) ==
[e70e45]53           (bin->max_blocks > 1 ? bin->max_blocks : 1));
54  return newpage;
55}
56
57/* primitives for handling of list of pages */
58OM_INLINE_LOCAL void omTakeOutBinPage(omBinPage page, omBin bin)
59{
[13fe1b]60  if (bin->current_page == page)
[e70e45]61  {
[13fe1b]62    if (page->next == NULL)
[e70e45]63    {
64      if (page->prev == NULL)
65      {
66        omAssume(bin->last_page == page);
67        bin->last_page = NULL;
68        bin->current_page = om_ZeroPage;
69        return;
70      }
71      bin->current_page = page->prev;
72    }
73    else
74      bin->current_page = page->next;
75  }
76  if (bin->last_page == page)
77  {
78    omAssume(page->prev != NULL && page->next == NULL);
79    bin->last_page = page->prev;
80  }
81  else
82  {
83    omAssume(page->next != NULL);
84    page->next->prev = page->prev;
85  }
86  if (page->prev != NULL) page->prev->next = page->next;
87}
88
89OM_INLINE_LOCAL void omInsertBinPage(omBinPage after, omBinPage page, omBin bin)
90{
91  if (bin->current_page == om_ZeroPage)
92  {
93    omAssume(bin->last_page == NULL);
94    page->next = NULL;
95    page->prev = NULL;
96    bin->current_page = page;
97    bin->last_page = page;
98  }
99  else
100  {
101    omAssume(after != NULL && bin->last_page != NULL);
[13fe1b]102    if (after == bin->last_page)
[e70e45]103    {
104      bin->last_page = page;
105    }
106    else
107    {
108      omAssume(after->next != NULL);
109      after->next->prev = page;
110    }
111    page->next = after->next;
112    after->next = page;
113    page->prev = after;
114  }
115}
116
117/* bin->current_page is empty, get new bin->current_page, return addr*/
118void* omAllocBinFromFullPage(omBin bin)
119{
120  void* addr;
121  omBinPage newpage;
122  omAssume(bin->current_page->current == NULL);
[13fe1b]123
[e70e45]124  if (bin->current_page != om_ZeroPage)
125  {
126    omAssume(bin->last_page != NULL);
127    /* Set this to zero, but preserve the first bit,
128       so that tracking works */
129#ifdef OM_HAVE_TRACK
[384936]130    bin->current_page->used_blocks &= (((unsigned long) 1) << (BIT_SIZEOF_LONG -1));
[13fe1b]131#else
[e70e45]132    bin->current_page->used_blocks = 0;
133#endif
134  }
135
[f103fb]136  if (!bin->sticky && bin->current_page->next != NULL)
[e70e45]137  {
138    omAssume(bin->current_page->next->current != NULL);
139    newpage = bin->current_page->next;
140  }
141  else
142  {
143    // need to Allocate new page
144    newpage = omAllocNewBinPage(bin);
145    omInsertBinPage(bin->current_page, newpage, bin);
146  }
[13fe1b]147
[e70e45]148  bin->current_page = newpage;
[13fe1b]149  omAssume(newpage != NULL && newpage != om_ZeroPage &&
[e70e45]150           newpage->current != NULL);
151  __omTypeAllocFromNonEmptyPage(void*, addr, newpage);
152  return addr;
153}
154
155
[13fe1b]156/* page->used_blocks <= 0, so, either free page or reallocate to
[e70e45]157   the right of current_page */
158/*
[13fe1b]159 * Now: there are three different strategies here, on what to do with
[e70e45]160 * pages which were full and now have a free block:
161 * 1.) Insert at the end (default)
162 * 2.) Insert after current_page  => #define PAGE_AFTER_CURRENT
163 * 3.) Let it be new current_page => #define PAGE_BEFORE_CURRENT
[13fe1b]164 * Still need to try out which is best
[e70e45]165 */
166void  omFreeToPageFault(omBinPage page, void* addr)
167{
168  omBin bin;
[8fe650]169  omAssume(page->used_blocks <= 0L);
[e70e45]170
171#ifdef OM_HAVE_TRACK
[8fe650]172  if (page->used_blocks < 0L)
[e70e45]173  {
174    omFreeTrackAddr(addr);
175    return;
176  }
177#endif
[13fe1b]178
[e70e45]179  bin = omGetBinOfPage(page);
[8fe650]180  if ((page->current != NULL) || (bin->max_blocks <= 1))
[e70e45]181  {
182    // all blocks of page are now collected
183    omTakeOutBinPage(page, bin);
184    // page can be freed
185    if (bin->max_blocks > 0)
186      omFreeBinPage(page);
187    else
188      omFreeBinPages(page, - bin->max_blocks);
189#ifdef OM_HAVE_TRACK
190    om_JustFreedPage = page;
[13fe1b]191#endif
[e70e45]192  }
193  else
194  {
195    // page was full
196    page->current = addr;
197    page->used_blocks = bin->max_blocks - 2;
198    *((void**)addr) = NULL;
199
200    omTakeOutBinPage(page, bin);
201#if defined(PAGE_BEFORE_CURRENT)
202    if (bin->current_page->prev != NULL)
203      omInsertBinPage(bin->current_page->prev, page);
204    else
205      omInsertBinPage(bin->current_page, page, bin);
206    bin->current_page = page;
207#else
208#  if defined(PAGE_AFTER_CURRENT)
[f103fb]209      omInsertBinPage(bin->current_page, page, bin);
[e70e45]210#  else
[f103fb]211      omInsertBinPage(bin->last_page, page, bin);
[e70e45]212#  endif
213#endif
214  }
215}
216
217/*******************************************************************
[13fe1b]218 *
[e70e45]219 *  DoRealloc
[13fe1b]220 *
[e70e45]221 *******************************************************************/
222#ifdef OM_ALIGNMNET_NEEDS_WORK
223#define DO_ZERO(flag) (flag & 1)
224#else
225#define DO_ZERO(flag)    flag
226#endif
227
228void* omDoRealloc(void* old_addr, size_t new_size, int flag)
229{
230  void* new_addr;
[13fe1b]231
[e70e45]232  if (!omIsBinPageAddr(old_addr) && new_size > OM_MAX_BLOCK_SIZE)
233  {
234    if (DO_ZERO(flag))
235      return omRealloc0Large(old_addr, new_size);
236    else
237      return omReallocLarge(old_addr, new_size);
238  }
239  else
240  {
241    size_t old_size = omSizeOfAddr(old_addr);
242    size_t min_size;
[13fe1b]243
[e70e45]244    omAssume(OM_IS_ALIGNED(old_addr));
[13fe1b]245
[e70e45]246#ifdef OM_ALIGNMENT_NEEDS_WORK
247    if (flag & 2)
248      __omTypeAllocAligned(void*, new_addr, new_size);
249    else
250#endif
251      __omTypeAlloc(void*, new_addr, new_size);
[13fe1b]252
[e70e45]253    new_size = omSizeOfAddr(new_addr);
254    min_size = (old_size < new_size ? old_size : new_size);
255    omMemcpyW(new_addr, old_addr, min_size >> LOG_SIZEOF_LONG);
[13fe1b]256
[e70e45]257    if (DO_ZERO(flag) && (new_size > old_size))
[13fe1b]258      omMemsetW((char*) new_addr + min_size, 0, (new_size - old_size) >> LOG_SIZEOF_LONG);
259
[e70e45]260    __omFreeSize(old_addr, old_size);
261
262    return new_addr;
263  }
264}
265#endif /* OM_ALLOC_C */
Note: See TracBrowser for help on using the repository browser.