A community wiki answer because it includes a lot of useful evidence, but I seem to flub the numbers somewhere:
Per OpenWatcom, the definition of _fmalloc
is this. Notably:
if( amt == 0 || amt > - ( sizeof( heapblk ) + TAG_SIZE * 2 ) ) {
return( NULL );
}
Allowing for integer rounding and given that size_t
is 16-bit, that asserts that if the block you asked for is larger than 65536
minus sizeof( heapblk ) + TAG_SIZE * 2
then the allocation will fail.
heapblk
is a struct:
struct heapblk {
tag len; /* size of heap (0 = 64K) */
heapptr prev; /* segment selector/offset for previous heap */
heapptr next; /* segment selector/offset for next heap */
freeptr 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 */
freelist freehead; /* listhead of free blocks in heap */
#if defined( __WARP__ )
unsigned int used_obj_any :1; /* allocated with OBJ_ANY - block may be in high memory */
#endif
};
And from line 50 of the same file, TAG_SIZE
is just sizeof(tag)
.
On line 106 tag
turns out to be a typedef for unsigned int
so it's also 16 bit.
heapptr
is a union defined on line 115, of a __segment
and a heapblk_nptr
(a.k.a. a _WCNEAR
). So it's two bytes as nptr
means near pointer, and a __segment
means 16 bit.
freeptr
is a union defined on line 120, of a freelist_nptr
and an unsigned int
. So also two bytes.
freelist
is a struct defined on line 125 consisting of a tag
, and two freeptr
s. So six bytes.
So a heapblk
is 22 bytes of meaningful storage:
- 8 bytes for the four
unsigned int
s;
- 2 bytes for the
tag
(because it's another unsigned int
);
- 6 more for the
freelist
;
- 2 for the
freeptr
; and
- 4 in total for the
heapptrs
.
That plus another 4 for the 2*TAG_SIZE is 26.
Therefore as posited elsewhere, you cannot allocate a full 64kb because some storage is reserved for heap management; however I seem to total that to 26 bytes, not 32.
sizeof(heapblk)
. If I can find my error I'll turn this into an answer.