source: git/omalloc/omAllocSystem.c @ 8babe7f

spielwiese
Last change on this file since 8babe7f was 8babe7f, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
FIX: omMmap.c is needed for building with Valloc with Mmap
  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*******************************************************************
2 *  File:    omAllocSystem.c
3 *  Purpose: implementation of main lowl-level alloc functions
4 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
5 *  Created: 11/99
6 *  Version: $Id$
7 *******************************************************************/
8#ifndef OM_ALLOC_SYSTEM_C
9#define OM_ALLOC_SYSTEM_C
10
11#include <unistd.h>
12#include <mylimits.h>
13
14
15#include <omalloc/omConfig.h>
16#include <omalloc/omDefaultConfig.h>
17#include <omalloc/omMalloc.h>
18#include <omalloc/omalloc.h>
19/* include after omMalloc.h */
20#include <string.h>
21
22#define OM_MALLOC_FROM_SYSTEM   OM_MALLOC_MALLOC
23#define OM_REALLOC_FROM_SYSTEM  OM_MALLOC_REALLOC
24#define OM_FREE_TO_SYSTEM       OM_MALLOC_FREE
25
26/*******************************************************************
27 *
28 *  AllocLarge/FreeLarge if malloc can not return sizeof(addr)
29 *
30 *******************************************************************/
31/* allocation of large addr */
32#if defined(OM_MALLOC_PROVIDES_SIZEOF_ADDR)
33#define _omSizeOfLargeAddr(addr) (OM_MALLOC_SIZEOF_ADDR(addr) & (~SIZEOF_OM_ALIGNMENT_1))
34#else
35void* omAllocLarge(size_t size)
36{
37  char* addr;
38  size = OM_ALIGN_SIZE(size);
39  addr = omAllocFromSystem(size + SIZEOF_STRICT_ALIGNMENT);
40  *((size_t*) addr) = size;
41  return (void *)(addr + SIZEOF_STRICT_ALIGNMENT);
42}
43
44void* omReallocLarge(void* old_addr, size_t new_size)
45{
46  char* _old_addr;
47  char* new_addr;
48
49  omAssume(omIsLargeAddr(old_addr));
50
51  new_size = OM_ALIGN_SIZE(new_size);
52  _old_addr = (char *)old_addr - SIZEOF_STRICT_ALIGNMENT;
53  new_addr = omReallocSizeFromSystem(_old_addr,
54                                     *((size_t*) _old_addr) + SIZEOF_STRICT_ALIGNMENT,
55                                     new_size + SIZEOF_STRICT_ALIGNMENT);
56  *((size_t*) new_addr) = new_size;
57  return (void *)(new_addr + SIZEOF_STRICT_ALIGNMENT);
58}
59
60void omFreeLarge(void* addr)
61{
62  char* _addr = (char *)addr - SIZEOF_STRICT_ALIGNMENT;
63  omFreeSizeToSystem(_addr, *((size_t*) _addr) + SIZEOF_STRICT_ALIGNMENT);
64}
65
66#define _omSizeOfLargeAddr(addr)  (*((size_t*) ((char*) addr - SIZEOF_STRICT_ALIGNMENT)))
67#endif /* OM_MALLOC_PROVIDES_SIZEOF_ADDR */
68
69void* omAlloc0Large(size_t size)
70{
71  void* addr = omAllocLarge(size);
72  size = omSizeOfLargeAddr(addr);
73  memset(addr, 0, size);
74  return addr;
75}
76
77void* omRealloc0Large(void* old_addr, size_t new_size)
78{
79  size_t old_size;
80  char* new_addr;
81
82  omAssume(!omIsBinPageAddr(old_addr));
83
84  old_size = omSizeOfLargeAddr(old_addr);
85
86  new_addr = omReallocLarge(old_addr, new_size);
87  new_size = omSizeOfLargeAddr(new_addr);
88  if (new_size > old_size)
89    memset(new_addr + old_size, 0, new_size - old_size);
90  return (void *)new_addr;
91}
92
93size_t omSizeOfLargeAddr(void* addr)
94{
95  return _omSizeOfLargeAddr((char *)addr);
96}
97
98size_t omSizeOfAddr(const void* addr)
99{
100
101  return (omIsBinPageAddr(addr) ?
102#ifdef OM_HAVE_TRACK
103          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr((char *)addr) : omSizeOfBinAddr(addr)) :
104#else
105          omSizeOfBinAddr(addr) :
106#endif
107          omSizeOfLargeAddr((char *)addr));
108}
109
110size_t omSizeWOfAddr(void* addr)
111{
112
113  return (omIsBinPageAddr(addr) ?
114#ifdef OM_HAVE_TRACK
115          (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr(addr) >> LOG_SIZEOF_LONG : omSizeWOfBinAddr(addr)) :
116#else
117          omSizeWOfBinAddr(addr) :
118#endif
119          omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG);
120}
121
122/*******************************************************************
123 *
124 *  Valloc
125 *
126 *******************************************************************/
127#ifdef OM_HAVE_VALLOC_MMAP
128
129#include "omMmap.c"
130
131#define OM_VALLOC_FROM_SYSTEM   omVallocMmap
132#define OM_VFREE_TO_SYSTEM      omVfreeMmap
133
134#elif defined(OM_HAVE_VALLOC_MALLOC)
135
136#define OM_VALLOC_FROM_SYSTEM OM_MALLOC_VALLOC
137#define OM_VFREE_TO_SYSTEM    OM_MALLOC_VFREE
138
139#else
140
141#define OM_VALLOC_FROM_SYSTEM   omEmulateValloc
142#define OM_VFREE_TO_SYSTEM      omEmulateVfree
143
144#define OM_ALIGN_PAGE(addr) ( ((long)addr + (SIZEOF_SYSTEM_PAGE -1)) & ~(SIZEOF_SYSTEM_PAGE - 1))
145/* now we implement an emulation */
146void* omEmulateValloc(size_t size)
147{
148  void* addr;
149  size_t padding = SIZEOF_VOIDP;
150  size = OM_ALIGN_SIZE(size);
151  while (1)
152  {
153    addr = OM_MALLOC_FROM_SYSTEM(size + padding);
154    if (addr == NULL) return NULL;
155    if ((OM_ALIGN_PAGE(addr) + SIZEOF_VOIDP) - (long) addr <= padding)
156    {
157      void* ret_addr = (void*) OM_ALIGN_PAGE(addr);
158      *((void**) ((void*) ret_addr + size)) = addr;
159      return ret_addr;
160    }
161    else
162    {
163      OM_FREE_TO_SYSTEM(addr);
164      padding = padding << 1;
165    }
166  }
167}
168
169void omEmulateVfree(void* addr, size_t size)
170{
171  size = OM_ALIGN_SIZE(size);
172  OM_FREE_TO_SYSTEM( *((void**) ((void*) addr + size)) );
173}
174#endif /* OM_HAVE_VALLOC_MMAP */
175
176/*******************************************************************
177 *
178 *  System-level Alloc/Free
179 *
180 *******************************************************************/
181void* omAllocFromSystem(size_t size)
182{
183  void* ptr;
184
185  ptr = OM_MALLOC_FROM_SYSTEM(size);
186  if (ptr == NULL)
187  {
188    OM_MEMORY_LOW_HOOK();
189    ptr = OM_MALLOC_FROM_SYSTEM(size);
190    if (ptr == NULL)
191    {
192      OM_OUT_OF_MEMORY_HOOK();
193      exit(1);
194    }
195  }
196
197#ifndef OM_NDEBUG
198  if (((unsigned long) ptr) + size > om_MaxAddr)
199    om_MaxAddr = ((unsigned long) ptr) + size;
200  if (((unsigned long) ptr) < om_MinAddr)
201    om_MinAddr = ((unsigned long) ptr);
202#endif
203
204  om_Info.CurrentBytesFromMalloc += size;
205  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
206  {
207    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
208#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
209    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
210      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
211#endif
212#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
213    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
214    if (om_Info.MaxBytesFromMalloc
215#ifndef OM_HAVE_VALLOC_MMAP
216        + om_Info.CurrentBytesFromValloc
217#endif
218        > om_Info.MaxBytesSbrk)
219    {
220      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
221    }
222#endif
223  }
224  OM_MALLOC_HOOK(size);
225  return ptr;
226}
227
228void* omReallocFromSystem(void* addr, size_t newsize)
229{
230  return omReallocSizeFromSystem(addr, omSizeOfAddr(addr), newsize);
231}
232
233void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize)
234{
235  void* res;
236
237  res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
238  if (res == NULL)
239  {
240    OM_MEMORY_LOW_HOOK();
241    /* Can do a realloc again: manpage reads:
242       "If realloc() fails the original block is left untouched -
243       it is not freed or moved." */
244    res = OM_REALLOC_FROM_SYSTEM(addr, newsize);
245    if (res == NULL)
246    {
247      OM_OUT_OF_MEMORY_HOOK();
248      /* should never get here */
249      omAssume(0);
250      exit(1);
251    }
252  }
253
254#ifndef OM_NDEBUG
255  if (((unsigned long) res) + newsize > om_MaxAddr)
256    om_MaxAddr = ((unsigned long) res) + newsize;
257  if (((unsigned long) res) < om_MinAddr)
258    om_MinAddr = ((unsigned long) res);
259#endif
260
261  om_Info.CurrentBytesFromMalloc += (long) newsize - (long) oldsize;
262
263
264  if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc)
265  {
266    om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc;
267#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
268    if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
269      om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
270#endif
271#if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
272    if (om_Info.MaxBytesFromMalloc
273#ifndef OM_HAVE_VALLOC_MMAP
274        + om_Info.CurrentBytesFromValloc
275#endif
276        > om_Info.MaxBytesSbrk)
277    {
278      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
279    }
280#endif
281  }
282
283  OM_REALLOC_HOOK(oldsize, newsize);
284  return res;
285}
286
287void omFreeToSystem(void* addr)
288{
289  omFreeSizeToSystem(addr, omSizeOfAddr(addr));
290}
291
292void omFreeSizeToSystem(void* addr, size_t size)
293{
294  OM_FREE_TO_SYSTEM( addr );
295  om_Info.CurrentBytesFromMalloc -= size;
296  OM_FREE_HOOK(size);
297}
298
299void* _omVallocFromSystem(size_t size, int fail)
300{
301  void* page = OM_VALLOC_FROM_SYSTEM(size);
302  if (page == NULL)
303  {
304    OM_MEMORY_LOW_HOOK();
305    page = OM_VALLOC_FROM_SYSTEM(size);
306    if (page == NULL)
307    {
308      if (fail) return NULL;
309      else
310      {
311        OM_OUT_OF_MEMORY_HOOK();
312        /* should never get here */
313        omAssume(0);
314        exit(1);
315      }
316    }
317  }
318
319#ifndef OM_NDEBUG
320  if (((unsigned long) page) + size > om_MaxAddr)
321    om_MaxAddr = ((unsigned long) page) + size;
322  if (((unsigned long) page) < om_MinAddr)
323    om_MinAddr = ((unsigned long) page);
324#endif
325
326  omAssume(omIsAddrPageAligned(page));
327  om_Info.CurrentBytesFromValloc += size;
328  if (om_Info.CurrentBytesFromValloc > om_Info.MaxBytesFromValloc)
329  {
330    om_Info.MaxBytesFromValloc = om_Info.CurrentBytesFromValloc;
331#if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM)
332    if (om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem)
333      om_Info.MaxBytesSystem = om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM;
334#endif
335#if defined(HAVE_SBRK) && !defined(OM_HAVE_VALLOC_MMAP) && !defined(OM_MALLOC_MAX_BYTES_SBRK)
336    if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size;
337    if (om_Info.CurrentBytesFromMalloc + om_Info.CurrentBytesFromValloc > om_Info.MaxBytesSbrk)
338    {
339      om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit;
340      omAssume(om_Info.MaxBytesSbrk >= om_Info.CurrentBytesFromMalloc
341               + om_Info.CurrentBytesFromValloc);
342    }
343#endif
344  }
345  OM_VALLOC_HOOK(size);
346  return page;
347}
348
349void omVfreeToSystem(void* page, size_t size)
350{
351  omAssume(omIsAddrPageAligned(page));
352  OM_VFREE_TO_SYSTEM(page, size);
353  om_Info.CurrentBytesFromValloc  -= size;
354  OM_VFREE_HOOK(size);
355}
356
357#endif /* OM_ALLOC_SYSTEM_C */
Note: See TracBrowser for help on using the repository browser.