/programs/develop/open watcom/trunk/clib/heap/amblksiz.c |
---|
0,0 → 1,48 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Defines the minimum block size requested from the OS for |
* the heap manager. |
* |
****************************************************************************/ |
#include "variety.h" |
#include <stdlib.h> |
#include <limits.h> |
#if defined(__NT__) |
_WCRTLINKD unsigned _WCNEAR _amblksiz = 64*1024; |
#elif defined(__WINDOWS_386__) |
_WCRTLINKD unsigned _WCNEAR _amblksiz = 32*1024; |
#elif defined(__WINDOWS__) |
_WCRTLINKD unsigned _WCNEAR _amblksiz = 8*1024; |
#elif INT_MAX < 65535 |
_WCRTLINKD unsigned _WCNEAR _amblksiz = 16; |
#else |
_WCRTLINKD unsigned _WCNEAR _amblksiz = 4*1024; |
#endif |
/programs/develop/open watcom/trunk/clib/heap/ambsptr.c |
---|
0,0 → 1,39 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
#include "variety.h" |
#include <stdlib.h> |
#include "rtdata.h" |
_WCRTLINK unsigned *__get_amblksiz_ptr( void ) { |
return &_amblksiz; |
} |
/programs/develop/open watcom/trunk/clib/heap/calloc.c |
---|
0,0 → 1,55 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <string.h> |
_WCRTLINK void *calloc( size_t n, size_t el_size ) |
{ |
void *mem; |
unsigned long chk_size; |
chk_size = (unsigned long) n * el_size; |
el_size = chk_size; |
#if defined(M_I86) |
if( el_size != chk_size ) { |
return( NULL ); |
} |
#endif |
mem = malloc( el_size ); |
if( mem == NULL ) { |
return( NULL ); |
} |
return( memset( mem, 0, el_size ) ); |
} |
/programs/develop/open watcom/trunk/clib/heap/freect.c |
---|
0,0 → 1,68 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
/* return the number of times that _nmalloc can be called to allocate |
and item "size" bytes from the near heap. */ |
_WCRTLINK unsigned int _freect( size_t size ) |
{ |
unsigned int count; |
size_t memsize; |
size_t size_of_chunk; |
frlptr pnext; |
mheapptr mhp; |
count = 0; |
size_of_chunk = (size + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE; |
if( size_of_chunk < size ) return( 0 ); |
if( size_of_chunk < FRL_SIZE ) { |
size_of_chunk = FRL_SIZE; |
} |
_AccessNHeap(); |
for( mhp = __nheapbeg; mhp != NULL; mhp = mhp->next ) { |
pnext = mhp->freehead.next; |
while( pnext != (frlptr) &mhp->freehead ) { |
memsize = pnext->len; |
count += memsize / size_of_chunk; |
pnext = pnext->next; |
} |
} |
_ReleaseNHeap(); |
return( count ); |
} |
/programs/develop/open watcom/trunk/clib/heap/grownear.c |
---|
0,0 → 1,560 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Heap growing routines - allocate near heap memory from OS. |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <malloc.h> |
#include "heapacc.h" |
#include "heap.h" |
#include <errno.h> |
#if defined(__DOS_EXT__) |
// #include "extender.h" |
// #include "tinyio.h" |
#endif |
#if defined(__CALL21__) |
// #include "tinyio.h" |
#endif |
#if defined(__WINDOWS_286__) || defined(__NT__) |
void* _stdcall UserAlloc(int size); |
// #include "windows.h" |
#endif |
#if defined(__OS2__) |
// #include <wos2.h> |
#endif |
#if defined(__WINDOWS_386__) |
// extern void * pascal DPMIAlloc(unsigned long); |
#endif |
static frlptr __LinkUpNewMHeap( mheapptr ); |
#if defined(__DOS_EXT__) |
extern int SegmentLimit(); |
#pragma aux SegmentLimit = \ |
"xor eax,eax" \ |
"mov ax,ds" \ |
"lsl eax,ax" \ |
"inc eax" \ |
value [eax] \ |
modify exact [eax]; |
static void __unlink( mheapptr miniheapptr ) |
{ |
mheapptr prev_link; |
mheapptr next_link; |
if( __nheapbeg == miniheapptr ) { |
__nheapbeg = miniheapptr->next; |
} |
if( miniheapptr == __MiniHeapRover ) { |
__MiniHeapRover = miniheapptr->prev; |
if( __MiniHeapRover == NULL ) { |
__MiniHeapRover = __nheapbeg; |
__LargestSizeB4MiniHeapRover = 0; |
} |
} |
if( miniheapptr == __MiniHeapFreeRover ) { |
__MiniHeapFreeRover = 0; |
} |
prev_link = miniheapptr->prev; |
next_link = miniheapptr->next; |
if( prev_link != NULL ) prev_link->next = next_link; |
if( next_link != NULL ) next_link->prev = prev_link; |
} |
void __FreeDPMIBlocks() |
{ |
mheapptr mhp; |
struct dpmi_hdr *dpmi; |
mhp = __nheapbeg; |
while( mhp != NULL ) { |
// see if the last free entry has the full size of |
// the DPMI block ( - overhead). If it is then we can give this |
// DPMI block back to the DPMI host. |
if( (mhp->freehead.prev)->len + sizeof(struct miniheapblkp) == |
mhp->len ) { |
mheapptr pnext; |
dpmi = ((struct dpmi_hdr *)mhp) - 1; |
pnext = mhp->next; |
__unlink( mhp ); |
mhp = pnext; |
if( dpmi->dos_seg_value == 0 ) { // if DPMI block |
TinyDPMIFree( dpmi->dpmi_handle ); |
} else { // else DOS block below 1MB |
TinyFreeBlock( dpmi->dos_seg_value ); |
} |
} else { |
mhp = mhp->next; |
} |
} |
} |
void *__ReAllocDPMIBlock( frlptr p1, unsigned req_size ) |
{ |
mheapptr mhp; |
struct dpmi_hdr *dpmi; |
struct dpmi_hdr *prev_dpmi; |
unsigned size; |
frlptr flp, flp2; |
if( !__heap_enabled ) return( 0 ); |
__FreeDPMIBlocks(); |
prev_dpmi = NULL; |
for( mhp = __nheapbeg; mhp; mhp = mhp->next ) { |
if( ((PTR)mhp + sizeof(struct miniheapblkp) == (PTR)p1) |
&& (mhp->numalloc == 1) ) { |
// The mini-heap contains only this memblk |
__unlink( mhp ); |
dpmi = ((struct dpmi_hdr *)mhp) - 1; |
if( dpmi->dos_seg_value != 0 ) return( NULL ); |
size = mhp->len + sizeof(struct dpmi_hdr) + TAG_SIZE; |
size += ( req_size - (p1->len-TAG_SIZE) ); |
size += 0x0fff; |
size &= ~0x0fff; |
prev_dpmi = dpmi; |
dpmi = TinyDPMIRealloc( dpmi, size ); |
if( dpmi == NULL ) { |
dpmi = prev_dpmi; |
return( NULL ); // indicate resize failed |
} |
dpmi->dos_seg_value = 0; |
mhp = (mheapptr)( dpmi + 1 ); |
mhp->len = size - sizeof(struct dpmi_hdr) - TAG_SIZE; |
flp = __LinkUpNewMHeap( mhp ); |
mhp->numalloc = 1; |
// round up to even number |
req_size = (req_size + 1) & ~1; |
size = flp->len - req_size; |
if( size >= FRL_SIZE ) { // Enough to spare a free block |
flp->len = req_size | 1;// adjust size and set allocated bit |
// Make up a free block at the end |
flp2 = (frlptr)((PTR)flp + req_size); |
flp2->len = size | 1; |
++mhp->numalloc; |
mhp->largest_blk = 0; |
_nfree( (PTR)flp2 + TAG_SIZE ); |
} else { |
flp->len |= 1; // set allocated bit |
} |
return( flp ); |
} |
} |
return( NULL ); |
} |
#endif |
static frlptr __LinkUpNewMHeap( mheapptr p1 ) // originally __AddNewHeap() |
{ |
mheapptr p2; |
mheapptr p2_prev; |
tag *last_tag; |
unsigned amount; |
/* insert into ordered heap list (14-jun-91 AFS) */ |
/* logic wasn't inserting heaps in proper ascending order */ |
/* (09-nov-93 Fred) */ |
p2_prev = NULL; |
for( p2 = __nheapbeg; p2 != NULL; p2 = p2->next ) { |
if( p1 < p2 ) break; |
p2_prev = p2; |
} |
/* ascending order should be: p2_prev < p1 < p2 */ |
/* except for special cases when p2_prev and/or p2 are NULL */ |
p1->prev = p2_prev; |
p1->next = p2; |
if( p2_prev != NULL ) { |
p2_prev->next = p1; |
} else { /* add p1 to beginning of heap */ |
__nheapbeg = p1; |
} |
if( p2 != NULL ) { |
/* insert before 'p2' (list is non-empty) */ |
p2->prev = p1; |
} |
amount = p1->len - sizeof( struct miniheapblkp ); |
/* Fill out the new miniheap descriptor */ |
p1->freehead.len = 0; |
p1->freehead.prev = &p1->freehead; |
p1->freehead.next = &p1->freehead; |
p1->rover = &p1->freehead; |
p1->b4rover = 0; |
p1->numalloc = 0; |
p1->numfree = 0; |
p1++; |
((frlptr)p1)->len = amount; |
/* fix up end of heap links */ |
last_tag = (tag *) ( (PTR)p1 + amount ); |
*last_tag = END_TAG; |
return( (frlptr) p1 ); |
} |
#if ! ( defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) \ |
) |
size_t __LastFree( void ) /* used by nheapgrow to know about adjustment */ |
{ |
frlptr p1; |
unsigned brk_value; |
if( __nheapbeg == NULL ) { /* no heap? can't have free blocks */ |
return( 0 ); |
} |
p1 = __nheapbeg->freehead.prev; /* point to last free block */ |
brk_value = (unsigned)((PTR)p1 + p1->len + TAG_SIZE ); |
#if defined(__DOS_EXT__) |
if( _IsPharLap() && !__X32VM) _curbrk = SegmentLimit(); /*19-feb-94*/ |
#endif |
if( brk_value == _curbrk ) { /* if last free block is at the end */ |
return( p1->len ); |
} |
return( 0 ); |
} |
#endif |
#if ! defined(__CALL21__) |
#if defined(__DOS_EXT__) |
static void *RationalAlloc( size_t size ) |
{ |
struct dpmi_hdr *dpmi; |
mheapptr mhp; |
tiny_ret_t save_DOS_block; |
tiny_ret_t DOS_block; |
__FreeDPMIBlocks(); |
/* size is a multiple of 4k */ |
dpmi = TinyDPMIAlloc( size ); |
if( dpmi != NULL ) { |
mhp = (mheapptr)( dpmi + 1 ); |
mhp->len = size - sizeof( struct dpmi_hdr ); |
dpmi->dos_seg_value = 0; // indicate DPMI block |
return( (void *)mhp ); |
} |
if( __minreal & 0xfff00000 ) { |
/* checks for users that want >1M real memory saved */ |
__minreal = 0xfffff; |
} |
if( size > 0x00010000 ) { |
/* cannot allocate more than 64k from DOS real memory */ |
return( NULL ); |
} |
save_DOS_block = TinyAllocBlock(( __minreal >> 4 ) | 1 ); |
if( TINY_OK( save_DOS_block ) ) { |
DOS_block = TinyAllocBlock( size >> 4 ); |
TinyFreeBlock( save_DOS_block ); |
if( TINY_OK( DOS_block ) ) { |
dpmi = (struct dpmi_hdr *) TinyDPMIBase( DOS_block ); |
dpmi->dos_seg_value = DOS_block; |
mhp = (mheapptr)( dpmi + 1 ); |
mhp->len = size - sizeof( struct dpmi_hdr ); |
return( (void *)mhp ); |
} |
} |
return( NULL ); |
} |
#endif |
#endif |
static int __AdjustAmount( unsigned *amount ) |
{ |
unsigned old_amount = *amount; |
unsigned amt; |
#if ! ( defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) \ |
) |
unsigned last_free_amt; |
#endif |
amt = old_amount; |
amt = ( amt + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE; |
if( amt < old_amount ) { |
return( 0 ); |
} |
#if ! ( defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) \ |
) |
#if defined(__DOS_EXT__) |
if( _IsRationalZeroBase() || _IsCodeBuilder() ) { |
// Allocating extra to identify the dpmi block |
amt += sizeof(struct dpmi_hdr); |
} else { |
#else |
{ |
#endif |
last_free_amt = __LastFree(); /* adjust for last free block */ |
if( last_free_amt >= amt ) { |
amt = 0; |
} else { |
amt -= last_free_amt; |
} |
} |
#endif |
/* amount is even here */ |
/* |
extra amounts (22-feb-91 AFS) |
(1) adding a new heap needs: |
frl free block req'd for _nmalloc request |
(frl is the MINIMUM because the block |
may be freed) |
tag end of miniheap descriptor |
struct miniheapblkp start of miniheap descriptor |
(2) extending heap needs: |
tag free block req'd for _nmalloc request |
*/ |
*amount = amt; |
amt += ( (TAG_SIZE) + sizeof(frl) + sizeof(struct miniheapblkp) ); |
if( amt < *amount ) return( 0 ); |
if( amt < _amblksiz ) { |
/* |
_amblksiz may not be even so round down to an even number |
nb. pathological case: where _amblksiz == 0xffff, we don't |
want the usual round up to even |
*/ |
amt = _amblksiz & ~1u; |
} |
#if defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) || \ |
defined(__CALL21__) || \ |
defined(__DOS_EXT__) |
/* make sure amount is a multiple of 4k */ |
*amount = amt; |
amt += 0x0fff; |
if( amt < *amount ) return( 0 ); |
amt &= ~0x0fff; |
#endif |
*amount = amt; |
return( *amount != 0 ); |
} |
#if defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) || \ |
defined(__CALL21__) || \ |
defined(__DOS_EXT__) |
static int __CreateNewNHeap( unsigned amount ) |
{ |
mheapptr p1; |
frlptr flp; |
unsigned brk_value; |
if( !__heap_enabled ) return( 0 ); |
if( _curbrk == ~1u ) return( 0 ); |
if( __AdjustAmount( &amount ) == 0 ) return( 0 ); |
#if defined(__WINDOWS_286__) |
brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount ); |
if( brk_value == 0 ) { |
return( 0 ); |
} |
#elif defined(__WINDOWS_386__) |
brk_value = (unsigned) DPMIAlloc( amount ); |
if( brk_value == 0 ) { |
return( 0 ); |
} |
#elif defined(__WARP__) |
{ |
PBYTE p; |
if( DosAllocMem( &p, amount, PAG_COMMIT|PAG_READ|PAG_WRITE ) ) { |
return( 0 ); |
} |
brk_value = (unsigned)p; |
} |
#elif defined(__NT__) |
// brk_value = (unsigned) VirtualAlloc( NULL, amount, MEM_COMMIT, |
// PAGE_EXECUTE_READWRITE ); |
brk_value = (unsigned) UserAlloc (amount ); |
//brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount ); |
if( brk_value == 0 ) { |
return( 0 ); |
} |
#elif defined(__CALL21__) |
{ |
tag _WCNEAR *tmp_tag; |
tmp_tag = (tag _WCNEAR *)TinyMemAlloc( amount ); |
if( tmp_tag == NULL ) { |
return( 0 ); |
} |
/* make sure it will not look like the end of a heap */ |
tmp_tag[0] = ! END_TAG; |
brk_value = (unsigned) &tmp_tag[2]; |
amount -= 2 * TAG_SIZE; // 11-jun-95, subtract extra tag |
} |
#elif defined(__DOS_EXT__) |
// if( _IsRationalZeroBase() || _IsCodeBuilder() ) { |
{ |
tag *tmp_tag; |
if( _IsRational() ) { |
tmp_tag = RationalAlloc( amount ); |
if( tmp_tag ) amount = *tmp_tag; |
} else { /* CodeBuilder */ |
tmp_tag = TinyCBAlloc( amount ); |
amount -= TAG_SIZE; |
} |
if( tmp_tag == NULL ) { |
return( 0 ); |
} |
brk_value = (unsigned) tmp_tag; |
} |
// Pharlap, RSI/non-zero can never call this function |
#endif |
if( amount - TAG_SIZE > amount ) { |
return( 0 ); |
} else { |
amount -= TAG_SIZE; |
} |
if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) { |
/* there isn't enough for a heap block (struct miniheapblkp) and |
one free block (frl) */ |
return( 0 ); |
} |
/* we've got a new heap block */ |
p1 = (mheapptr) brk_value; |
p1->len = amount; |
// Now link it up |
flp = __LinkUpNewMHeap( p1 ); |
amount = flp->len; |
/* build a block for _nfree() */ |
flp->len = amount | 1; |
++p1->numalloc; /* 28-dec-90 */ |
p1->largest_blk = 0; |
_nfree( (PTR)flp + TAG_SIZE ); |
return( 1 ); |
} |
#endif |
int __ExpandDGROUP( unsigned amount ) |
{ |
#if defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WARP__) || \ |
defined(__NT__) || \ |
defined(__CALL21__) |
// first try to free any available storage |
_nheapshrink(); |
return( __CreateNewNHeap( amount ) ); |
#else |
mheapptr p1; |
frlptr flp; |
unsigned brk_value; |
tag *last_tag; |
unsigned new_brk_value; |
void _WCNEAR *brk_ret; |
#if defined(__DOS_EXT__) |
if( ( _IsRationalZeroBase() || _IsCodeBuilder() ) ) { |
return( __CreateNewNHeap( amount ) ); // Won't slice either |
} |
// Rational non-zero based system should go through. |
#endif |
if( !__heap_enabled ) return( 0 ); |
if( _curbrk == ~1u ) return( 0 ); |
if( __AdjustAmount( &amount ) == 0 ) return( 0 ); |
#if defined(__DOS_EXT__) |
if( _IsPharLap() && !__X32VM ) { /* 19-feb-94 */ |
_curbrk = SegmentLimit(); |
} |
#endif |
new_brk_value = amount + _curbrk; |
if( new_brk_value < _curbrk ) { |
new_brk_value = ~1u; |
} |
brk_ret = __brk( new_brk_value ); |
if( brk_ret == (void _WCNEAR *) -1 ) { |
return( 0 ); |
} |
brk_value = (unsigned) brk_ret; |
if( brk_value > /*0xfff8*/ ~7u ) { |
return( 0 ); |
} |
if( new_brk_value <= brk_value ) { |
return( 0 ); |
} |
amount = new_brk_value - brk_value; |
if( amount - TAG_SIZE > amount ) { |
return( 0 ); |
} else { |
amount -= TAG_SIZE; |
} |
for( p1 = __nheapbeg; p1 != NULL; p1 = p1->next ) { |
if( p1->next == NULL ) break; |
if( (unsigned)p1 <= brk_value && |
((unsigned)p1)+p1->len+TAG_SIZE >= brk_value ) break; |
} |
if( (p1 != NULL) && |
((brk_value - TAG_SIZE) == (unsigned)( (PTR)p1 + p1->len) ) ) { |
/* we are extending the previous heap block (slicing) */ |
/* nb. account for the end-of-heap tag */ |
brk_value -= TAG_SIZE; |
amount += TAG_SIZE; |
flp = (frlptr) brk_value; |
/* adjust current entry in heap list */ |
p1->len += amount; |
/* fix up end of heap links */ |
last_tag = (tag *) ( (PTR)flp + amount ); |
last_tag[0] = END_TAG; |
} else { |
if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) { |
/* there isn't enough for a heap block (struct miniheapblkp) and |
one free block (frl) */ |
return( 0 ); |
} |
// Initializing the near heap if __nheapbeg == NULL, |
// otherwise, a new mini-heap is getting linked up |
p1 = (mheapptr) brk_value; |
p1->len = amount; |
flp = __LinkUpNewMHeap( p1 ); |
amount = flp->len; |
} |
/* build a block for _nfree() */ |
flp->len = amount | 1; |
++p1->numalloc; /* 28-dec-90 */ |
p1->largest_blk = ~0; /* set to largest value to be safe */ |
_nfree( (PTR)flp + TAG_SIZE ); |
return( 1 ); |
#endif |
} |
/programs/develop/open watcom/trunk/clib/heap/heap.h |
---|
0,0 → 1,207 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Heap library configuration for various platforms. |
* |
****************************************************************************/ |
#include "variety.h" |
#if defined(_M_IX86) |
#include <i86.h> |
#endif |
#if !defined(__DOS_EXT__) |
#if defined(__386__) && \ |
!defined(__WINDOWS_386__) && \ |
!defined(__WINDOWS__) && \ |
!defined(__OS2__) && \ |
!defined(__NT__) && \ |
!defined(__OSI__) && \ |
!defined(__UNIX__) |
#define __DOS_EXT__ |
#endif |
#endif |
typedef unsigned int tag; |
typedef struct freelistp frl; |
typedef struct freelistp _WCNEAR *frlptr; |
typedef struct freelist _WCFAR *farfrlptr; |
typedef unsigned char _WCNEAR *PTR; |
typedef unsigned char _WCFAR *FARPTR; |
typedef struct miniheapblkp _WCNEAR *mheapptr; |
/* |
** NOTE: the size of these data structures is critical to the alignemnt |
** of the pointers returned by malloc(). |
*/ |
struct freelist { |
tag len; /* length of block in free list */ |
unsigned int prev; /* offset of previous block in free list */ |
unsigned int next; /* offset of next block in free list */ |
}; |
struct heapblk { |
tag heaplen; /* size of heap (0 = 64K) */ |
unsigned int prevseg; /* segment selector for previous heap */ |
unsigned int nextseg; /* segment selector for next heap */ |
unsigned int rover; /* roving pointer into free list */ |
unsigned int b4rover; /* largest block before rover */ |
unsigned int largest_blk; /* largest block in the heap */ |
unsigned int numalloc; /* number of allocated blocks in heap */ |
unsigned int numfree; /* number of free blocks in the heap */ |
struct freelist freehead; /* listhead of free blocks in heap */ |
}; |
struct freelistp { |
tag len; |
frlptr prev; |
frlptr next; |
}; |
struct heapblkp { |
tag heaplen; |
unsigned int prevseg; |
unsigned int nextseg; |
frlptr rover; |
unsigned int b4rover; |
unsigned int largest_blk; |
unsigned int numalloc; |
unsigned int numfree; |
frl freehead; |
}; |
struct miniheapblkp { |
tag len; |
mheapptr prev; |
mheapptr next; |
frlptr rover; |
unsigned int b4rover; |
unsigned int largest_blk; |
unsigned int numalloc; |
unsigned int numfree; |
frl freehead; |
}; |
struct heapstart { |
struct heapblk h; |
struct freelist first; |
}; |
struct heapend { |
tag last_tag; |
struct freelist last; |
}; |
#ifdef __DOS_EXT__ |
struct dpmi_hdr { |
unsigned long dpmi_handle; |
tag dos_seg_value; // 0 => DPMI block, else DOS segment |
}; |
#endif |
extern unsigned _curbrk; |
extern mheapptr _WCNEAR __nheapbeg; |
#if defined(_M_IX86) |
extern __segment __fheap; |
extern __segment __bheap; |
extern __segment __fheapRover; |
#endif |
extern int __heap_enabled; |
extern unsigned int __LargestSizeB4Rover; |
extern struct miniheapblkp _WCNEAR *__MiniHeapRover; |
extern unsigned int __LargestSizeB4MiniHeapRover; |
extern struct miniheapblkp _WCNEAR *__MiniHeapFreeRover; |
extern size_t __LastFree( void ); |
extern int __NHeapWalk( struct _heapinfo *entry, mheapptr heapbeg ); |
extern int __ExpandDGROUP( unsigned int __amt ); |
#if defined(_M_IX86) |
extern unsigned __AllocSeg( unsigned int __amt ); |
extern unsigned __GrowSeg( __segment __seg, unsigned int __amt ); |
extern int __FreeSeg( __segment seg ); |
extern int __HeapWalk( struct _heapinfo *entry, __segment seg, unsigned all ); |
extern int __HeapMin( __segment seg, unsigned one_seg ); |
extern int __HeapSet( __segment seg, unsigned fill ); |
#endif |
#if defined(__DOS_EXT__) |
extern void __FreeDPMIBlocks( void ); |
extern void *__ReAllocDPMIBlock( frlptr p1, unsigned req_size ); |
extern void *__ExpandDPMIBlock( frlptr, unsigned ); |
#endif |
extern int __HeapManager_expand( __segment seg, unsigned offset, |
size_t req_size, size_t *growth_size ); |
extern void _WCFAR __HeapInit( void _WCNEAR *start, unsigned int amount ); |
_WCRTLINK extern void _WCNEAR *__brk( unsigned ); |
#if defined(_M_IX86) |
#define _DGroup() FP_SEG((&__nheapbeg)) |
#else |
#define _DGroup() 0 |
#endif |
// __IsCtsNHeap() is used to determine whether the operating system provides |
// a continuous near heap block. __ExpandDGroup should slice for more near |
// heap under those operating systems with __IsCtsNHeap() == 1. |
#if defined(__WARP__) || \ |
defined(__NT__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__WINDOWS_286__) |
#define __IsCtsNHeap() 0 |
#elif defined(__DOS_EXT__) |
#define __IsCtsNHeap() ((_IsRationalZeroBase() || _IsCodeBuilder()) ? 0 : 1) |
#else |
#define __IsCtsNHeap() 1 |
#endif |
extern unsigned __MemAllocator( unsigned __sz, unsigned __seg, unsigned __off ); |
extern void __MemFree( unsigned __ptr, unsigned __seg, unsigned __off ); |
#if defined(_M_IX86) |
#if defined(__386__) |
#pragma aux __MemAllocator "*" parm [eax] [edx] [ebx]; |
#pragma aux __MemFree "*" parm [eax] [edx] [ebx]; |
#else |
#pragma aux __MemAllocator "*" parm [ax] [dx] [bx]; |
#pragma aux __MemFree "*" parm [ax] [dx] [bx]; |
#endif |
#endif |
#define PARAS_IN_64K (0x1000) |
#define END_TAG (~0) |
#define TAG_SIZE (sizeof(tag)) |
#if defined(M_I86) |
#define ROUND_SIZE (TAG_SIZE-1) |
#else |
#define ROUND_SIZE (TAG_SIZE+TAG_SIZE-1) |
#endif |
#define FRL_SIZE ((sizeof(frl)+ROUND_SIZE)&~ROUND_SIZE) |
#define __HM_SUCCESS 0 |
#define __HM_FAIL 1 |
#define __HM_TRYGROW 2 |
/programs/develop/open watcom/trunk/clib/heap/heapacc.h |
---|
0,0 → 1,59 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
#ifndef _HEAPACC_H_INCLUDED |
#define _HEAPACC_H_INCLUDED |
/* macros for serialization of accesses to the heap */ |
#if defined(__SW_BM) |
#if defined(__386__) || defined(__AXP__) || defined(__PPC__) |
extern void (*_AccessFHeap)(); |
extern void (*_ReleaseFHeap)(); |
extern void (*_AccessNHeap)(); |
extern void (*_ReleaseNHeap)(); |
#else |
extern void __AccessFHeap(); |
extern void __ReleaseFHeap(); |
extern void __AccessNHeap(); |
extern void __ReleaseNHeap(); |
#define _AccessFHeap() __AccessFHeap() |
#define _ReleaseFHeap() __ReleaseFHeap() |
#define _AccessNHeap() __AccessNHeap() |
#define _ReleaseNHeap() __ReleaseNHeap() |
#endif |
#else |
#define _AccessFHeap() |
#define _ReleaseFHeap() |
#define _AccessNHeap() |
#define _ReleaseNHeap() |
#endif |
#endif |
/programs/develop/open watcom/trunk/clib/heap/heapen.c |
---|
0,0 → 1,53 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
int __heap_enabled = 1; |
_WCRTLINK int _heapenable( int new ) |
{ |
int old; |
_AccessNHeap(); |
old = __heap_enabled; |
__heap_enabled = new; |
_ReleaseNHeap(); |
return( old ); |
} |
/programs/develop/open watcom/trunk/clib/heap/heapgrow.c |
---|
0,0 → 1,126 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Routines to grow heap (allocate memory from OS). |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <malloc.h> |
#if defined(__QNX__) |
#elif defined(__LINUX__) |
#elif defined(__OS2__) |
#elif defined(_M_IX86) |
// #include "tinyio.h" |
#endif |
#include "heap.h" |
#include "heapacc.h" |
#if defined(M_I86) |
_WCRTLINK void _fheapgrow( void ) |
{ |
/* multiple heaps are used so growing the far heaps is not necessary */ |
} |
#endif |
#if defined(__SMALL_DATA__) |
_WCRTLINK void _heapgrow( void ) |
{ |
_nheapgrow(); |
} |
#else |
_WCRTLINK void _heapgrow( void ) |
{ |
_fheapgrow(); |
} |
#endif |
_WCRTLINK void _nheapgrow( void ) |
{ |
#if defined(__WINDOWS_286__) || defined(__386__) || defined(__AXP__) || defined(__PPC__) || defined(__MIPS__) |
_nfree( _nmalloc( 1 ) ); /* get something into the heap */ |
#else |
unsigned max_paras; |
unsigned curr_paras; |
unsigned diff_paras; |
unsigned expand; |
_AccessNHeap(); |
/* calculate # pages which always has extra slack space (ie. 0x10) */ |
curr_paras = (( _curbrk + 0x10 ) & ~0x0f ) >> 4; |
if( curr_paras == 0 ) { |
/* we're already at 64k */ |
_ReleaseNHeap(); |
return; |
} |
#if defined(__QNX__) |
if( qnx_segment_realloc( _DGroup(), 65536L ) == -1 ) { |
_ReleaseNHeap(); |
return; |
} |
max_paras = PARAS_IN_64K; |
#elif defined(__OS2__) |
if( DosReallocSeg( 0, _DGroup() ) ) { |
_ReleaseNHeap(); |
return; |
} |
max_paras = PARAS_IN_64K; |
#else |
if( _osmode != DOS_MODE ) { /* 23-apr-91 */ |
max_paras = PARAS_IN_64K; |
} else { |
max_paras = TinyMaxSet( _psp ); |
/* subtract off code size */ |
max_paras -= _DGroup() - _psp; |
if( max_paras > PARAS_IN_64K ) { |
max_paras = PARAS_IN_64K; |
} |
} |
#endif |
if( max_paras <= curr_paras ) { |
/* '<' -> something is wrong, '==' -> can't change size */ |
_ReleaseNHeap(); |
return; |
} |
diff_paras = max_paras - curr_paras; |
expand = (( diff_paras + 1 ) << 4 ) - ( _curbrk & 0x0f ); |
expand += __LastFree(); /* compensate for _expand's adjustment */ |
_ReleaseNHeap(); |
_nfree( _nmalloc( expand - ( sizeof( size_t ) + sizeof(frl) ) ) ); |
#endif |
} |
/programs/develop/open watcom/trunk/clib/heap/mem.c |
---|
0,0 → 1,343 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Heart of the heap manager. Do not break |
* unless you have a death wish. |
* |
****************************************************************************/ |
#include "variety.h" |
#include <limits.h> |
#include <malloc.h> |
#include "heap.h" |
#if defined(M_I86) |
extern unsigned setup_ds( unsigned ); |
#pragma aux setup_ds = \ |
"push ax" \ |
"mov ax,ds" \ |
"pop ds" \ |
parm [ax] value [ax]; |
#define setup_segment( _x ) _x = setup_ds( _x ); |
#else |
#define setup_segment( _x ) (void)(_x = _x); |
#endif |
// |
// input: |
// size - #bytes to allocate |
// segment - 16bit Intel data selector containing heap |
// offset - address of heap control block |
// if 16bit Intel -> offset within segment |
// else -> absolute pointer value |
// |
// output: |
// result - address of allocated storage or zero on failure |
// if 16bit Intel -> offset within segment |
// else -> absolute pointer value |
// |
unsigned __MemAllocator( unsigned size, unsigned segment, unsigned offset ) |
{ |
frlptr result; |
result = 0; // assume the worst |
setup_segment( segment ); // setup DS for 16bit Intel |
if( size != 0 ) { // quit if size is zero |
unsigned new_size; |
new_size = size + TAG_SIZE + ROUND_SIZE;// round up size |
if( new_size >= size ) { // quit if overflowed |
struct heapblkp _WCI86NEAR *heap; |
unsigned largest; |
heap = (struct heapblkp _WCI86NEAR *)offset; |
size = new_size & ~ROUND_SIZE; // make size even |
largest = heap->largest_blk; |
if( size < FRL_SIZE ) { |
size = FRL_SIZE; |
} |
if( size <= largest ) { // quit if size too big |
frlptr pcur; |
unsigned len; |
pcur = heap->rover; // start at rover |
largest = heap->b4rover; |
if( size <= largest ) { // check size with rover |
pcur = heap->freehead.next; // start at beginning |
largest = 0; // reset largest block size |
} |
for(;;) { // search free list |
len = pcur->len; |
if( size <= len ) { // found one |
break; |
} |
if( len > largest ) { // update largest block size |
largest = len; |
} |
pcur = pcur->next; // advance to next entry |
if( pcur == // if back at start |
(frlptr)&(heap->freehead)) { |
heap->largest_blk = largest; // update largest |
setup_segment( segment ); // 16bit Intel restore |
return( (unsigned)result ); // return 0 |
} |
} |
heap->b4rover = largest; // update rover size |
heap->numalloc++; // udpate allocation count |
len -= size; // compute leftover size |
if( len >= FRL_SIZE ) { // if leftover big enough |
// split into two chunks |
frlptr pprev; // before current |
frlptr pnext; // after current |
frlptr pnew; // start of new piece |
pnew = (frlptr)((PTR)pcur + size); |
heap->rover = pnew; // update rover |
pnew->len = len; // set new size |
pcur->len = size; // reset current size |
pprev = pcur->prev; // update next/prev links |
pnew->prev = pprev; |
pnext = pcur->next; |
pnew->next = pnext; |
pprev->next = pnew; |
pnext->prev = pnew; |
} else { // just use this chunk |
frlptr pprev; // before current |
frlptr pnext; // after current |
heap->numfree--; // 1 fewer entries in free list |
pprev = pcur->prev; |
heap->rover = pprev; // update rover |
pnext = pcur->next; // update next/prev links |
pprev->next = pnext; |
pnext->prev = pprev; |
} |
pcur->len |= 1; // mark as allocated |
// get pointer to user area |
result = (frlptr)((PTR)pcur + TAG_SIZE); |
} |
} |
} |
setup_segment( segment ); // 16bit Intel restore |
return( (unsigned)result ); |
} |
// |
// input: |
// pointer - address of block to free |
// if 16bit Intel -> offset within segment |
// else -> absolute pointer value |
// segment - 16bit Intel data selector containing heap |
// offset - address of heap control block |
// if 16bit Intel -> offset within segment |
// else -> absolute pointer value |
// |
// output: |
// none |
// |
void __MemFree( unsigned pointer, unsigned segment, unsigned offset ) |
{ |
setup_segment( segment ); // setup DS for 16bit Intel |
if( pointer != 0 ) { // quit if pointer is zero |
frlptr pfree; |
pfree = (frlptr)(pointer - TAG_SIZE); |
if( pfree->len & 1 ) { // quit if storage is free |
struct heapblkp _WCI86NEAR *heap; |
frlptr pnext; |
frlptr pprev; |
frlptr ptr; |
unsigned len; |
heap = (struct heapblkp _WCI86NEAR *)offset; |
do { // this allows break statement |
unsigned average; |
unsigned numfree; |
// look at next block to try and coalesce |
len = pfree->len & ~1; // get next block |
pnext = (frlptr)((PTR)pfree + len); |
if( (pnext->len & 1) == 0 ) { // if it is free |
len += pnext->len; // include the length |
pfree->len = len; // update pfree length |
if( pnext == heap->rover ) { // check for rover |
heap->rover = pfree; // update rover |
} |
pprev = pnext->prev; // fixup next/prev links |
pnext = pnext->next; |
pprev->next = pnext; |
pnext->prev = pprev; |
heap->numfree--; // reduce numfree |
break; // proceed to coalesce code |
} |
// following block is not free |
// we must now try to figure out where pfree |
// is in relation to the entries in the free list |
pfree->len = len; // remove allocated marker |
// check a few special places |
// see if pfree is: |
// - just before or just after the rover |
// - at the very beginning or very end of the heap |
pnext = heap->rover; // get rover |
if( pfree < pnext ) { // where is pfree? |
// pfree is before rover |
if( pfree > pnext->prev ) { // where is pfree? |
// pfree is next to rover |
break; // proceed to coalesce code |
} |
pnext = heap->freehead.next; // get start of free list |
if( pfree < pnext ) { // where is pfree? |
// pfree is at start of list |
break; // proceed to coalesce code |
} |
} else { // pfree is after rover |
pnext = pnext->next; // pnext is after rover |
if( pfree < pnext ) { // where is pfree? |
// pfree is just after rover |
break; // proceed to coalesce code |
} |
// get end of free list |
pnext = (frlptr)&(heap->freehead); |
pprev = pnext->prev; |
if( pfree > pprev ) { // where is pfree? |
// pfree is at end of list |
break; // proceed to coalesce code |
} |
} |
// Calculate the average number of allocated blocks we may |
// have to skip until we expect to find a free block. If |
// this number is less than the total number of free blocks, |
// chances are that we can find the correct position in the |
// free list by scanning ahead for a free block and linking |
// this free block before the found free block. We protect |
// ourself against the degenerate case where there is an |
// extremely long string of allocated blocks by limiting the |
// number of blocks we will search to twice the calculated |
// average. |
numfree = heap->numfree; |
average = heap->numalloc / (numfree+1); |
if( average < numfree ) { |
// There are lots of allocated blocks and lots of free |
// blocks. On average we should find a free block |
// quickly by following the allocated blocks, but the |
// worst case can be very bad. So, we try scanning the |
// allocated blocks and give up once we have looked at |
// twice the average. |
unsigned worst; |
worst = heap->numalloc - numfree; |
average *= 2; // give up after this many |
if( worst <= numfree ) { |
average = UINT_MAX; // we won't give up loop |
} |
// point at next allocated |
pnext = (frlptr)((PTR)pfree + pfree->len); |
for(;;) { |
len = pnext->len; |
if( len & 1 ) { // pnext is allocated |
if( len != END_TAG ) { // check for end TAG |
len &= ~1; // advance pnext |
pnext = (frlptr)((PTR)pnext + len); |
average--; |
if( !average ) { // give up search |
break; |
} |
} else { |
break; // stop at end tag |
} |
} else { |
// break twice! |
goto found_it; // we have the spot |
} |
} |
} |
// when all else fails, search the free list |
pnext = heap->rover; // begin at rover |
if( pfree < pnext ) { // is pfree before rover? |
// then begin at start |
pnext = heap->freehead.next; |
} |
for(;;) { |
if( pfree < pnext ) { // if pfree before pnext |
break; // we found it |
} |
pnext = pnext->next; // advance pnext |
if( pfree < pnext ) { // if pfree before pnext |
break; // we found it |
} |
pnext = pnext->next; // advance pnext |
if( pfree < pnext ) { // if pfree before pnext |
break; // we found it |
} |
pnext = pnext->next; // advance pnext |
} |
} while( 0 ); // only do once |
found_it: |
// if we are here, then we found the spot |
pprev = pnext->prev; // setup pprev |
// pprev, pfree, pnext are all setup |
len = pfree->len; |
// check pprev and pfree |
ptr = (frlptr)((PTR)pprev + pprev->len); |
if( ptr == pfree ) { // are they adjacent? |
// coalesce pprev and pfree |
len += pprev->len; // udpate len |
pprev->len = len; |
if( heap->rover == pfree ) { // check rover impact |
heap->rover = pprev; // update rover |
} |
pfree = pprev; // now work with coalesced blk |
} else { |
heap->numfree++; // one more free entry |
pfree->next = pnext; // update next/prev entries |
pfree->prev = pprev; |
pprev->next = pfree; |
pnext->prev = pfree; |
} |
heap->numalloc--; // one fewer allocated |
if( pfree < heap->rover ) { // check rover impact |
if( len > heap->b4rover ) { // is len bigger than b4rover |
heap->b4rover = len; // then update b4rover |
} |
} |
if( len > heap->largest_blk ) { // check largest block |
heap->largest_blk = len; |
} |
} |
} |
setup_segment( segment ); // 16bit Intel restore |
} |
/programs/develop/open watcom/trunk/clib/heap/memavl.c |
---|
0,0 → 1,61 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
/* Return the amount of memory available in the near heap. */ |
/* Best done at start of program and after _nheapgrow() has been called. */ |
_WCRTLINK size_t _memavl( void ) |
{ |
size_t length; |
frlptr pnext; |
mheapptr mhp; |
length = 0; |
_AccessNHeap(); |
for( mhp = __nheapbeg; mhp != NULL; mhp = mhp->next ) { |
pnext = mhp->freehead.next; |
while( pnext != (frlptr) &mhp->freehead ) { |
length += ( (pnext->len - TAG_SIZE) & ~ROUND_SIZE ); |
pnext = pnext->next; |
} |
} |
_ReleaseNHeap(); |
return( length ); |
} |
/programs/develop/open watcom/trunk/clib/heap/memmax.c |
---|
0,0 → 1,58 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
_WCRTLINK size_t _memmax( void ) /* return size of largest free piece from near heap */ |
{ |
size_t maxlen, size; |
frlptr pnext; |
mheapptr mhp; |
maxlen = 0; |
_AccessNHeap(); |
for( mhp = __nheapbeg; mhp != NULL; mhp = mhp->next ) { |
pnext = mhp->freehead.next; |
while( pnext != (frlptr) &mhp->freehead ) { |
size = ((pnext->len - TAG_SIZE) & ~ROUND_SIZE); |
if( size > maxlen ) maxlen = size; |
pnext = pnext->next; |
} |
} |
_ReleaseNHeap(); |
return( maxlen ); |
} |
/programs/develop/open watcom/trunk/clib/heap/ncalloc.c |
---|
0,0 → 1,56 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <malloc.h> |
#include <string.h> |
#include "heap.h" |
_WCRTLINK void _WCNEAR *_ncalloc( size_t n, size_t el_size ) |
{ |
void _WCI86NEAR *p; |
unsigned long chk_size; |
chk_size = (unsigned long) n * el_size; |
el_size = chk_size; |
#if defined(M_I86) |
if( el_size != chk_size ) { |
return( (void _WCNEAR *)NULL ); |
} |
#endif |
p = _nmalloc( el_size ); |
if( p != (void _WCNEAR *)NULL ) { |
memset( p, 0, el_size ); |
} |
return( p ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nexpand.c |
---|
0,0 → 1,205 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Near heap expansion routines. |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
#if defined(__DOS_EXT__) |
#include "extender.h" |
#endif |
#if defined(__SMALL_DATA__) |
_WCRTLINK void *_expand( void *stg, size_t amount ) |
{ |
return( _nexpand( stg, amount ) ); |
} |
#endif |
#if defined(__AXP__) || defined(__PPC__) |
#define _SEGMENT int |
#else |
#define _SEGMENT __segment |
#endif |
int __HeapManager_expand( _SEGMENT seg, |
unsigned offset, |
size_t req_size, |
size_t *growth_size ) |
{ |
#if defined(M_I86) |
typedef struct freelistp __based(seg) *fptr; |
typedef char __based(void) *cptr; |
struct miniheapblkp __based(seg) *hblk; |
#else |
typedef struct freelistp _WCNEAR *fptr; |
typedef char _WCNEAR *cptr; |
mheapptr hblk; |
#endif |
fptr p1; |
fptr p2; |
fptr pnext; |
fptr pprev; |
size_t new_size; |
size_t old_size; |
size_t free_size; |
/* round (new_size + tag) to multiple of pointer size */ |
new_size = (req_size + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE; |
if( new_size < req_size ) new_size = ~0; //go for max |
if( new_size < FRL_SIZE ) { |
new_size = FRL_SIZE; |
} |
p1 = (fptr) ((cptr)offset - TAG_SIZE); |
old_size = p1->len & ~1; |
if( new_size > old_size ) { |
/* enlarging the current allocation */ |
p2 = (fptr) ((cptr)p1 + old_size); |
*growth_size = new_size - old_size; |
for(;;) { |
free_size = p2->len; |
if( p2->len == END_TAG ) { |
return( __HM_TRYGROW ); |
} else if( free_size & 1 ) { /* next piece is allocated */ |
break; |
} else { |
pnext = p2->next; |
pprev = p2->prev; |
if( seg == _DGroup() ) { // near heap |
for( hblk = __nheapbeg; hblk->next; hblk = hblk->next ) { |
if( (fptr)hblk <= (fptr)offset && |
(fptr)((PTR)hblk+hblk->len) > (fptr)offset ) break; |
} |
} |
#if defined(M_I86) |
else { // Based heap |
hblk = 0; |
} |
#endif |
if( hblk->rover == p2 ) { /* 09-feb-91 */ |
hblk->rover = p2->prev; |
} |
if( free_size < *growth_size || |
free_size - *growth_size < FRL_SIZE ) { |
/* unlink small free block */ |
pprev->next = pnext; |
pnext->prev = pprev; |
p1->len += free_size; |
hblk->numfree--; |
if( free_size >= *growth_size ) { |
return( __HM_SUCCESS ); |
} |
*growth_size -= free_size; |
p2 = (fptr) ((cptr)p2 + free_size); |
} else { |
p2 = (fptr) ((cptr)p2 + *growth_size); |
p2->len = free_size - *growth_size; |
p2->prev = pprev; |
p2->next = pnext; |
pprev->next = p2; |
pnext->prev = p2; |
p1->len += *growth_size; |
return( __HM_SUCCESS ); |
} |
} |
} |
/* no suitable free blocks behind, have to move block */ |
return( __HM_FAIL ); |
} else { |
/* shrinking the current allocation */ |
if( old_size - new_size >= FRL_SIZE ) { |
/* block big enough to split */ |
p1->len = new_size | 1; |
p1 = (fptr) ((cptr)p1 + new_size); |
p1->len = (old_size - new_size) | 1; |
if( seg == _DGroup() ) { // near heap |
for( hblk = __nheapbeg; hblk->next; hblk = hblk->next ) { |
if( (fptr)hblk <= (fptr)offset && |
(fptr)((PTR)hblk+hblk->len) > (fptr)offset ) break; |
} |
} |
#if defined(M_I86) |
else // Based heap |
hblk = 0; |
#endif |
/* _bfree will decrement 'numalloc' 08-jul-91 */ |
hblk->numalloc++; |
#if defined(M_I86) |
_bfree( seg, (cptr)p1 + TAG_SIZE ); |
/* free the top portion */ |
#else |
_nfree( (cptr)p1 + TAG_SIZE ); |
#endif |
} |
} |
return( __HM_SUCCESS ); |
} |
_WCRTLINK void _WCNEAR *_nexpand( void _WCNEAR *stg, size_t req_size ) |
{ |
struct { |
unsigned expanded : 1; |
} flags; |
int retval; |
size_t growth_size; |
flags.expanded = 0; |
_AccessNHeap(); |
for( ;; ) { |
retval = __HeapManager_expand( _DGroup(), |
(unsigned) stg, |
req_size, |
&growth_size ); |
if( retval == __HM_SUCCESS ) { |
_ReleaseNHeap(); |
return( stg ); |
} |
if( retval == __HM_FAIL || !__IsCtsNHeap() ) break; |
if( retval == __HM_TRYGROW ) { |
if( flags.expanded ) break; |
if( __ExpandDGROUP( growth_size ) == 0 ) { |
break; |
} |
flags.expanded = 1; |
} |
} |
_ReleaseNHeap(); |
return( NULL ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nfree.c |
---|
0,0 → 1,123 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Implementation of near free() and _nfree(). |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
#if defined(__SMALL_DATA__) |
_WCRTLINK void free( void *stg ) |
{ |
_nfree( stg ); |
} |
#endif |
struct miniheapblkp _WCNEAR *__MiniHeapFreeRover; |
_WCRTLINK void _nfree( void _WCNEAR *stg ) |
{ |
mheapptr p1,p2; |
if( !stg ) |
return; |
_AccessNHeap(); |
do { |
// first try some likely locations |
p1 = __MiniHeapFreeRover; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
p2 = p1; |
p1 = p1->prev; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
} |
p1 = p2->next; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
} |
} |
p1 = __MiniHeapRover; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
p2 = p1; |
p1 = p1->prev; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
} |
p1 = p2->next; |
if( p1 ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
break; |
} |
} |
} |
// not found near rover, so search the list |
for( p1 = __nheapbeg; p1; p1 = p1->next ) { |
if( (PTR)p1 <= (PTR)stg && (PTR)p1+p1->len > (PTR)stg ) { |
// break twice! |
goto found_it; |
} |
} |
// this pointer is not in the heap |
_ReleaseNHeap(); |
return; |
} while( 0 ); |
found_it: |
// we found the miniheap, free the storage |
__MemFree( (unsigned)stg, _DGroup(), (unsigned) p1 ); |
__MiniHeapFreeRover = p1; |
if( p1 < __MiniHeapRover ) { |
if( p1->largest_blk > __LargestSizeB4MiniHeapRover ) { |
__LargestSizeB4MiniHeapRover = p1->largest_blk; |
} |
} |
_ReleaseNHeap(); |
} |
/programs/develop/open watcom/trunk/clib/heap/nheapchk.c |
---|
0,0 → 1,162 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Implementation of near _heapchk() and _nheapchk(). |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
frlptr __nheapchk_current; |
static int checkFreeList( size_t *free_size ) |
{ |
frlptr p; |
frlptr end; |
size_t new_size; |
size_t free_list_size = 0; |
mheapptr mhp; |
for( mhp = __nheapbeg; mhp != NULL; mhp = mhp ->next ) { |
/* check that the free list is a doubly linked ring */ |
__nheapchk_current = p = mhp->freehead.next; |
/* make sure we start off on the right track */ |
if( (p->prev == NULL) || |
(p->prev < &(mhp->freehead)) || |
(((PTR)p->prev) > (((PTR)mhp)+mhp->len)) ) { |
return( _HEAPBADNODE ); |
} |
if( p->prev->next != p ) { |
return( _HEAPBADNODE ); |
} |
end = p; |
do { |
/* loop invariant: p->prev->next == p */ |
/* are we still in a ring if we move to p->next? */ |
/* nb. this check is sufficient to ensure that we will |
never cycle */ |
if( (p->next == NULL) || |
(p->next < &(mhp->freehead)) || |
(((PTR)p->next) > (((PTR)mhp)+mhp->len)) ) { |
return( _HEAPBADNODE ); |
} |
if( p->next->prev != p ) { |
return( _HEAPBADNODE ); |
} |
/* is entry allocated? */ |
if( p->len & 1 ) { |
return( _HEAPBADNODE ); |
} |
new_size = free_list_size + p->len; |
if( new_size < free_list_size ) { |
/* this is a case where we do not know where memory |
is corrupted */ |
return( _HEAPBADNODE ); |
} |
free_list_size = new_size; |
__nheapchk_current = p = p->next; |
} while( p != end ); |
} |
*free_size = free_list_size; |
return( _HEAPOK ); |
} |
static int checkFree( frlptr p ) |
{ |
frlptr next; |
frlptr prev; |
frlptr next_next; |
frlptr prev_prev; |
__nheapchk_current = p; |
if( p->len & 1 ) { |
return( _HEAPBADNODE ); |
} |
next = p->next; |
prev = p->prev; |
if( next->prev != p || prev->next != p ) { |
return( _HEAPBADNODE ); |
} |
next_next = next->next; |
prev_prev = prev->prev; |
if( next_next->prev != next || prev_prev->next != prev ) { |
return( _HEAPBADNODE ); |
} |
if( next_next->prev != next || prev_prev->next != prev ) { |
return( _HEAPBADNODE ); |
} |
return( _HEAPOK ); |
} |
#if defined(__SMALL_DATA__) |
_WCRTLINK int _heapchk( void ) |
{ |
return( _nheapchk() ); |
} |
#endif |
_WCRTLINK int _nheapchk( void ) |
{ |
struct _heapinfo hi; |
int heap_status; |
size_t free_size; |
_AccessNHeap(); |
heap_status = checkFreeList( &free_size ); |
if( heap_status != _HEAPOK ) { |
_ReleaseNHeap(); |
return( heap_status ); |
} |
hi._pentry = NULL; |
for(;;) { |
heap_status = __NHeapWalk( &hi, __nheapbeg ); |
if( heap_status != _HEAPOK ) |
break; |
if( hi._useflag == _FREEENTRY ) { |
heap_status = checkFree( (frlptr) hi._pentry ); |
if( heap_status != _HEAPOK ) |
break; |
free_size -= hi._size; |
} |
} |
if( free_size != 0 ) { |
heap_status = _HEAPBADNODE; |
} else if( heap_status == _HEAPBADPTR ) { |
heap_status = _HEAPBADNODE; |
} else { |
if( heap_status == _HEAPEND ) { |
heap_status = _HEAPOK; |
} |
} |
_ReleaseNHeap(); |
return( heap_status ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nheapmin.c |
---|
0,0 → 1,256 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Implementation of near _heapmin() and _nheapmin(). |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
#if defined(__DOS_EXT__) |
// #include "extender.h" |
#endif |
#if defined(__WINDOWS_286__) || defined(__NT__) |
int _stdcall UserFree(void* p); |
// #include "windows.h" |
#endif |
#if defined(__OS2__) |
// #include <wos2.h> |
#endif |
#if defined(__WINDOWS_386__) |
// extern int __pascal DPMIFree(unsigned long); // windows extender function |
#endif |
#if defined(__CALL21__) |
// #include "tinyio.h" |
#endif |
#if defined(__SMALL_DATA__) |
_WCRTLINK int _heapshrink( void ) |
{ |
return( _nheapshrink() ); |
} |
_WCRTLINK int _heapmin( void ) |
{ |
return( _nheapshrink() ); |
} |
#endif |
_WCRTLINK int _nheapmin( void ) |
{ |
return( _nheapshrink() ); |
} |
#if defined(__WARP__) || \ |
defined(__WINDOWS_286__) || \ |
defined(__WINDOWS_386__) || \ |
defined(__NT__) || \ |
defined(__CALL21__) |
static int __ReturnMemToSystem( mheapptr mhp ) |
{ |
mheapptr pnext; |
pnext = mhp->next; |
#if defined(__WARP__) |
if( DosFreeMem( (PBYTE)mhp ) ) return( -1 ); |
#elif defined(__NT__) |
//if( LocalFree( (HLOCAL)mhp ) != NULL ) return( -1 ); |
// if (!VirtualFree(mhp, 0, MEM_RELEASE)) |
// return -1; |
if(!UserFree(mhp)) |
return -1; |
#elif defined(__WINDOWS_386__) |
if( DPMIFree( (unsigned long)mhp ) != 0 ) return( -1 ); |
#elif defined(__WINDOWS_286__) |
if( LocalFree( (HLOCAL)mhp ) != NULL ) return( -1 ); |
#elif defined(__CALL21__) |
// No way to free storage under OSI |
if( mhp ) return( -1 ); |
#endif |
if( __MiniHeapRover == mhp ) { // Update rovers |
if( pnext ) { |
__MiniHeapRover = pnext; |
} else { |
__MiniHeapRover = __nheapbeg; |
__LargestSizeB4MiniHeapRover = 0; |
} |
} |
if( __MiniHeapFreeRover == mhp ) { |
__MiniHeapFreeRover = 0; |
} |
return( 0 ); // success |
} |
static void __ReleaseMiniHeap( mheapptr mhp ) |
{ |
mheapptr pprev; |
mheapptr pnext; |
pprev = mhp->prev; |
pnext = mhp->next; |
if( __ReturnMemToSystem( mhp ) == 0 ) { |
if( pprev == NULL ) { |
__nheapbeg = pnext; |
} else { |
pprev->next = pnext; |
} |
if( pnext != NULL ) pnext->prev = pprev; |
} //else: do not unlink if the memory cannot be freed successfully |
} |
#endif |
_WCRTLINK int _nheapshrink( void ) |
{ |
mheapptr mhp; |
#if !defined(__WARP__) && \ |
!defined(__WINDOWS_286__) && \ |
!defined(__WINDOWS_386__) && \ |
!defined(__NT__) && \ |
!defined(__CALL21__) |
// Shrink by adjusting _curbrk |
frlptr last_free; |
frlptr end_tag; |
unsigned new_brk; |
_AccessNHeap(); |
#if defined(__DOS_EXT__) |
if( !_IsRationalZeroBase() && !_IsCodeBuilder() ) { |
#endif |
if( __nheapbeg == NULL ) { |
_ReleaseNHeap(); |
return( 0 ); // No near heap, can't shrink |
} |
/* Goto the end of miniheaplist (if there's more than 1 blk) */ |
for( mhp = __nheapbeg; mhp->next; mhp = mhp->next ); |
/* check that last free block is at end of heap */ |
last_free = mhp->freehead.prev; |
end_tag = (frlptr) ( (PTR)last_free + last_free->len ); |
if( end_tag->len != END_TAG ) { |
_ReleaseNHeap(); |
return( 0 ); |
} |
if( end_tag != (frlptr) ((PTR)mhp + mhp->len ) ) { |
_ReleaseNHeap(); |
return( 0 ); |
} |
#if defined(__DOS_EXT__) |
// only shrink if we can shave off at least 4k |
if( last_free->len < 0x1000 ) { |
_ReleaseNHeap(); |
return( 0 ); |
} |
#else |
if( last_free->len <= sizeof( frl ) ) { |
_ReleaseNHeap(); |
return( 0 ); |
} |
#endif |
/* make sure there hasn't been an external change in _curbrk */ |
if( sbrk( 0 ) != &(end_tag->prev) ) { |
_ReleaseNHeap(); |
return( 0 ); |
} |
/* calculate adjustment factor */ |
if( mhp->len-last_free->len > sizeof( struct miniheapblkp ) ) { |
// this miniheapblk is still being used |
#if defined(__DOS_EXT__) |
frlptr new_last_free; |
new_last_free = (frlptr)((((unsigned)last_free + 0xfff) & ~0xfff) - TAG_SIZE); |
if( new_last_free == last_free ) { |
#endif |
// remove entire entry |
mhp->len -= last_free->len; |
--mhp->numfree; |
// Relink the freelist entries, and update the rover |
mhp->freehead.prev = last_free->prev; |
last_free->prev->next = &mhp->freehead; |
if( mhp->rover == last_free ) mhp->rover = last_free->prev; |
#if defined(__DOS_EXT__) |
} else { |
// just shrink the last free entry |
mhp->len -= last_free->len; |
last_free->len = (PTR)new_last_free - (PTR)last_free; |
mhp->len += last_free->len; |
last_free = new_last_free; |
} |
#endif |
last_free->len = END_TAG; |
new_brk = (unsigned) ((PTR)last_free + TAG_SIZE ); |
} else { |
// we can remove this miniheapblk |
if( mhp->prev ) { // Not the first miniheapblk |
mhp->prev->next = NULL; |
new_brk = (unsigned)mhp;//->prev + (unsigned)mhp->prev->len; |
} else { // Is the first miniheapblk |
new_brk = (unsigned)__nheapbeg; |
__nheapbeg = NULL; |
} |
// Update rover info |
if( __MiniHeapRover == mhp ) { |
__MiniHeapRover = __nheapbeg; |
__LargestSizeB4MiniHeapRover = 0; |
} |
} |
if( __brk( new_brk ) == (void _WCNEAR *) -1 ) { |
_ReleaseNHeap(); |
return( -1 ); |
} |
_ReleaseNHeap(); |
return( 0 ); |
#if defined(__DOS_EXT__) |
} |
__FreeDPMIBlocks(); // For RSI/zero-base and Intel CB |
_ReleaseNHeap(); |
return( 0 ); |
#endif |
#else |
// Shrink by releasing mini-heaps |
{ |
mheapptr pnext; |
_AccessNHeap(); |
for( mhp = __nheapbeg; mhp; mhp = pnext ) { |
pnext = mhp->next; |
if( mhp->len - sizeof(struct miniheapblkp) == |
(mhp->freehead.prev)->len ) __ReleaseMiniHeap( mhp ); |
} |
_ReleaseNHeap(); |
return( 0 ); |
} |
#endif |
} |
/programs/develop/open watcom/trunk/clib/heap/nheapset.c |
---|
0,0 → 1,79 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Near heap set routines. |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include <string.h> |
#include "heap.h" |
#include "heapacc.h" |
#if defined(__SMALL_DATA__) |
_WCRTLINK int _heapset( unsigned int fill ) |
{ |
return( _nheapset( fill ) ); |
} |
#endif |
#if defined(_M_IX86) |
#pragma intrinsic(_fmemset) |
#endif |
_WCRTLINK int _nheapset( unsigned int fill ) |
{ |
mheapptr mhp; |
frlptr curr; |
int test_heap; |
test_heap = _heapchk(); |
if( test_heap != _HEAPOK ) { |
return( test_heap ); |
} |
fill |= fill << 8; |
_AccessNHeap(); |
for( mhp = __nheapbeg; mhp != NULL; mhp = mhp->next ) { |
curr = mhp->freehead.next; |
for( ;; ) { |
if( curr == (frlptr) &mhp->freehead ) break; |
#if defined(_M_IX86) |
_fmemset( (void _WCFAR *)(curr + 1), fill, curr->len - sizeof(frl) ); |
#else |
memset( (void *)(curr + 1), fill, curr->len - sizeof(frl) ); |
#endif |
curr = curr->next; |
} |
} |
_ReleaseNHeap(); |
return( _HEAPOK ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nheapwal.c |
---|
0,0 → 1,103 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include "heap.h" |
#include "heapacc.h" |
#if defined(__SMALL_DATA__) |
_WCRTLINK int _heapwalk( struct _heapinfo *entry ) |
{ |
return( _nheapwalk( entry ) ); |
} |
#endif |
int __NHeapWalk( struct _heapinfo *entry, mheapptr heapbeg ) |
{ |
frlptr p; |
frlptr q; |
if( heapbeg == NULL ) { |
return( _HEAPEMPTY ); |
} |
p = (frlptr)(entry->_pentry); |
if( p == NULL ) { |
p = (frlptr)(heapbeg + 1); |
} else { /* advance to next entry */ |
for( heapbeg = __nheapbeg;; heapbeg = heapbeg->next ) { |
if( heapbeg->next == NULL ) break; |
if( (PTR)heapbeg <= (PTR)p && |
(PTR)heapbeg+heapbeg->len > (PTR)p ) break; |
} |
q = (frlptr)((PTR)p + (p->len & ~1)); |
if( q <= p ) { |
return( _HEAPBADNODE ); |
} |
p = q; |
} |
for( ;; ) { |
if( p->len == END_TAG ) { |
if( heapbeg->next == NULL ) { |
entry->_useflag = _USEDENTRY; |
entry->_size = 0; |
entry->_pentry = NULL; |
return( _HEAPEND ); |
} else { // We advance to next miniheapblk |
heapbeg = heapbeg->next; |
p = (frlptr)(heapbeg + 1); |
} |
} else { |
break; |
} |
} |
entry->_pentry = p; |
entry->_useflag = _FREEENTRY; |
entry->_size = p->len & ~1; |
if( p->len & 1 ) { |
entry->_useflag = _USEDENTRY; |
} |
return( _HEAPOK ); |
} |
_WCRTLINK int _nheapwalk( struct _heapinfo *entry ) |
{ |
int heap_status; |
_AccessNHeap(); |
heap_status = __NHeapWalk( entry, __nheapbeg ); |
_ReleaseNHeap(); |
return( heap_status ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nmalloc.c |
---|
0,0 → 1,124 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Implementation of near malloc() and _nmalloc(). |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <malloc.h> |
#include "extfunc.h" |
#include "heapacc.h" |
#include "heap.h" |
#if defined(_M_IX86) |
#pragma aux (__outside_CLIB) __nmemneed; |
#endif |
mheapptr _WCNEAR __nheapbeg = NULL; |
struct miniheapblkp _WCNEAR *__MiniHeapRover = NULL; |
unsigned int __LargestSizeB4MiniHeapRover = 0; |
#if defined(__SMALL_DATA__) |
_WCRTLINK void *malloc( size_t amount ) |
{ |
return( _nmalloc( amount ) ); |
} |
#endif |
_WCRTLINK void _WCNEAR *_nmalloc( size_t amt ) |
{ |
unsigned largest; |
unsigned size; |
unsigned ptr; |
unsigned char expanded; |
mheapptr miniheap_ptr; |
if( (amt == 0) || (amt > -sizeof(struct heapblk)) ) { |
return( (void _WCNEAR *)NULL ); |
} |
// Try to determine which miniheap to begin allocating from. |
// first, round up the amount |
size = (amt + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE; |
if( size < FRL_SIZE ) { |
size = FRL_SIZE; |
} |
_AccessNHeap(); |
ptr = NULL; |
expanded = 0; |
for(;;) { |
if( size > __LargestSizeB4MiniHeapRover ) { |
miniheap_ptr = __MiniHeapRover; |
if( miniheap_ptr == NULL ) { |
__LargestSizeB4MiniHeapRover = 0; |
miniheap_ptr = __nheapbeg; |
} |
} else { |
__LargestSizeB4MiniHeapRover = 0; // force value to be updated |
miniheap_ptr = __nheapbeg; |
} |
for(;;) { |
if( miniheap_ptr == NULL ) { |
break; |
} |
__MiniHeapRover = miniheap_ptr; |
largest = miniheap_ptr->largest_blk; |
if( largest >= amt ) { |
ptr = __MemAllocator( amt, _DGroup(), (unsigned)miniheap_ptr ); |
if( ptr != NULL ) { |
goto lbl_release_heap; |
} |
} |
if( largest > __LargestSizeB4MiniHeapRover ) { |
__LargestSizeB4MiniHeapRover = largest; |
} |
miniheap_ptr = miniheap_ptr->next; |
} |
if( expanded || !__ExpandDGROUP( amt ) ) { |
if( !__nmemneed( amt ) ) { |
break; |
} |
expanded = 0; |
} else { |
expanded = 1; |
} |
} |
lbl_release_heap: |
_ReleaseNHeap(); |
return( (void _WCNEAR *)ptr ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nmemneed.c |
---|
0,0 → 1,42 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
int __nmemneed( size_t size ) |
{ |
size = size; |
return( 0 ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nmsize.c |
---|
0,0 → 1,55 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <malloc.h> |
#include "heap.h" |
#if defined(__SMALL_DATA__) |
_WCRTLINK size_t _msize( void *p ) |
{ |
tag *q; |
q = (tag *)(((unsigned char *)p) - TAG_SIZE); |
return( ( *q & ~1 ) - TAG_SIZE ); |
} |
#endif |
_WCRTLINK size_t _nmsize( void _WCNEAR *p ) |
{ |
tag _WCNEAR *q; |
q = (tag _WCNEAR *)(((unsigned char _WCNEAR *)p) - TAG_SIZE); |
return( ( *q & ~1 ) - TAG_SIZE ); |
} |
/programs/develop/open watcom/trunk/clib/heap/nrealloc.c |
---|
0,0 → 1,88 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: Near heap realloc routines. |
* |
****************************************************************************/ |
//#include "dll.h" // needs to be first |
#include "variety.h" |
#include <stddef.h> |
#include <malloc.h> |
#include <string.h> |
#include "heap.h" |
#if defined(__DOS_EXT__) |
#include "extender.h" |
#endif |
#if defined(__SMALL_DATA__) |
_WCRTLINK void *realloc( void *stg, size_t amount ) |
{ |
return( _nrealloc( stg, amount ) ); |
} |
#endif |
#pragma intrinsic(memcpy) |
_WCRTLINK void _WCNEAR *_nrealloc( void _WCI86NEAR *stg, size_t req_size ) |
{ |
void _WCNEAR *p; |
size_t old_size; |
if( stg == NULL ) { |
return( _nmalloc( req_size ) ); |
} |
if( req_size == 0 ) { |
_nfree( stg ); |
return( (void _WCNEAR *) NULL ); |
} |
old_size = _nmsize( stg ); |
p = _nexpand( stg, req_size ); /* try to expand it in place */ |
if( p == NULL ) { /* if couldn't be expanded in place */ |
#if defined(__DOS_EXT__) |
if( _IsRational() ) { |
frlptr flp, newflp; |
flp = (frlptr) ((PTR)stg - TAG_SIZE); |
newflp = __ReAllocDPMIBlock( flp, req_size + TAG_SIZE ); |
if( newflp ) { |
return( (void _WCNEAR *)((PTR)newflp + TAG_SIZE) ); |
} |
} |
#endif |
p = _nmalloc( req_size ); /* - allocate a new block */ |
if( p != NULL ) { /* - if we got one */ |
memcpy( p, stg, old_size ); /* copy it */ |
_nfree( stg ); /* and free old one */ |
} else { |
_nexpand( stg, old_size ); /* reset back to old size */ |
} |
} |
return( p ); |
} |
/programs/develop/open watcom/trunk/clib/heap/sbrkwnt.c |
---|
0,0 → 1,64 |
/**************************************************************************** |
* |
* Open Watcom Project |
* |
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. |
* |
* ======================================================================== |
* |
* This file contains Original Code and/or Modifications of Original |
* Code as defined in and that are subject to the Sybase Open Watcom |
* Public License version 1.0 (the 'License'). You may not use this file |
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO |
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is |
* provided with the Original Code and Modifications, and is also |
* available at www.sybase.com/developer/opensource. |
* |
* The Original Code and all software distributed under the License are |
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM |
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR |
* NON-INFRINGEMENT. Please see the License for the specific language |
* governing rights and limitations under the License. |
* |
* ======================================================================== |
* |
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE |
* DESCRIBE IT HERE! |
* |
****************************************************************************/ |
#include "variety.h" |
#include <stddef.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <dos.h> |
//#include <windows.h> |
void* _stdcall UserAlloc(int size); |
extern unsigned _curbrk; |
extern unsigned _STACKTOP; |
_WCRTLINK void _WCNEAR *sbrk( int increment ) |
{ |
if( increment > 0 ) |
{ |
void* p; |
increment = ( increment + 0x0fff ) & ~0x0fff; |
//p = LocalAlloc( LMEM_FIXED, increment ); |
//p = VirtualAlloc(NULL, increment, MEM_COMMIT,PAGE_EXECUTE_READWRITE); |
p = UserAlloc(increment); |
if( p != NULL ) return( p ); |
errno = ENOMEM; |
} |
else |
{ |
errno = EINVAL; |
} |
return( (void *) -1 ); |
} |