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
)
120 * Check validity of block
122 m
= (MDESC
*) old_block
- 1;
124 printf("HEAP_ReAlloc new_size=%d !\n", new_size
);
125 printf("HEAP_ReAlloc old_block=%08X !\n", old_block
);
126 printf("HEAP_ReAlloc m=%08X free_list=%08X !\n", m
, free_list
);
127 printf("HEAP_ReAlloc m->prev=%08X !\n", m
->prev
);
128 printf("HEAP_ReAlloc m->next=%08X !\n", m
->next
);
129 printf("HEAP_ReAlloc *free_list=%08X !\n", *free_list
);
131 if (m
->prev
!= m
|| m
->next
!= m
||
132 ((int) m
& 0xffff0000) != ((int) *free_list
& 0xffff0000))
134 printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
137 printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
144 * Check for grow block
147 printf("HEAP_ReAlloc Check for grow block !\n");
149 if (new_size
> m
->length
)
151 m_free
= m
+ 1 + m
->length
/ sizeof(MDESC
);
152 if (m_free
->next
== m_free
||
153 m_free
->prev
== m_free
||
154 m_free
->length
+ sizeof(MDESC
) < new_size
)
156 void *new_p
= HEAP_Alloc(free_list
, flags
, new_size
);
159 memcpy(new_p
, old_block
, m
->length
);
160 HEAP_Free(free_list
, old_block
);
164 if (m_free
->prev
== NULL
)
165 *free_list
= m_free
->next
;
167 m_free
->prev
->next
= m_free
->next
;
169 if (m_free
->next
!= NULL
)
170 m_free
->next
->prev
= m_free
->prev
;
172 m
->length
+= sizeof(MDESC
) + m_free
->length
;
174 printf("HEAP_ReAlloc before GLOBAL_FLAGS_ZEROINIT !\n");
176 if (flags
& GLOBAL_FLAGS_ZEROINIT
)
177 memset(m_free
, '\0', sizeof(MDESC
) + m_free
->length
);
181 * Check for shrink block.
184 printf("HEAP_ReAlloc Check for shrink block !\n");
186 if (new_size
< m
->length
- 4 * sizeof(MDESC
))
188 m_free
= m
+ new_size
/ sizeof(MDESC
) + 2;
189 m_free
->next
= m_free
;
190 m_free
->prev
= m_free
;
191 m_free
->length
= m
->length
- (int) m_free
- (int) m
;
192 m
->length
= (int) m_free
- (int) (m
+ 1);
193 HEAP_Free(free_list
, m_free
+ 1);
200 /**********************************************************************
204 HEAP_Free(MDESC
**free_list
, void *block
)
213 m_free
= (MDESC
*) block
- 1;
214 if (m_free
->prev
!= m_free
|| m_free
->next
!= m_free
||
215 ((int) m_free
& 0xffff0000) != ((int) *free_list
& 0xffff0000))
218 printf("Attempt to free bad pointer,"
219 "m_free = %08x, *free_list = %08x\n",
226 * Find location in free list.
229 for (m
= *free_list
; m
!= NULL
&& m
< m_free
; m
= m
->next
)
232 if (m_prev
!= NULL
&& (int) m_prev
+ m_prev
->length
> (int) m_free
)
235 printf("Attempt to free bad pointer,"
236 "m_free = %08x, m_prev = %08x (length %x)\n",
237 m_free
, m_prev
, m_prev
->length
);
242 if ((m
!= NULL
&& (int) m_free
+ m_free
->length
> (int) m
) ||
243 (int) m_free
+ m_free
->length
> ((int) m_free
| 0xffff))
246 printf("Attempt to free bad pointer,"
247 "m_free = %08x (length %x), m = %08x\n",
248 m_free
, m_free
->length
, m
);
254 * Put block back in free list.
255 * Does it merge with the previos block?
259 if ((int) m_prev
+ m_prev
->length
== (int) m_free
)
261 m_prev
->length
+= sizeof(MDESC
) + m_free
->length
;
266 m_prev
->next
= m_free
;
267 m_free
->prev
= m_prev
;
277 * Does it merge with the next block?
281 if ((int) m_free
+ m_free
->length
== (int) m
)
283 m_free
->length
+= sizeof(MDESC
) + m
->length
;
284 m_free
->next
= m
->next
;
300 /**********************************************************************
304 HEAP_LocalFindHeap(unsigned short owner
)
309 printf("HEAP_LocalFindHeap: owner %04x\n", owner
);
312 for (lh
= LocalHeaps
; lh
!= NULL
; lh
= lh
->next
)
314 if (lh
->selector
== owner
)
321 /**********************************************************************
325 HEAP_LocalInit(unsigned short owner
, void *start
, int length
)
330 printf("HEAP_LocalInit: owner %04x, start %08x, length %04x\n",
331 owner
, start
, length
);
334 if (length
< 2 * sizeof(MDESC
))
337 lh
= (LHEAP
*) malloc(sizeof(*lh
));
341 lh
->next
= LocalHeaps
;
342 lh
->selector
= owner
;
343 lh
->local_table
= NULL
;
344 HEAP_Init(&lh
->free_list
, start
, length
);
348 /**********************************************************************
352 WIN16_LocalAlloc(int flags
, int bytes
)
357 printf("WIN16_LocalAlloc: flags %x, bytes %d\n", flags
, bytes
);
358 printf(" called from segment %04x\n", Stack16Frame
[11]);
361 m
= HEAP_Alloc(LOCALHEAP(), flags
, bytes
);
364 printf("WIN16_LocalAlloc: returning %x\n", (int) m
);
369 /**********************************************************************
373 WIN16_LocalCompact(int min_free
)
379 for (m
= *LOCALHEAP(); m
!= NULL
; m
= m
->next
)
380 if (m
->length
> max_block
)
381 max_block
= m
->length
;
386 /**********************************************************************
390 WIN16_LocalFlags(unsigned int handle
)
394 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
395 (handle
& 0xffff)) - 1;
396 if (m
->next
!= m
|| m
->prev
!= m
)
402 /**********************************************************************
406 WIN16_LocalFree(unsigned int handle
)
410 addr
= ((int) *LOCALHEAP() & 0xffff0000) | (handle
& 0xffff);
411 if (HEAP_Free(LOCALHEAP(), (void *) addr
) < 0)
417 /**********************************************************************
421 WIN16_LocalInit(unsigned int segment
, unsigned int start
, unsigned int end
)
423 unsigned short owner
= HEAP_OWNER
;
424 LHEAP
*lh
= HEAP_LocalFindHeap(owner
);
429 segment
= Stack16Frame
[6];
434 HEAP_LocalInit(owner
,
435 (void *) ((segment
<< 16) | start
), end
- start
+ 1);
439 HEAP_Init(&lh
->free_list
,
440 (void *) ((segment
<< 16) | start
), end
- start
+ 1);
442 printf("WIN16_LocalInit // return segment=%04X !\n", segment
);
446 /**********************************************************************
450 WIN16_LocalLock(unsigned int handle
)
454 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
455 (handle
& 0xffff)) - 1;
456 if (m
->next
!= m
|| m
->prev
!= m
)
460 return (void *) (m
+ 1);
463 /**********************************************************************
467 WIN16_LocalReAlloc(unsigned int handle
, int bytes
, int flags
)
471 printf("WIN16_LocalReAlloc(%04X, %d, %04X); !\n", handle
, bytes
, flags
);
472 printf("WIN16_LocalReAlloc // LOCALHEAP()=%08X !\n", LOCALHEAP());
473 printf("WIN16_LocalReAlloc // *LOCALHEAP()=%08X !\n", *LOCALHEAP());
475 m
= HEAP_ReAlloc(LOCALHEAP(), (void *)
476 (((int) *LOCALHEAP() & 0xffff0000) | (handle
& 0xffff)),
482 /**********************************************************************
486 WIN16_LocalSize(unsigned int handle
)
490 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
491 (handle
& 0xffff)) - 1;
492 if (m
->next
!= m
|| m
->prev
!= m
)
498 /**********************************************************************
502 WIN16_LocalUnlock(unsigned int handle
)
506 m
= (MDESC
*) (((int) *LOCALHEAP() & 0xffff0000) |
507 (handle
& 0xffff)) - 1;
508 if (m
->next
!= m
|| m
->prev
!= m
)
517 /**********************************************************************
518 * GetFreeSystemResources (user.284)
521 #define USERRESOURCES 2
522 #define GDIRESOURCES 1
523 #define SYSTEMRESOURCES 0
527 WORD
GetFreeSystemResources(WORD SystemResourceType
)
529 unsigned int GdiFree
=0,GdiResult
=0;
530 unsigned int UserFree
=0,UserResult
=0;
531 unsigned int result
=0;
534 printf("GetFreeSystemResources(%u)\n",SystemResourceType
);
536 switch(SystemResourceType
) {
538 for (m
= USER_Heap
; m
!= NULL
; m
= m
->next
) /* add up free area in heap */
539 UserFree
+= m
->length
;
540 result
=(UserFree
*100)/65516; /* 65516 == 64K */
543 for (m
= GDI_Heap
; m
!= NULL
; m
= m
->next
)
544 GdiFree
+= m
->length
;
545 result
=(GdiFree
*100)/65516;
547 case(SYSTEMRESOURCES
):
548 for (m
= USER_Heap
; m
!= NULL
; m
= m
->next
)
549 UserFree
+= m
->length
;
550 UserResult
=(UserFree
*100)/65516;
551 for (m
= GDI_Heap
; m
!= NULL
; m
= m
->next
)
552 GdiFree
+= m
->length
;
553 GdiResult
=(GdiFree
*100)/65516;
554 result
=(UserResult
< GdiResult
) ? UserResult
:GdiResult
;