1 static char RCSId
[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
7 #include "prototypes.h"
12 /* #define DEBUG_HEAP */
14 LHEAP
*LocalHeaps
= NULL
;
16 /**********************************************************************
20 HEAP_Init(MDESC
**free_list
, void *start
, int length
)
22 if (length
< 2 * sizeof(MDESC
))
25 *free_list
= (MDESC
*) start
;
26 (*free_list
)->prev
= NULL
;
27 (*free_list
)->next
= NULL
;
28 (*free_list
)->length
= length
- sizeof(MDESC
);
31 /**********************************************************************
35 HEAP_Alloc(MDESC
**free_list
, int flags
, int bytes
)
40 printf("HeapAlloc: free_list %08x, flags %x, bytes %d\n",
41 free_list
, flags
, bytes
);
45 * Find free block big enough.
47 for (m
= *free_list
; m
!= NULL
; m
= m
->next
)
49 if (m
->length
>= bytes
&& m
->length
< bytes
+ 4 * sizeof(MDESC
))
53 else if (m
->length
> bytes
)
55 m_new
= m
+ (bytes
/ sizeof(MDESC
)) + 2;
59 m
->prev
->next
= m_new
;
62 m
->next
->prev
= m_new
;
64 m_new
->next
= m
->next
;
65 m_new
->prev
= m
->prev
;
66 m_new
->length
= m
->length
- ((int) m_new
- (int) m
);
67 m
->length
-= (m_new
->length
+ sizeof(MDESC
));
73 if (flags
& GLOBAL_FLAGS_ZEROINIT
)
74 memset(m
+ 1, 0, bytes
);
76 printf("HeapAlloc: returning %08x\n", (m
+ 1));
78 return (void *) (m
+ 1);
87 m
->prev
->next
= m
->next
;
90 m
->next
->prev
= m
->prev
;
96 if (flags
& GLOBAL_FLAGS_ZEROINIT
)
97 memset(m
+ 1, 0, bytes
);
99 printf("HeapAlloc: returning %08x\n", (m
+ 1));
101 return (void *) (m
+ 1);
105 printf("HeapAlloc: returning %08x\n", 0);
110 /**********************************************************************
114 HEAP_ReAlloc(MDESC
**free_list
, void *old_block
,
115 int new_size
, unsigned int flags
)
121 * Check validity of block
123 m
= (MDESC
*) old_block
- 1;
124 if (m
->prev
!= m
|| m
->next
!= m
||
125 ((int) m
& 0xffff0000) != ((int) *free_list
& 0xffff0000))
128 printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
135 * Check for grow block
137 if (new_size
> m
->length
)
139 m_free
= m
+ 1 + m
->length
/ sizeof(MDESC
);
140 if (m_free
->next
== m_free
||
141 m_free
->prev
== m_free
||
142 m_free
->length
+ sizeof(MDESC
) < new_size
)
144 void *new_p
= HEAP_Alloc(free_list
, flags
, new_size
);
148 memcpy(new_p
, old_block
, m
->length
);
149 HEAP_Free(free_list
, old_block
);
153 if (m_free
->prev
== NULL
)
154 *free_list
= m_free
->next
;
156 m_free
->prev
->next
= m_free
->next
;
158 if (m_free
->next
!= NULL
)
159 m_free
->next
->prev
= m_free
->prev
;
161 m
->length
+= sizeof(MDESC
) + m_free
->length
;
162 if (flags
& GLOBAL_FLAGS_ZEROINIT
)
163 memset(m_free
, '\0', sizeof(MDESC
) + m_free
->length
);
167 * Check for shrink block.
169 if (new_size
< m
->length
- 4 * sizeof(MDESC
))
171 m_free
= m
+ new_size
/ sizeof(MDESC
) + 2;
172 m_free
->next
= m_free
;
173 m_free
->prev
= m_free
;
174 m_free
->length
= m
->length
- (int) m_free
- (int) m
;
175 m
->length
= (int) m_free
- (int) (m
+ 1);
176 HEAP_Free(free_list
, m_free
+ 1);
183 /**********************************************************************
187 HEAP_Free(MDESC
**free_list
, void *block
)
196 m_free
= (MDESC
*) block
- 1;
197 if (m_free
->prev
!= m_free
|| m_free
->next
!= m_free
||
198 ((int) m_free
& 0xffff0000) != ((int) *free_list
& 0xffff0000))
201 printf("Attempt to free bad pointer,"
202 "m_free = %08x, *free_list = %08x\n",
209 * Find location in free list.
212 for (m
= *free_list
; m
!= NULL
&& m
< m_free
; m
= m
->next
)
215 if (m_prev
!= NULL
&& (int) m_prev
+ m_prev
->length
> (int) m_free
)
218 printf("Attempt to free bad pointer,"
219 "m_free = %08x, m_prev = %08x (length %x)\n",
220 m_free
, m_prev
, m_prev
->length
);
225 if ((m
!= NULL
&& (int) m_free
+ m_free
->length
> (int) m
) ||
226 (int) m_free
+ m_free
->length
> ((int) m_free
| 0xffff))
229 printf("Attempt to free bad pointer,"
230 "m_free = %08x (length %x), m = %08x\n",
231 m_free
, m_free
->length
, m
);
237 * Put block back in free list.
238 * Does it merge with the previos block?
242 if ((int) m_prev
+ m_prev
->length
== (int) m_free
)
244 m_prev
->length
+= sizeof(MDESC
) + m_free
->length
;
249 m_prev
->next
= m_free
;
250 m_free
->prev
= m_prev
;
260 * Does it merge with the next block?
264 if ((int) m_free
+ m_free
->length
== (int) m
)
266 m_free
->length
+= sizeof(MDESC
) + m
->length
;
267 m_free
->next
= m
->next
;
283 /**********************************************************************
287 HEAP_LocalFindHeap(unsigned short owner
)
292 printf("HEAP_LocalFindHeap: owner %04x\n", owner
);
295 for (lh
= LocalHeaps
; lh
!= NULL
; lh
= lh
->next
)
297 if (lh
->selector
== owner
)
304 /**********************************************************************
308 HEAP_LocalInit(unsigned short owner
, void *start
, int length
)
313 printf("HEAP_LocalInit: owner %04x, start %08x, length %04x\n",
314 owner
, start
, length
);
317 if (length
< 2 * sizeof(MDESC
))
320 lh
= (LHEAP
*) malloc(sizeof(*lh
));
324 lh
->next
= LocalHeaps
;
325 lh
->selector
= owner
;
326 lh
->local_table
= NULL
;
327 HEAP_Init(&lh
->free_list
, start
, length
);
331 /**********************************************************************
335 WIN16_LocalAlloc(int flags
, int bytes
)
340 printf("WIN16_LocalAlloc: flags %x, bytes %d\n", flags
, bytes
);
341 printf(" called from segment %04x\n", Stack16Frame
[11]);
344 m
= HEAP_Alloc(LOCALHEAP(), flags
, bytes
);
347 printf("WIN16_LocalAlloc: returning %x\n", (int) m
);
352 /**********************************************************************
356 WIN16_LocalCompact(int min_free
)
362 for (m
= *LOCALHEAP(); m
!= NULL
; m
= m
->next
)
363 if (m
->length
> max_block
)
364 max_block
= m
->length
;
369 /**********************************************************************
373 WIN16_LocalFlags(unsigned int handle
)
377 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
378 (handle
& 0xffff)) - 1;
379 if (m
->next
!= m
|| m
->prev
!= m
)
385 /**********************************************************************
389 WIN16_LocalFree(unsigned int handle
)
393 addr
= ((int) *LOCALHEAP() & 0xffff0000) | (handle
& 0xffff);
394 if (HEAP_Free(LOCALHEAP(), (void *) addr
) < 0)
400 /**********************************************************************
404 WIN16_LocalInit(unsigned int segment
, unsigned int start
, unsigned int end
)
406 unsigned short owner
= HEAP_OWNER
;
407 LHEAP
*lh
= HEAP_LocalFindHeap(owner
);
412 segment
= Stack16Frame
[6];
417 HEAP_LocalInit(owner
,
418 (void *) ((segment
<< 16) | start
), end
- start
+ 1);
422 HEAP_Init(&lh
->free_list
,
423 (void *) ((segment
<< 16) | start
), end
- start
+ 1);
429 /**********************************************************************
433 WIN16_LocalLock(unsigned int handle
)
437 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
438 (handle
& 0xffff)) - 1;
439 if (m
->next
!= m
|| m
->prev
!= m
)
443 return (void *) (m
+ 1);
446 /**********************************************************************
450 WIN16_LocalReAlloc(unsigned int handle
, int flags
, int bytes
)
454 m
= HEAP_ReAlloc(LOCALHEAP(), (void *)
455 (((int) *LOCALHEAP() & 0xffff0000) | (handle
& 0xffff)),
461 /**********************************************************************
465 WIN16_LocalSize(unsigned int handle
)
469 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
470 (handle
& 0xffff)) - 1;
471 if (m
->next
!= m
|| m
->prev
!= m
)
477 /**********************************************************************
481 WIN16_LocalUnlock(unsigned int handle
)
485 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
486 (handle
& 0xffff)) - 1;
487 if (m
->next
!= m
|| m
->prev
!= m
)
496 /**********************************************************************
497 * GetFreeSystemResources (user.284)
500 #define USERRESOURCES 2
501 #define GDIRESOURCES 1
502 #define SYSTEMRESOURCES 0
506 WORD
GetFreeSystemResources(WORD SystemResourceType
)
508 unsigned int GdiFree
=0,GdiResult
=0;
509 unsigned int UserFree
=0,UserResult
=0;
510 unsigned int result
=0;
513 printf("GetFreeSystemResources(%u)\n",SystemResourceType
);
515 switch(SystemResourceType
) {
517 for (m
= USER_Heap
; m
!= NULL
; m
= m
->next
) /* add up free area in heap */
518 UserFree
+= m
->length
;
519 result
=(UserFree
*100)/65516; /* 65516 == 64K */
522 for (m
= GDI_Heap
; m
!= NULL
; m
= m
->next
)
523 GdiFree
+= m
->length
;
524 result
=(GdiFree
*100)/65516;
526 case(SYSTEMRESOURCES
):
527 for (m
= USER_Heap
; m
!= NULL
; m
= m
->next
)
528 UserFree
+= m
->length
;
529 UserResult
=(UserFree
*100)/65516;
530 for (m
= GDI_Heap
; m
!= NULL
; m
= m
->next
)
531 GdiFree
+= m
->length
;
532 GdiResult
=(GdiFree
*100)/65516;
533 result
=(UserResult
< GdiResult
) ? UserResult
:GdiResult
;