forked from KolibriOS/kolibrios
Clib string & memory functions
git-svn-id: svn://kolibrios.org@553 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
48
programs/develop/open watcom/trunk/clib/heap/amblksiz.c
Normal file
48
programs/develop/open watcom/trunk/clib/heap/amblksiz.c
Normal file
@@ -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
|
||||
|
39
programs/develop/open watcom/trunk/clib/heap/ambsptr.c
Normal file
39
programs/develop/open watcom/trunk/clib/heap/ambsptr.c
Normal file
@@ -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;
|
||||
}
|
55
programs/develop/open watcom/trunk/clib/heap/calloc.c
Normal file
55
programs/develop/open watcom/trunk/clib/heap/calloc.c
Normal file
@@ -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 ) );
|
||||
}
|
68
programs/develop/open watcom/trunk/clib/heap/freect.c
Normal file
68
programs/develop/open watcom/trunk/clib/heap/freect.c
Normal file
@@ -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 );
|
||||
}
|
560
programs/develop/open watcom/trunk/clib/heap/grownear.c
Normal file
560
programs/develop/open watcom/trunk/clib/heap/grownear.c
Normal file
@@ -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
|
||||
}
|
207
programs/develop/open watcom/trunk/clib/heap/heap.h
Normal file
207
programs/develop/open watcom/trunk/clib/heap/heap.h
Normal file
@@ -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
|
59
programs/develop/open watcom/trunk/clib/heap/heapacc.h
Normal file
59
programs/develop/open watcom/trunk/clib/heap/heapacc.h
Normal file
@@ -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
|
||||
|
53
programs/develop/open watcom/trunk/clib/heap/heapen.c
Normal file
53
programs/develop/open watcom/trunk/clib/heap/heapen.c
Normal file
@@ -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 );
|
||||
}
|
126
programs/develop/open watcom/trunk/clib/heap/heapgrow.c
Normal file
126
programs/develop/open watcom/trunk/clib/heap/heapgrow.c
Normal file
@@ -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
|
||||
}
|
343
programs/develop/open watcom/trunk/clib/heap/mem.c
Normal file
343
programs/develop/open watcom/trunk/clib/heap/mem.c
Normal file
@@ -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
|
||||
}
|
61
programs/develop/open watcom/trunk/clib/heap/memavl.c
Normal file
61
programs/develop/open watcom/trunk/clib/heap/memavl.c
Normal file
@@ -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 );
|
||||
}
|
58
programs/develop/open watcom/trunk/clib/heap/memmax.c
Normal file
58
programs/develop/open watcom/trunk/clib/heap/memmax.c
Normal file
@@ -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 );
|
||||
}
|
56
programs/develop/open watcom/trunk/clib/heap/ncalloc.c
Normal file
56
programs/develop/open watcom/trunk/clib/heap/ncalloc.c
Normal file
@@ -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 );
|
||||
}
|
205
programs/develop/open watcom/trunk/clib/heap/nexpand.c
Normal file
205
programs/develop/open watcom/trunk/clib/heap/nexpand.c
Normal file
@@ -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 );
|
||||
}
|
123
programs/develop/open watcom/trunk/clib/heap/nfree.c
Normal file
123
programs/develop/open watcom/trunk/clib/heap/nfree.c
Normal file
@@ -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();
|
||||
}
|
162
programs/develop/open watcom/trunk/clib/heap/nheapchk.c
Normal file
162
programs/develop/open watcom/trunk/clib/heap/nheapchk.c
Normal file
@@ -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 );
|
||||
}
|
256
programs/develop/open watcom/trunk/clib/heap/nheapmin.c
Normal file
256
programs/develop/open watcom/trunk/clib/heap/nheapmin.c
Normal file
@@ -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
|
||||
}
|
79
programs/develop/open watcom/trunk/clib/heap/nheapset.c
Normal file
79
programs/develop/open watcom/trunk/clib/heap/nheapset.c
Normal file
@@ -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 );
|
||||
}
|
103
programs/develop/open watcom/trunk/clib/heap/nheapwal.c
Normal file
103
programs/develop/open watcom/trunk/clib/heap/nheapwal.c
Normal file
@@ -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 );
|
||||
}
|
||||
|
124
programs/develop/open watcom/trunk/clib/heap/nmalloc.c
Normal file
124
programs/develop/open watcom/trunk/clib/heap/nmalloc.c
Normal file
@@ -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 );
|
||||
}
|
42
programs/develop/open watcom/trunk/clib/heap/nmemneed.c
Normal file
42
programs/develop/open watcom/trunk/clib/heap/nmemneed.c
Normal file
@@ -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 );
|
||||
}
|
||||
|
55
programs/develop/open watcom/trunk/clib/heap/nmsize.c
Normal file
55
programs/develop/open watcom/trunk/clib/heap/nmsize.c
Normal file
@@ -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 );
|
||||
}
|
88
programs/develop/open watcom/trunk/clib/heap/nrealloc.c
Normal file
88
programs/develop/open watcom/trunk/clib/heap/nrealloc.c
Normal file
@@ -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 );
|
||||
}
|
64
programs/develop/open watcom/trunk/clib/heap/sbrkwnt.c
Normal file
64
programs/develop/open watcom/trunk/clib/heap/sbrkwnt.c
Normal file
@@ -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 );
|
||||
}
|
Reference in New Issue
Block a user