Subversion Repositories Kolibri OS

Rev

Rev 553 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 553 Rev 704
1
/****************************************************************************
1
/****************************************************************************
2
*
2
*
3
*                            Open Watcom Project
3
*                            Open Watcom Project
4
*
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
6
*
7
*  ========================================================================
7
*  ========================================================================
8
*
8
*
9
*    This file contains Original Code and/or Modifications of Original
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
15
*    available at www.sybase.com/developer/opensource.
16
*
16
*
17
*    The Original Code and all software distributed under the License are
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
23
*    governing rights and limitations under the License.
24
*
24
*
25
*  ========================================================================
25
*  ========================================================================
26
*
26
*
27
* Description:  Heap growing routines - allocate near heap memory from OS.
27
* Description:  Heap growing routines - allocate near heap memory from OS.
28
*
28
*
29
****************************************************************************/
29
****************************************************************************/
30
 
30
 
31
 
-
 
32
//#include "dll.h"        // needs to be first
31
 
33
#include "variety.h"
32
#include "variety.h"
34
#include 
33
#include 
35
#include 
34
#include 
36
#include 
35
#include 
37
#include "heapacc.h"
36
#include "heapacc.h"
38
#include "heap.h"
37
#include "heap.h"
39
#include 
38
#include 
40
#if defined(__DOS_EXT__)
39
#if defined(__DOS_EXT__)
41
// #include "extender.h"
40
// #include "extender.h"
42
// #include "tinyio.h"
41
// #include "tinyio.h"
43
#endif
42
#endif
44
#if defined(__CALL21__)
43
#if defined(__CALL21__)
45
// #include "tinyio.h"
44
// #include "tinyio.h"
46
#endif
45
#endif
47
#if defined(__WINDOWS_286__) || defined(__NT__)
46
#if defined(__WINDOWS_286__) || defined(__NT__)
48
void* _stdcall UserAlloc(int size);
-
 
49
 
-
 
50
// #include "windows.h"
47
 #include "kolibri.h"
51
#endif
48
#endif
52
#if defined(__OS2__)
49
#if defined(__OS2__)
53
// #include 
50
// #include 
54
#endif
51
#endif
55
#if defined(__WINDOWS_386__)
52
#if defined(__WINDOWS_386__)
56
// extern void * pascal DPMIAlloc(unsigned long);
53
// extern void * pascal DPMIAlloc(unsigned long);
57
#endif
54
#endif
58
 
55
 
59
static frlptr __LinkUpNewMHeap( mheapptr );
56
static frlptr __LinkUpNewMHeap( mheapptr );
60
 
57
 
61
#if defined(__DOS_EXT__)
58
#if defined(__DOS_EXT__)
62
 
59
 
63
extern  int                     SegmentLimit();
60
extern  int                     SegmentLimit();
64
#pragma aux SegmentLimit        = \
61
#pragma aux SegmentLimit        = \
65
        "xor    eax,eax"        \
62
        "xor    eax,eax"        \
66
        "mov    ax,ds"          \
63
        "mov    ax,ds"          \
67
        "lsl    eax,ax"         \
64
        "lsl    eax,ax"         \
68
        "inc    eax"            \
65
        "inc    eax"            \
69
        value                   [eax] \
66
        value                   [eax] \
70
        modify exact            [eax];
67
        modify exact            [eax];
71
 
68
 
72
static void __unlink( mheapptr miniheapptr )
69
static void __unlink( mheapptr miniheapptr )
73
{
70
{
74
    mheapptr            prev_link;
71
    mheapptr            prev_link;
75
    mheapptr            next_link;
72
    mheapptr            next_link;
76
 
73
 
77
    if( __nheapbeg == miniheapptr ) {
74
    if( __nheapbeg == miniheapptr ) {
78
        __nheapbeg = miniheapptr->next;
75
        __nheapbeg = miniheapptr->next;
79
    }
76
    }
80
    if( miniheapptr == __MiniHeapRover ) {
77
    if( miniheapptr == __MiniHeapRover ) {
81
        __MiniHeapRover = miniheapptr->prev;
78
        __MiniHeapRover = miniheapptr->prev;
82
        if( __MiniHeapRover == NULL ) {
79
        if( __MiniHeapRover == NULL ) {
83
            __MiniHeapRover = __nheapbeg;
80
            __MiniHeapRover = __nheapbeg;
84
            __LargestSizeB4MiniHeapRover = 0;
81
            __LargestSizeB4MiniHeapRover = 0;
85
        }
82
        }
86
    }
83
    }
87
    if( miniheapptr == __MiniHeapFreeRover ) {
84
    if( miniheapptr == __MiniHeapFreeRover ) {
88
        __MiniHeapFreeRover = 0;
85
        __MiniHeapFreeRover = 0;
89
    }
86
    }
90
    prev_link = miniheapptr->prev;
87
    prev_link = miniheapptr->prev;
91
    next_link = miniheapptr->next;
88
    next_link = miniheapptr->next;
92
    if( prev_link != NULL )  prev_link->next = next_link;
89
    if( prev_link != NULL )  prev_link->next = next_link;
93
    if( next_link != NULL )  next_link->prev = prev_link;
90
    if( next_link != NULL )  next_link->prev = prev_link;
94
}
91
}
95
 
92
 
96
void __FreeDPMIBlocks()
93
void __FreeDPMIBlocks()
97
{
94
{
98
    mheapptr            mhp;
95
    mheapptr            mhp;
99
    struct dpmi_hdr     *dpmi;
96
    struct dpmi_hdr     *dpmi;
100
 
97
 
101
    mhp = __nheapbeg;
98
    mhp = __nheapbeg;
102
    while( mhp != NULL ) {
99
    while( mhp != NULL ) {
103
        // see if the last free entry has the full size of
100
        // see if the last free entry has the full size of
104
        // the DPMI block ( - overhead).  If it is then we can give this
101
        // the DPMI block ( - overhead).  If it is then we can give this
105
        // DPMI block back to the DPMI host.
102
        // DPMI block back to the DPMI host.
106
        if( (mhp->freehead.prev)->len + sizeof(struct miniheapblkp) ==
103
        if( (mhp->freehead.prev)->len + sizeof(struct miniheapblkp) ==
107
            mhp->len ) {
104
            mhp->len ) {
108
            mheapptr    pnext;
105
            mheapptr    pnext;
109
 
106
 
110
            dpmi = ((struct dpmi_hdr *)mhp) - 1;
107
            dpmi = ((struct dpmi_hdr *)mhp) - 1;
111
            pnext = mhp->next;
108
            pnext = mhp->next;
112
            __unlink( mhp );
109
            __unlink( mhp );
113
            mhp = pnext;
110
            mhp = pnext;
114
            if( dpmi->dos_seg_value == 0 ) {    // if DPMI block
111
            if( dpmi->dos_seg_value == 0 ) {    // if DPMI block
115
                TinyDPMIFree( dpmi->dpmi_handle );
112
                TinyDPMIFree( dpmi->dpmi_handle );
116
            } else {                            // else DOS block below 1MB
113
            } else {                            // else DOS block below 1MB
117
                TinyFreeBlock( dpmi->dos_seg_value );
114
                TinyFreeBlock( dpmi->dos_seg_value );
118
            }
115
            }
119
        } else {
116
        } else {
120
            mhp = mhp->next;
117
            mhp = mhp->next;
121
        }
118
        }
122
    }
119
    }
123
}
120
}
124
 
121
 
125
void *__ReAllocDPMIBlock( frlptr p1, unsigned req_size )
122
void *__ReAllocDPMIBlock( frlptr p1, unsigned req_size )
126
{
123
{
127
    mheapptr            mhp;
124
    mheapptr            mhp;
128
    struct dpmi_hdr     *dpmi;
125
    struct dpmi_hdr     *dpmi;
129
    struct dpmi_hdr     *prev_dpmi;
126
    struct dpmi_hdr     *prev_dpmi;
130
    unsigned            size;
127
    unsigned            size;
131
    frlptr              flp, flp2;
128
    frlptr              flp, flp2;
132
 
129
 
133
    if( !__heap_enabled ) return( 0 );
130
    if( !__heap_enabled ) return( 0 );
134
    __FreeDPMIBlocks();
131
    __FreeDPMIBlocks();
135
    prev_dpmi = NULL;
132
    prev_dpmi = NULL;
136
    for( mhp = __nheapbeg; mhp; mhp = mhp->next ) {
133
    for( mhp = __nheapbeg; mhp; mhp = mhp->next ) {
137
        if( ((PTR)mhp + sizeof(struct miniheapblkp) == (PTR)p1)
134
        if( ((PTR)mhp + sizeof(struct miniheapblkp) == (PTR)p1)
138
          && (mhp->numalloc == 1) ) {
135
          && (mhp->numalloc == 1) ) {
139
            // The mini-heap contains only this memblk
136
            // The mini-heap contains only this memblk
140
            __unlink( mhp );
137
            __unlink( mhp );
141
            dpmi = ((struct dpmi_hdr *)mhp) - 1;
138
            dpmi = ((struct dpmi_hdr *)mhp) - 1;
142
            if( dpmi->dos_seg_value != 0 ) return( NULL );
139
            if( dpmi->dos_seg_value != 0 ) return( NULL );
143
            size = mhp->len + sizeof(struct dpmi_hdr) + TAG_SIZE;
140
            size = mhp->len + sizeof(struct dpmi_hdr) + TAG_SIZE;
144
            size += ( req_size - (p1->len-TAG_SIZE) );
141
            size += ( req_size - (p1->len-TAG_SIZE) );
145
            size += 0x0fff;
142
            size += 0x0fff;
146
            size &= ~0x0fff;
143
            size &= ~0x0fff;
147
            prev_dpmi = dpmi;
144
            prev_dpmi = dpmi;
148
            dpmi = TinyDPMIRealloc( dpmi, size );
145
            dpmi = TinyDPMIRealloc( dpmi, size );
149
            if( dpmi == NULL ) {
146
            if( dpmi == NULL ) {
150
                dpmi = prev_dpmi;
147
                dpmi = prev_dpmi;
151
                return( NULL );         // indicate resize failed
148
                return( NULL );         // indicate resize failed
152
            }
149
            }
153
            dpmi->dos_seg_value = 0;
150
            dpmi->dos_seg_value = 0;
154
            mhp = (mheapptr)( dpmi + 1 );
151
            mhp = (mheapptr)( dpmi + 1 );
155
            mhp->len = size - sizeof(struct dpmi_hdr) - TAG_SIZE;
152
            mhp->len = size - sizeof(struct dpmi_hdr) - TAG_SIZE;
156
            flp = __LinkUpNewMHeap( mhp );
153
            flp = __LinkUpNewMHeap( mhp );
157
            mhp->numalloc = 1;
154
            mhp->numalloc = 1;
158
 
155
 
159
            // round up to even number
156
            // round up to even number
160
            req_size = (req_size + 1) & ~1;
157
            req_size = (req_size + 1) & ~1;
161
            size = flp->len - req_size;
158
            size = flp->len - req_size;
162
            if( size >= FRL_SIZE ) {    // Enough to spare a free block
159
            if( size >= FRL_SIZE ) {    // Enough to spare a free block
163
                flp->len = req_size | 1;// adjust size and set allocated bit
160
                flp->len = req_size | 1;// adjust size and set allocated bit
164
                // Make up a free block at the end
161
                // Make up a free block at the end
165
                flp2 = (frlptr)((PTR)flp + req_size);
162
                flp2 = (frlptr)((PTR)flp + req_size);
166
                flp2->len = size | 1;
163
                flp2->len = size | 1;
167
                ++mhp->numalloc;
164
                ++mhp->numalloc;
168
                mhp->largest_blk = 0;
165
                mhp->largest_blk = 0;
169
                _nfree( (PTR)flp2 + TAG_SIZE );
166
                _nfree( (PTR)flp2 + TAG_SIZE );
170
            } else {
167
            } else {
171
                flp->len |= 1; // set allocated bit
168
                flp->len |= 1; // set allocated bit
172
            }
169
            }
173
            return( flp );
170
            return( flp );
174
        }
171
        }
175
    }
172
    }
176
    return( NULL );
173
    return( NULL );
177
}
174
}
178
#endif
175
#endif
179
 
176
 
180
static frlptr __LinkUpNewMHeap( mheapptr p1 ) // originally __AddNewHeap()
177
static frlptr __LinkUpNewMHeap( mheapptr p1 ) // originally __AddNewHeap()
181
{
178
{
182
    mheapptr    p2;
179
    mheapptr    p2;
183
    mheapptr    p2_prev;
180
    mheapptr    p2_prev;
184
    tag         *last_tag;
181
    tag         *last_tag;
185
    unsigned    amount;
182
    unsigned    amount;
186
 
183
 
187
    /* insert into ordered heap list (14-jun-91 AFS) */
184
    /* insert into ordered heap list (14-jun-91 AFS) */
188
    /* logic wasn't inserting heaps in proper ascending order */
185
    /* logic wasn't inserting heaps in proper ascending order */
189
    /* (09-nov-93 Fred) */
186
    /* (09-nov-93 Fred) */
190
    p2_prev = NULL;
187
    p2_prev = NULL;
191
    for( p2 = __nheapbeg; p2 != NULL; p2 = p2->next ) {
188
    for( p2 = __nheapbeg; p2 != NULL; p2 = p2->next ) {
192
        if( p1 < p2 ) break;
189
        if( p1 < p2 ) break;
193
        p2_prev = p2;
190
        p2_prev = p2;
194
    }
191
    }
195
    /* ascending order should be: p2_prev < p1 < p2  */
192
    /* ascending order should be: p2_prev < p1 < p2  */
196
    /* except for special cases when p2_prev and/or p2 are NULL */
193
    /* except for special cases when p2_prev and/or p2 are NULL */
197
    p1->prev = p2_prev;
194
    p1->prev = p2_prev;
198
    p1->next = p2;
195
    p1->next = p2;
199
    if( p2_prev != NULL ) {
196
    if( p2_prev != NULL ) {
200
        p2_prev->next = p1;
197
        p2_prev->next = p1;
201
    } else {            /* add p1 to beginning of heap */
198
    } else {            /* add p1 to beginning of heap */
202
        __nheapbeg = p1;
199
        __nheapbeg = p1;
203
    }
200
    }
204
    if( p2 != NULL ) {
201
    if( p2 != NULL ) {
205
        /* insert before 'p2' (list is non-empty) */
202
        /* insert before 'p2' (list is non-empty) */
206
        p2->prev = p1;
203
        p2->prev = p1;
207
    }
204
    }
208
    amount = p1->len - sizeof( struct miniheapblkp );
205
    amount = p1->len - sizeof( struct miniheapblkp );
209
    /* Fill out the new miniheap descriptor */
206
    /* Fill out the new miniheap descriptor */
210
    p1->freehead.len = 0;
207
    p1->freehead.len = 0;
211
    p1->freehead.prev = &p1->freehead;
208
    p1->freehead.prev = &p1->freehead;
212
    p1->freehead.next = &p1->freehead;
209
    p1->freehead.next = &p1->freehead;
213
    p1->rover = &p1->freehead;
210
    p1->rover = &p1->freehead;
214
    p1->b4rover = 0;
211
    p1->b4rover = 0;
215
    p1->numalloc = 0;
212
    p1->numalloc = 0;
216
    p1->numfree  = 0;
213
    p1->numfree  = 0;
217
    p1++;
214
    p1++;
218
    ((frlptr)p1)->len = amount;
215
    ((frlptr)p1)->len = amount;
219
    /* fix up end of heap links */
216
    /* fix up end of heap links */
220
    last_tag = (tag *) ( (PTR)p1 + amount );
217
    last_tag = (tag *) ( (PTR)p1 + amount );
221
    *last_tag = END_TAG;
218
    *last_tag = END_TAG;
222
    return( (frlptr) p1 );
219
    return( (frlptr) p1 );
223
}
220
}
224
 
221
 
225
#if ! ( defined(__WINDOWS_286__) || \
222
#if ! ( defined(__WINDOWS_286__) || \
226
        defined(__WINDOWS_386__) || \
223
        defined(__WINDOWS_386__) || \
227
        defined(__WARP__)        || \
224
        defined(__WARP__)        || \
228
        defined(__NT__)             \
225
        defined(__NT__)             \
229
    )
226
    )
230
size_t __LastFree( void )    /* used by nheapgrow to know about adjustment */
227
size_t __LastFree( void )    /* used by nheapgrow to know about adjustment */
231
{
228
{
232
    frlptr p1;
229
    frlptr p1;
233
    unsigned brk_value;
230
    unsigned brk_value;
234
 
231
 
235
    if( __nheapbeg == NULL ) {      /* no heap? can't have free blocks */
232
    if( __nheapbeg == NULL ) {      /* no heap? can't have free blocks */
236
        return( 0 );
233
        return( 0 );
237
    }
234
    }
238
    p1 = __nheapbeg->freehead.prev;        /* point to last free block */
235
    p1 = __nheapbeg->freehead.prev;        /* point to last free block */
239
    brk_value = (unsigned)((PTR)p1 + p1->len + TAG_SIZE );
236
    brk_value = (unsigned)((PTR)p1 + p1->len + TAG_SIZE );
240
    #if defined(__DOS_EXT__)
237
    #if defined(__DOS_EXT__)
241
        if( _IsPharLap() && !__X32VM) _curbrk = SegmentLimit(); /*19-feb-94*/
238
        if( _IsPharLap() && !__X32VM) _curbrk = SegmentLimit(); /*19-feb-94*/
242
    #endif
239
    #endif
243
    if( brk_value == _curbrk ) {   /* if last free block is at the end */
240
    if( brk_value == _curbrk ) {   /* if last free block is at the end */
244
        return( p1->len );
241
        return( p1->len );
245
    }
242
    }
246
    return( 0 );
243
    return( 0 );
247
}
244
}
248
#endif
245
#endif
249
 
246
 
250
#if ! defined(__CALL21__)
247
#if ! defined(__CALL21__)
251
#if defined(__DOS_EXT__)
248
#if defined(__DOS_EXT__)
252
static void *RationalAlloc( size_t size )
249
static void *RationalAlloc( size_t size )
253
{
250
{
254
    struct dpmi_hdr     *dpmi;
251
    struct dpmi_hdr     *dpmi;
255
    mheapptr            mhp;
252
    mheapptr            mhp;
256
    tiny_ret_t          save_DOS_block;
253
    tiny_ret_t          save_DOS_block;
257
    tiny_ret_t          DOS_block;
254
    tiny_ret_t          DOS_block;
258
 
255
 
259
    __FreeDPMIBlocks();
256
    __FreeDPMIBlocks();
260
    /* size is a multiple of 4k */
257
    /* size is a multiple of 4k */
261
    dpmi = TinyDPMIAlloc( size );
258
    dpmi = TinyDPMIAlloc( size );
262
    if( dpmi != NULL ) {
259
    if( dpmi != NULL ) {
263
        mhp = (mheapptr)( dpmi + 1 );
260
        mhp = (mheapptr)( dpmi + 1 );
264
        mhp->len = size - sizeof( struct dpmi_hdr );
261
        mhp->len = size - sizeof( struct dpmi_hdr );
265
        dpmi->dos_seg_value = 0;        // indicate DPMI block
262
        dpmi->dos_seg_value = 0;        // indicate DPMI block
266
        return( (void *)mhp );
263
        return( (void *)mhp );
267
    }
264
    }
268
    if( __minreal & 0xfff00000 ) {
265
    if( __minreal & 0xfff00000 ) {
269
        /* checks for users that want >1M real memory saved */
266
        /* checks for users that want >1M real memory saved */
270
        __minreal = 0xfffff;
267
        __minreal = 0xfffff;
271
    }
268
    }
272
    if( size > 0x00010000 ) {
269
    if( size > 0x00010000 ) {
273
        /* cannot allocate more than 64k from DOS real memory */
270
        /* cannot allocate more than 64k from DOS real memory */
274
        return( NULL );
271
        return( NULL );
275
    }
272
    }
276
    save_DOS_block = TinyAllocBlock(( __minreal >> 4 ) | 1 );
273
    save_DOS_block = TinyAllocBlock(( __minreal >> 4 ) | 1 );
277
    if( TINY_OK( save_DOS_block ) ) {
274
    if( TINY_OK( save_DOS_block ) ) {
278
        DOS_block = TinyAllocBlock( size >> 4 );
275
        DOS_block = TinyAllocBlock( size >> 4 );
279
        TinyFreeBlock( save_DOS_block );
276
        TinyFreeBlock( save_DOS_block );
280
        if( TINY_OK( DOS_block ) ) {
277
        if( TINY_OK( DOS_block ) ) {
281
            dpmi = (struct dpmi_hdr *) TinyDPMIBase( DOS_block );
278
            dpmi = (struct dpmi_hdr *) TinyDPMIBase( DOS_block );
282
            dpmi->dos_seg_value = DOS_block;
279
            dpmi->dos_seg_value = DOS_block;
283
            mhp = (mheapptr)( dpmi + 1 );
280
            mhp = (mheapptr)( dpmi + 1 );
284
            mhp->len = size - sizeof( struct dpmi_hdr );
281
            mhp->len = size - sizeof( struct dpmi_hdr );
285
            return( (void *)mhp );
282
            return( (void *)mhp );
286
        }
283
        }
287
    }
284
    }
288
    return( NULL );
285
    return( NULL );
289
}
286
}
290
#endif
287
#endif
291
#endif
288
#endif
292
 
289
 
293
static int __AdjustAmount( unsigned *amount )
290
static int __AdjustAmount( unsigned *amount )
294
{
291
{
295
    unsigned old_amount = *amount;
292
    unsigned old_amount = *amount;
296
    unsigned amt;
293
    unsigned amt;
297
    #if ! ( defined(__WINDOWS_286__) || \
294
    #if ! ( defined(__WINDOWS_286__) || \
298
            defined(__WINDOWS_386__) || \
295
            defined(__WINDOWS_386__) || \
299
            defined(__WARP__)        || \
296
            defined(__WARP__)        || \
300
            defined(__NT__)             \
297
            defined(__NT__)             \
301
        )
298
        )
302
        unsigned last_free_amt;
299
        unsigned last_free_amt;
303
    #endif
300
    #endif
304
 
301
 
305
    amt = old_amount;
302
    amt = old_amount;
306
    amt = ( amt + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE;
303
    amt = ( amt + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE;
307
    if( amt < old_amount ) {
304
    if( amt < old_amount ) {
308
        return( 0 );
305
        return( 0 );
309
    }
306
    }
310
    #if ! ( defined(__WINDOWS_286__) || \
307
    #if ! ( defined(__WINDOWS_286__) || \
311
            defined(__WINDOWS_386__) || \
308
            defined(__WINDOWS_386__) || \
312
            defined(__WARP__)        || \
309
            defined(__WARP__)        || \
313
            defined(__NT__)             \
310
            defined(__NT__)             \
314
        )
311
        )
315
        #if defined(__DOS_EXT__)
312
        #if defined(__DOS_EXT__)
316
            if( _IsRationalZeroBase() || _IsCodeBuilder() ) {
313
            if( _IsRationalZeroBase() || _IsCodeBuilder() ) {
317
                // Allocating extra to identify the dpmi block
314
                // Allocating extra to identify the dpmi block
318
                amt += sizeof(struct dpmi_hdr);
315
                amt += sizeof(struct dpmi_hdr);
319
            } else {
316
            } else {
320
        #else
317
        #else
321
            {
318
            {
322
        #endif
319
        #endif
323
                last_free_amt = __LastFree();   /* adjust for last free block */
320
                last_free_amt = __LastFree();   /* adjust for last free block */
324
                if( last_free_amt >= amt ) {
321
                if( last_free_amt >= amt ) {
325
                    amt = 0;
322
                    amt = 0;
326
                } else {
323
                } else {
327
                    amt -= last_free_amt;
324
                    amt -= last_free_amt;
328
                }
325
                }
329
            }
326
            }
330
    #endif
327
    #endif
331
    /* amount is even here */
328
    /* amount is even here */
332
    /*
329
    /*
333
      extra amounts        (22-feb-91 AFS)
330
      extra amounts        (22-feb-91 AFS)
334
 
331
 
335
       (1) adding a new heap needs:
332
       (1) adding a new heap needs:
336
           frl                    free block req'd for _nmalloc request
333
           frl                    free block req'd for _nmalloc request
337
                                  (frl is the MINIMUM because the block
334
                                  (frl is the MINIMUM because the block
338
                                  may be freed)
335
                                  may be freed)
339
           tag                    end of miniheap descriptor
336
           tag                    end of miniheap descriptor
340
           struct miniheapblkp    start of miniheap descriptor
337
           struct miniheapblkp    start of miniheap descriptor
341
       (2) extending heap needs:
338
       (2) extending heap needs:
342
           tag               free block req'd for _nmalloc request
339
           tag               free block req'd for _nmalloc request
343
    */
340
    */
344
    *amount = amt;
341
    *amount = amt;
345
    amt += ( (TAG_SIZE) + sizeof(frl) + sizeof(struct miniheapblkp) );
342
    amt += ( (TAG_SIZE) + sizeof(frl) + sizeof(struct miniheapblkp) );
346
    if( amt < *amount ) return( 0 );
343
    if( amt < *amount ) return( 0 );
347
    if( amt < _amblksiz ) {
344
    if( amt < _amblksiz ) {
348
        /*
345
        /*
349
          _amblksiz may not be even so round down to an even number
346
          _amblksiz may not be even so round down to an even number
350
          nb. pathological case: where _amblksiz == 0xffff, we don't
347
          nb. pathological case: where _amblksiz == 0xffff, we don't
351
                                 want the usual round up to even
348
                                 want the usual round up to even
352
        */
349
        */
353
        amt = _amblksiz & ~1u;
350
        amt = _amblksiz & ~1u;
354
    }
351
    }
355
    #if defined(__WINDOWS_386__) || \
352
    #if defined(__WINDOWS_386__) || \
356
        defined(__WARP__)        || \
353
        defined(__WARP__)        || \
357
        defined(__NT__)          || \
354
        defined(__NT__)          || \
358
        defined(__CALL21__)      || \
355
        defined(__CALL21__)      || \
359
        defined(__DOS_EXT__)
356
        defined(__DOS_EXT__)
360
        /* make sure amount is a multiple of 4k */
357
        /* make sure amount is a multiple of 4k */
361
        *amount = amt;
358
        *amount = amt;
362
        amt += 0x0fff;
359
        amt += 0x0fff;
363
        if( amt < *amount ) return( 0 );
360
        if( amt < *amount ) return( 0 );
364
        amt &= ~0x0fff;
361
        amt &= ~0x0fff;
365
    #endif
362
    #endif
366
    *amount = amt;
363
    *amount = amt;
367
    return( *amount != 0 );
364
    return( *amount != 0 );
368
}
365
}
369
 
366
 
370
#if defined(__WINDOWS_286__) || \
367
#if defined(__WINDOWS_286__) || \
371
    defined(__WINDOWS_386__) || \
368
    defined(__WINDOWS_386__) || \
372
    defined(__WARP__)        || \
369
    defined(__WARP__)        || \
373
    defined(__NT__)          || \
370
    defined(__NT__)          || \
374
    defined(__CALL21__)      || \
371
    defined(__CALL21__)      || \
375
    defined(__DOS_EXT__)
372
    defined(__DOS_EXT__)
376
static int __CreateNewNHeap( unsigned amount )
373
static int __CreateNewNHeap( unsigned amount )
377
{
374
{
378
    mheapptr        p1;
375
    mheapptr        p1;
379
    frlptr          flp;
376
    frlptr          flp;
380
    unsigned        brk_value;
377
    unsigned        brk_value;
381
 
378
 
382
    if( !__heap_enabled ) return( 0 );
379
    if( !__heap_enabled ) return( 0 );
383
    if( _curbrk == ~1u ) return( 0 );
380
    if( _curbrk == ~1u ) return( 0 );
384
    if( __AdjustAmount( &amount ) == 0 ) return( 0 );
381
    if( __AdjustAmount( &amount ) == 0 ) return( 0 );
385
#if defined(__WINDOWS_286__)
382
#if defined(__WINDOWS_286__)
386
    brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount );
383
    brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount );
387
    if( brk_value == 0 ) {
384
    if( brk_value == 0 ) {
388
        return( 0 );
385
        return( 0 );
389
    }
386
    }
390
#elif defined(__WINDOWS_386__)
387
#elif defined(__WINDOWS_386__)
391
    brk_value = (unsigned) DPMIAlloc( amount );
388
    brk_value = (unsigned) DPMIAlloc( amount );
392
    if( brk_value == 0 ) {
389
    if( brk_value == 0 ) {
393
        return( 0 );
390
        return( 0 );
394
    }
391
    }
395
#elif defined(__WARP__)
392
#elif defined(__WARP__)
396
    {
393
    {
397
        PBYTE           p;
394
        PBYTE           p;
398
 
395
 
399
        if( DosAllocMem( &p, amount, PAG_COMMIT|PAG_READ|PAG_WRITE ) ) {
396
        if( DosAllocMem( &p, amount, PAG_COMMIT|PAG_READ|PAG_WRITE ) ) {
400
            return( 0 );
397
            return( 0 );
401
        }
398
        }
402
        brk_value = (unsigned)p;
399
        brk_value = (unsigned)p;
403
    }
400
    }
404
#elif defined(__NT__)
401
#elif defined(__NT__)
405
//    brk_value = (unsigned) VirtualAlloc( NULL, amount, MEM_COMMIT,
402
//    brk_value = (unsigned) VirtualAlloc( NULL, amount, MEM_COMMIT,
406
//                                        PAGE_EXECUTE_READWRITE );
403
//                                        PAGE_EXECUTE_READWRITE );
407
      brk_value = (unsigned) UserAlloc (amount );
404
      brk_value = (unsigned) user_alloc(amount );
408
      
405
      
409
    //brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount );
406
    //brk_value = (unsigned) LocalAlloc( LMEM_FIXED, amount );
410
    if( brk_value == 0 ) {
407
    if( brk_value == 0 ) {
411
        return( 0 );
408
        return( 0 );
412
    }
409
    }
413
#elif defined(__CALL21__)
410
#elif defined(__CALL21__)
414
    {
411
    {
415
        tag _WCNEAR *tmp_tag;
412
        tag _WCNEAR *tmp_tag;
416
 
413
 
417
        tmp_tag = (tag _WCNEAR *)TinyMemAlloc( amount );
414
        tmp_tag = (tag _WCNEAR *)TinyMemAlloc( amount );
418
        if( tmp_tag == NULL ) {
415
        if( tmp_tag == NULL ) {
419
            return( 0 );
416
            return( 0 );
420
        }
417
        }
421
        /* make sure it will not look like the end of a heap */
418
        /* make sure it will not look like the end of a heap */
422
        tmp_tag[0] = ! END_TAG;
419
        tmp_tag[0] = ! END_TAG;
423
        brk_value = (unsigned) &tmp_tag[2];
420
        brk_value = (unsigned) &tmp_tag[2];
424
        amount -= 2 * TAG_SIZE; // 11-jun-95, subtract extra tag
421
        amount -= 2 * TAG_SIZE; // 11-jun-95, subtract extra tag
425
    }
422
    }
426
#elif defined(__DOS_EXT__)
423
#elif defined(__DOS_EXT__)
427
    // if( _IsRationalZeroBase() || _IsCodeBuilder() ) {
424
    // if( _IsRationalZeroBase() || _IsCodeBuilder() ) {
428
    {
425
    {
429
        tag         *tmp_tag;
426
        tag         *tmp_tag;
430
 
427
 
431
        if( _IsRational() ) {
428
        if( _IsRational() ) {
432
            tmp_tag = RationalAlloc( amount );
429
            tmp_tag = RationalAlloc( amount );
433
            if( tmp_tag ) amount = *tmp_tag;
430
            if( tmp_tag ) amount = *tmp_tag;
434
        } else {    /* CodeBuilder */
431
        } else {    /* CodeBuilder */
435
            tmp_tag = TinyCBAlloc( amount );
432
            tmp_tag = TinyCBAlloc( amount );
436
            amount -= TAG_SIZE;
433
            amount -= TAG_SIZE;
437
        }
434
        }
438
        if( tmp_tag == NULL ) {
435
        if( tmp_tag == NULL ) {
439
            return( 0 );
436
            return( 0 );
440
        }
437
        }
441
        brk_value = (unsigned) tmp_tag;
438
        brk_value = (unsigned) tmp_tag;
442
    }
439
    }
443
    // Pharlap, RSI/non-zero can never call this function
440
    // Pharlap, RSI/non-zero can never call this function
444
#endif
441
#endif
445
    if( amount - TAG_SIZE > amount ) {
442
    if( amount - TAG_SIZE > amount ) {
446
        return( 0 );
443
        return( 0 );
447
    } else {
444
    } else {
448
        amount -= TAG_SIZE;
445
        amount -= TAG_SIZE;
449
    }
446
    }
450
    if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) {
447
    if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) {
451
        /* there isn't enough for a heap block (struct miniheapblkp) and
448
        /* there isn't enough for a heap block (struct miniheapblkp) and
452
           one free block (frl) */
449
           one free block (frl) */
453
        return( 0 );
450
        return( 0 );
454
    }
451
    }
455
    /* we've got a new heap block */
452
    /* we've got a new heap block */
456
    p1 = (mheapptr) brk_value;
453
    p1 = (mheapptr) brk_value;
457
    p1->len = amount;
454
    p1->len = amount;
458
    // Now link it up
455
    // Now link it up
459
    flp = __LinkUpNewMHeap( p1 );
456
    flp = __LinkUpNewMHeap( p1 );
460
    amount = flp->len;
457
    amount = flp->len;
461
    /* build a block for _nfree() */
458
    /* build a block for _nfree() */
462
    flp->len = amount | 1;
459
    flp->len = amount | 1;
463
    ++p1->numalloc;                         /* 28-dec-90 */
460
    ++p1->numalloc;                         /* 28-dec-90 */
464
    p1->largest_blk = 0;
461
    p1->largest_blk = 0;
465
    _nfree( (PTR)flp + TAG_SIZE );
462
    _nfree( (PTR)flp + TAG_SIZE );
466
    return( 1 );
463
    return( 1 );
467
}
464
}
468
#endif
465
#endif
469
 
466
 
470
int __ExpandDGROUP( unsigned amount )
467
int __ExpandDGROUP( unsigned amount )
471
{
468
{
472
    #if defined(__WINDOWS_286__) || \
469
    #if defined(__WINDOWS_286__) || \
473
        defined(__WINDOWS_386__) || \
470
        defined(__WINDOWS_386__) || \
474
        defined(__WARP__)        || \
471
        defined(__WARP__)        || \
475
        defined(__NT__)          || \
472
        defined(__NT__)          || \
476
        defined(__CALL21__)
473
        defined(__CALL21__)
477
        // first try to free any available storage
474
        // first try to free any available storage
478
        _nheapshrink();
475
        _nheapshrink();
479
        return( __CreateNewNHeap( amount ) );
476
        return( __CreateNewNHeap( amount ) );
480
    #else
477
    #else
481
        mheapptr        p1;
478
        mheapptr        p1;
482
        frlptr          flp;
479
        frlptr          flp;
483
        unsigned brk_value;
480
        unsigned brk_value;
484
        tag     *last_tag;
481
        tag     *last_tag;
485
        unsigned new_brk_value;
482
        unsigned new_brk_value;
486
        void _WCNEAR *brk_ret;
483
        void _WCNEAR *brk_ret;
487
 
484
 
488
        #if defined(__DOS_EXT__)
485
        #if defined(__DOS_EXT__)
489
            if( ( _IsRationalZeroBase() || _IsCodeBuilder() ) ) {
486
            if( ( _IsRationalZeroBase() || _IsCodeBuilder() ) ) {
490
                return( __CreateNewNHeap( amount ) );   // Won't slice either
487
                return( __CreateNewNHeap( amount ) );   // Won't slice either
491
            }
488
            }
492
            // Rational non-zero based system should go through.
489
            // Rational non-zero based system should go through.
493
        #endif
490
        #endif
494
        if( !__heap_enabled ) return( 0 );
491
        if( !__heap_enabled ) return( 0 );
495
        if( _curbrk == ~1u ) return( 0 );
492
        if( _curbrk == ~1u ) return( 0 );
496
        if( __AdjustAmount( &amount ) == 0 ) return( 0 );
493
        if( __AdjustAmount( &amount ) == 0 ) return( 0 );
497
        #if defined(__DOS_EXT__)
494
        #if defined(__DOS_EXT__)
498
            if( _IsPharLap() && !__X32VM ) {        /* 19-feb-94 */
495
            if( _IsPharLap() && !__X32VM ) {        /* 19-feb-94 */
499
                _curbrk = SegmentLimit();
496
                _curbrk = SegmentLimit();
500
            }
497
            }
501
        #endif
498
        #endif
502
        new_brk_value = amount + _curbrk;
499
        new_brk_value = amount + _curbrk;
503
        if( new_brk_value < _curbrk ) {
500
        if( new_brk_value < _curbrk ) {
504
            new_brk_value = ~1u;
501
            new_brk_value = ~1u;
505
        }
502
        }
506
        brk_ret = __brk( new_brk_value );
503
        brk_ret = __brk( new_brk_value );
507
        if( brk_ret == (void _WCNEAR *) -1 ) {
504
        if( brk_ret == (void _WCNEAR *) -1 ) {
508
            return( 0 );
505
            return( 0 );
509
        }
506
        }
510
        brk_value = (unsigned) brk_ret;
507
        brk_value = (unsigned) brk_ret;
511
        if( brk_value >  /*0xfff8*/ ~7u ) {
508
        if( brk_value >  /*0xfff8*/ ~7u ) {
512
            return( 0 );
509
            return( 0 );
513
        }
510
        }
514
        if( new_brk_value <= brk_value ) {
511
        if( new_brk_value <= brk_value ) {
515
            return( 0 );
512
            return( 0 );
516
        }
513
        }
517
        amount = new_brk_value - brk_value;
514
        amount = new_brk_value - brk_value;
518
        if( amount - TAG_SIZE > amount ) {
515
        if( amount - TAG_SIZE > amount ) {
519
            return( 0 );
516
            return( 0 );
520
        } else {
517
        } else {
521
            amount -= TAG_SIZE;
518
            amount -= TAG_SIZE;
522
        }
519
        }
523
        for( p1 = __nheapbeg; p1 != NULL; p1 = p1->next ) {
520
        for( p1 = __nheapbeg; p1 != NULL; p1 = p1->next ) {
524
            if( p1->next == NULL ) break;
521
            if( p1->next == NULL ) break;
525
            if( (unsigned)p1 <= brk_value &&
522
            if( (unsigned)p1 <= brk_value &&
526
                ((unsigned)p1)+p1->len+TAG_SIZE >= brk_value ) break;
523
                ((unsigned)p1)+p1->len+TAG_SIZE >= brk_value ) break;
527
        }
524
        }
528
        if( (p1 != NULL) &&
525
        if( (p1 != NULL) &&
529
        ((brk_value - TAG_SIZE) == (unsigned)( (PTR)p1 + p1->len) ) ) {
526
        ((brk_value - TAG_SIZE) == (unsigned)( (PTR)p1 + p1->len) ) ) {
530
                /* we are extending the previous heap block (slicing) */
527
                /* we are extending the previous heap block (slicing) */
531
                /* nb. account for the end-of-heap tag */
528
                /* nb. account for the end-of-heap tag */
532
                brk_value -= TAG_SIZE;
529
                brk_value -= TAG_SIZE;
533
                amount += TAG_SIZE;
530
                amount += TAG_SIZE;
534
                flp = (frlptr) brk_value;
531
                flp = (frlptr) brk_value;
535
                /* adjust current entry in heap list */
532
                /* adjust current entry in heap list */
536
                p1->len += amount;
533
                p1->len += amount;
537
                /* fix up end of heap links */
534
                /* fix up end of heap links */
538
                last_tag = (tag *) ( (PTR)flp + amount );
535
                last_tag = (tag *) ( (PTR)flp + amount );
539
                last_tag[0] = END_TAG;
536
                last_tag[0] = END_TAG;
540
        } else {
537
        } else {
541
            if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) {
538
            if( amount < sizeof( struct miniheapblkp ) + sizeof( frl ) ) {
542
            /*  there isn't enough for a heap block (struct miniheapblkp) and
539
            /*  there isn't enough for a heap block (struct miniheapblkp) and
543
                one free block (frl) */
540
                one free block (frl) */
544
                return( 0 );
541
                return( 0 );
545
            }
542
            }
546
            // Initializing the near heap if __nheapbeg == NULL,
543
            // Initializing the near heap if __nheapbeg == NULL,
547
            // otherwise, a new mini-heap is getting linked up
544
            // otherwise, a new mini-heap is getting linked up
548
            p1 = (mheapptr) brk_value;
545
            p1 = (mheapptr) brk_value;
549
            p1->len = amount;
546
            p1->len = amount;
550
            flp = __LinkUpNewMHeap( p1 );
547
            flp = __LinkUpNewMHeap( p1 );
551
            amount = flp->len;
548
            amount = flp->len;
552
        }
549
        }
553
        /* build a block for _nfree() */
550
        /* build a block for _nfree() */
554
        flp->len = amount | 1;
551
        flp->len = amount | 1;
555
        ++p1->numalloc;                         /* 28-dec-90 */
552
        ++p1->numalloc;                         /* 28-dec-90 */
556
        p1->largest_blk = ~0;    /* set to largest value to be safe */
553
        p1->largest_blk = ~0;    /* set to largest value to be safe */
557
        _nfree( (PTR)flp + TAG_SIZE );
554
        _nfree( (PTR)flp + TAG_SIZE );
558
        return( 1 );
555
        return( 1 );
559
    #endif
556
    #endif
560
}
557
}