mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-06-07 08:14:48 +00:00

Reformatted BlkPool.CC, HeapCtrl.CC, MAllocFree.CC, MemPag.CC, MemPhysical.CC, PageTables.CC.
202 lines
4.1 KiB
C++
Executable File
202 lines
4.1 KiB
C++
Executable File
U0 SysBadFree(I64 *ptr)
|
|
{
|
|
Panic("Bad Free:", ptr);
|
|
}
|
|
|
|
U0 SysBadMAlloc(I64 *ptr)
|
|
{
|
|
Panic("Bad MAlloc:", ptr);
|
|
}
|
|
|
|
U8 *MemPagAlloc(I64 pags, CBlkPool *bp=NULL)
|
|
{/*Alloc pags from BlkPool. Don't link to task.
|
|
(Linking to a task means they will be freed when the task dies.)
|
|
It might give you more than you asked for.
|
|
|
|
Return: NULL if out of memory.
|
|
*/
|
|
CMemBlk *res = NULL, *m;
|
|
I64 i;
|
|
|
|
if (!bp)
|
|
bp = sys_code_bp;
|
|
|
|
PUSHFD
|
|
CLI
|
|
while (LBts(&bp->locked_flags, BPlf_LOCKED))
|
|
PAUSE
|
|
if (pags < MEM_FREE_PAG_HASH_SIZE)
|
|
{
|
|
if (res = bp->free_pag_hash[pags])
|
|
{
|
|
bp->free_pag_hash[pags] = res->next;
|
|
goto at_done;
|
|
}
|
|
i = Bsr(MEM_FREE_PAG_HASH_SIZE) + 1;
|
|
} else {
|
|
//We'll now round-up to a power of two.
|
|
//There is some overhead on allocations and
|
|
//we wouldn't want to round to the next
|
|
//power of two if a power of two was requested.
|
|
//So we use a little more than a power of two.
|
|
pags -= MEM_EXTRA_HASH2_PAGS;
|
|
i = Bsr(pags) + 1;
|
|
pags = 1 << i + MEM_EXTRA_HASH2_PAGS;
|
|
if (res = bp->free_pag_hash2[i])
|
|
{
|
|
bp->free_pag_hash2[i] = res->next;
|
|
goto at_done;
|
|
}
|
|
}
|
|
m = &bp->mem_free_list;
|
|
while (TRUE)
|
|
{
|
|
if (!(res = m->next))
|
|
{
|
|
//We're probably out of luck, but lets search for a
|
|
//freed larger size block... and, screw-it, return the whole thing.
|
|
do
|
|
{
|
|
if (res = bp->free_pag_hash2[++i])
|
|
{
|
|
pags = 1 << i + MEM_EXTRA_HASH2_PAGS;
|
|
bp->free_pag_hash2[i] = res->next;
|
|
goto at_done;
|
|
}
|
|
}
|
|
while (i < 64 - MEM_PAG_BITS - 1);
|
|
|
|
pags = 0;
|
|
res = NULL; //Out of memory
|
|
goto at_done2;
|
|
}
|
|
if (res->pags < pags)
|
|
m = res;
|
|
else
|
|
{
|
|
if (res->pags == pags)
|
|
{
|
|
m->next = res->next;
|
|
goto at_done;
|
|
}
|
|
else
|
|
{
|
|
res->pags -= pags;
|
|
res(U8 *) += res->pags << MEM_PAG_BITS;
|
|
res->pags = pags;
|
|
goto at_done;
|
|
}
|
|
}
|
|
}
|
|
at_done:
|
|
bp->used_u8s += res->pags << MEM_PAG_BITS;
|
|
at_done2:
|
|
LBtr(&bp->locked_flags, BPlf_LOCKED);
|
|
POPFD
|
|
|
|
return res;
|
|
}
|
|
|
|
U0 MemPagFree(CMemBlk *m, CBlkPool *bp=NULL)
|
|
{//Return non-task pags to BlkPool.
|
|
I64 i, pags;
|
|
|
|
if (m)
|
|
{
|
|
if (!bp)
|
|
bp = sys_code_bp;
|
|
|
|
PUSHFD
|
|
CLI
|
|
while (LBts(&bp->locked_flags, BPlf_LOCKED))
|
|
PAUSE
|
|
pags = m->pags;
|
|
m->mb_signature = MBS_UNUSED_SIGNATURE_VAL;
|
|
bp->used_u8s -= pags << MEM_PAG_BITS;
|
|
if (pags < MEM_FREE_PAG_HASH_SIZE)
|
|
{
|
|
m->next = bp->free_pag_hash[pags];
|
|
bp->free_pag_hash[pags] = m;
|
|
}
|
|
else
|
|
{
|
|
//We'll now round-up to a power of two.
|
|
//There is some overhead on allocations and
|
|
//we wouldn't want to round to the next
|
|
//power of two if a power of two was requested.
|
|
//So we use a little more than a power of two.
|
|
pags -= MEM_EXTRA_HASH2_PAGS;
|
|
i = Bsr(pags);
|
|
m->next = bp->free_pag_hash2[i];
|
|
bp->free_pag_hash2[i] = m;
|
|
}
|
|
LBtr(&bp->locked_flags, BPlf_LOCKED);
|
|
POPFD
|
|
}
|
|
}
|
|
|
|
CMemBlk *MemPagTaskAlloc(I64 pags, CHeapCtrl *hc)
|
|
{/*hc must be locked. Don't preempt this routine.
|
|
Currently, this is only called from $LK,"MAlloc",A="MN:MAlloc"$().
|
|
Return: NULL if out of memory.
|
|
*/
|
|
CMemBlk *res;
|
|
I64 threshold, count, size;
|
|
CMemUnused *uum, **_uum, **_ptr;
|
|
|
|
if (res = MemPagAlloc(pags, hc->bp))
|
|
{
|
|
QueueInsert(res, hc->last_mem_blk);
|
|
res->mb_signature = MBS_USED_SIGNATURE_VAL;
|
|
hc->alloced_u8s += res->pags << MEM_PAG_BITS;
|
|
|
|
//Tidy-up free list (Move into heap hash)
|
|
//because if free list gets long, delay causes crash.
|
|
threshold = MEM_HEAP_HASH_SIZE >> 4;
|
|
#assert MEM_HEAP_HASH_SIZE >> 4 >= sizeof(U8 *)
|
|
do
|
|
{
|
|
count = 0;
|
|
_uum = &hc->malloc_free_list;
|
|
while (uum = *_uum)
|
|
{
|
|
#assert !offset(CMemUnused.next)
|
|
size = uum->size;
|
|
if (size < threshold)
|
|
{
|
|
*_uum = uum->next;
|
|
_ptr = (&hc->heap_hash)(U8 *) + size;
|
|
uum->next = *_ptr;
|
|
*_ptr = uum;
|
|
}
|
|
else
|
|
{
|
|
count++;
|
|
_uum = uum;
|
|
}
|
|
}
|
|
threshold <<= 1;
|
|
}
|
|
while (count > 8 && threshold <= MEM_HEAP_HASH_SIZE);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
U0 MemPagTaskFree(CMemBlk *m, CHeapCtrl *hc)
|
|
{//hc must be locked
|
|
if (m)
|
|
{
|
|
PUSHFD
|
|
CLI
|
|
if (m->mb_signature != MBS_USED_SIGNATURE_VAL)
|
|
SysBadFree(m);
|
|
else
|
|
{
|
|
QueueRemove(m);
|
|
hc->alloced_u8s -= m->pags << MEM_PAG_BITS;
|
|
MemPagFree(m, hc->bp);
|
|
}
|
|
POPFD
|
|
}
|
|
}
|