Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 552 → Rev 553

/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 );
}