Loading...
Searching...
No Matches
om_Alloc.c
Go to the documentation of this file.
/*******************************************************************
* File: omAlloc.c
* Purpose: implementation of main omalloc functions
* Author: obachman@mathematik.uni-kl.de (Olaf Bachmann)
* Created: 11/99
*******************************************************************/
#ifndef OM_ALLOC_C
#define OM_ALLOC_C
#include "omalloc.h"
#ifdef HAVE_OMALLOC
/*******************************************************************
*
* global variables
*
*******************************************************************/
omBinPage_t om_ZeroPage[] = {{0, NULL, NULL, NULL, NULL}};
omSpecBin om_SpecBin = NULL;
#include "omalloc/omTables.inc"
/*******************************************************************
*
* Local stuff
*
*******************************************************************/
/* Get new page and initialize */
static omBinPage omAllocNewBinPage(omBin bin)
{
omBinPage newpage;
void* tmp;
int i = 1;
if (bin->max_blocks > 0) newpage = omAllocBinPage();
else newpage = omAllocBinPages(-bin->max_blocks);
omAssume(omIsAddrPageAligned((void*) newpage));
omSetTopBinAndStickyOfPage(newpage, bin, bin->sticky);
newpage->used_blocks = -1;
newpage->current = (void*) (((char*)newpage) + SIZEOF_OM_BIN_PAGE_HEADER);
tmp = newpage->current;
while (i < bin->max_blocks)
{
tmp = *((void**)tmp) = ((void**) tmp) + bin->sizeW;
i++;
}
*((void**)tmp) = NULL;
omAssume(omListLength(newpage->current) ==
(bin->max_blocks > 1 ? bin->max_blocks : 1));
return newpage;
}
/* primitives for handling of list of pages */
OM_INLINE_LOCAL void omTakeOutBinPage(omBinPage page, omBin bin)
{
if (bin->current_page == page)
{
if (page->next == NULL)
{
if (page->prev == NULL)
{
omAssume(bin->last_page == page);
bin->last_page = NULL;
bin->current_page = om_ZeroPage;
return;
}
bin->current_page = page->prev;
}
else
bin->current_page = page->next;
}
if (bin->last_page == page)
{
omAssume(page->prev != NULL && page->next == NULL);
bin->last_page = page->prev;
}
else
{
omAssume(page->next != NULL);
page->next->prev = page->prev;
}
if (page->prev != NULL) page->prev->next = page->next;
}
OM_INLINE_LOCAL void omInsertBinPage(omBinPage after, omBinPage page, omBin bin)
{
if (bin->current_page == om_ZeroPage)
{
omAssume(bin->last_page == NULL);
page->next = NULL;
page->prev = NULL;
bin->current_page = page;
bin->last_page = page;
}
else
{
omAssume(after != NULL && bin->last_page != NULL);
if (after == bin->last_page)
{
bin->last_page = page;
}
else
{
omAssume(after->next != NULL);
after->next->prev = page;
}
page->next = after->next;
after->next = page;
page->prev = after;
}
}
/* bin->current_page is empty, get new bin->current_page, return addr*/
void* omAllocBinFromFullPage(omBin bin)
{
void* addr;
omBinPage newpage;
omAssume(bin->current_page->current == NULL);
if (bin->current_page != om_ZeroPage)
{
omAssume(bin->last_page != NULL);
/* Set this to zero, but preserve the first bit,
so that tracking works */
#ifdef OM_HAVE_TRACK
bin->current_page->used_blocks &= (((unsigned long) 1) << (BIT_SIZEOF_LONG -1));
#else
bin->current_page->used_blocks = 0;
#endif
}
if (!bin->sticky && bin->current_page->next != NULL)
{
omAssume(bin->current_page->next->current != NULL);
newpage = bin->current_page->next;
}
else
{
// need to Allocate new page
newpage = omAllocNewBinPage(bin);
omInsertBinPage(bin->current_page, newpage, bin);
}
bin->current_page = newpage;
omAssume(newpage != NULL && newpage != om_ZeroPage &&
newpage->current != NULL);
__omTypeAllocFromNonEmptyPage(void*, addr, newpage);
return addr;
}
/* page->used_blocks <= 0, so, either free page or reallocate to
the right of current_page */
/*
* Now: there are three different strategies here, on what to do with
* pages which were full and now have a free block:
* 1.) Insert at the end (default)
* 2.) Insert after current_page => #define PAGE_AFTER_CURRENT
* 3.) Let it be new current_page => #define PAGE_BEFORE_CURRENT
* Still need to try out which is best
*/
void omFreeToPageFault(omBinPage page, void* addr)
{
omBin bin;
omAssume(page->used_blocks <= 0L);
#ifdef OM_HAVE_TRACK
if (page->used_blocks < 0L)
{
omFreeTrackAddr(addr);
return;
}
#endif
bin = omGetBinOfPage(page);
if ((page->current != NULL) || (bin->max_blocks <= 1))
{
// all blocks of page are now collected
omTakeOutBinPage(page, bin);
// page can be freed
if (bin->max_blocks > 0)
omFreeBinPage(page);
else
omFreeBinPages(page, - bin->max_blocks);
#ifdef OM_HAVE_TRACK
om_JustFreedPage = page;
#endif
}
else
{
// page was full
page->current = addr;
page->used_blocks = bin->max_blocks - 2;
*((void**)addr) = NULL;
omTakeOutBinPage(page, bin);
#if defined(PAGE_BEFORE_CURRENT)
if (bin->current_page->prev != NULL)
omInsertBinPage(bin->current_page->prev, page);
else
omInsertBinPage(bin->current_page, page, bin);
bin->current_page = page;
#else
# if defined(PAGE_AFTER_CURRENT)
omInsertBinPage(bin->current_page, page, bin);
# else
omInsertBinPage(bin->last_page, page, bin);
# endif
#endif
}
}
/*******************************************************************
*
* DoRealloc
*
*******************************************************************/
#ifdef OM_ALIGNMNET_NEEDS_WORK
#define DO_ZERO(flag) (flag & 1)
#else
#define DO_ZERO(flag) flag
#endif
void* omDoRealloc(void* old_addr, size_t new_size, int flag)
{
void* new_addr;
if (!omIsBinPageAddr(old_addr) && new_size > OM_MAX_BLOCK_SIZE)
{
if (DO_ZERO(flag))
return omRealloc0Large(old_addr, new_size);
else
return omReallocLarge(old_addr, new_size);
}
else
{
size_t old_size = omSizeOfAddr(old_addr);
size_t min_size;
omAssume(OM_IS_ALIGNED(old_addr));
#ifdef OM_ALIGNMENT_NEEDS_WORK
if (flag & 2)
__omTypeAllocAligned(void*, new_addr, new_size);
else
#endif
__omTypeAlloc(void*, new_addr, new_size);
new_size = omSizeOfAddr(new_addr);
min_size = (old_size < new_size ? old_size : new_size);
omMemcpyW(new_addr, old_addr, min_size >> LOG_SIZEOF_LONG);
if (DO_ZERO(flag) && (new_size > old_size))
omMemsetW((char*) new_addr + min_size, 0, (new_size - old_size) >> LOG_SIZEOF_LONG);
__omFreeSize(old_addr, old_size);
return new_addr;
}
}
#endif
#endif /* OM_ALLOC_C */
BIT_SIZEOF_LONG
#define BIT_SIZEOF_LONG
Definition auxiliary.h:80
i
int i
Definition cfEzgcd.cc:132
omSetTopBinAndStickyOfPage
#define omSetTopBinAndStickyOfPage(page, bin, sticky)
Definition omAllocPrivate.h:74
SIZEOF_OM_BIN_PAGE_HEADER
#define SIZEOF_OM_BIN_PAGE_HEADER
Definition omAllocPrivate.h:31
__omTypeAllocFromNonEmptyPage
#define __omTypeAllocFromNonEmptyPage(type, addr, page)
Definition omAllocPrivate.h:115
__omTypeAlloc
#define __omTypeAlloc(type, addr, size)
Definition omAllocPrivate.h:213
__omTypeAllocAligned
#define __omTypeAllocAligned
Definition omAllocPrivate.h:280
__omFreeSize
#define __omFreeSize(addr, size)
Definition omAllocPrivate.h:284
omRealloc0Large
void * omRealloc0Large(void *old_addr, size_t new_size)
Definition omAllocSystem.c:89
omReallocLarge
void * omReallocLarge(void *old_addr, size_t new_size)
Definition omAllocSystem.c:57
omSizeOfAddr
size_t omSizeOfAddr(const void *addr)
Definition omAllocSystem.c:110
omFreeBinPages
void omFreeBinPages(omBinPage bin_page, int how_many)
Definition omBinPage.c:206
omAllocBinPages
omBinPage omAllocBinPages(int how_many)
Definition omBinPage.c:149
omAllocBinPage
omBinPage omAllocBinPage()
Definition omBinPage.c:98
omIsBinPageAddr
#define omIsBinPageAddr(addr)
Definition omBinPage.h:68
omIsAddrPageAligned
#define omIsAddrPageAligned(addr)
Definition omBinPage.h:16
omFreeBinPage
#define omFreeBinPage(addr)
Definition omBinPage.h:88
omAssume
#define omAssume(x)
Definition omError.h:85
omGetBinOfPage
OM_INLINE_DECL omBin omGetBinOfPage(omBinPage page)
NULL
#define NULL
Definition omList.c:12
omListLength
#define omListLength(ptr)
Definition omList.h:62
omMemcpyW
#define omMemcpyW(p1, p2, l)
Definition omMemOps.h:29
omMemsetW
#define omMemsetW(P1, W, L)
Definition omMemOps.h:161
omBinPage
omBinPage_t * omBinPage
Definition omStructs.h:16
omBin
omBin_t * omBin
Definition omStructs.h:12
omSpecBin
omSpecBin_t * omSpecBin
Definition omStructs.h:30
OM_MAX_BLOCK_SIZE
#define OM_MAX_BLOCK_SIZE
Definition omTables.c:31
om_ZeroPage
omBinPage_t om_ZeroPage[]
Definition om_Alloc.c:19
om_SpecBin
omSpecBin om_SpecBin
Definition om_Alloc.c:20
omAllocBinFromFullPage
void * omAllocBinFromFullPage(omBin bin)
Definition om_Alloc.c:119
omInsertBinPage
OM_INLINE_LOCAL void omInsertBinPage(omBinPage after, omBinPage page, omBin bin)
Definition om_Alloc.c:90
DO_ZERO
#define DO_ZERO(flag)
Definition om_Alloc.c:226
omTakeOutBinPage
OM_INLINE_LOCAL void omTakeOutBinPage(omBinPage page, omBin bin)
Definition om_Alloc.c:59
omFreeToPageFault
void omFreeToPageFault(omBinPage page, void *addr)
Definition om_Alloc.c:167
omAllocNewBinPage
static omBinPage omAllocNewBinPage(omBin bin)
Definition om_Alloc.c:32
omDoRealloc
void * omDoRealloc(void *old_addr, size_t new_size, int flag)
Definition om_Alloc.c:229
omalloc.h