📄 memmgr.c
字号:
/* Initialize */
p = (mcb FAR *)(MK_FP(first_mcb, 0));
/* Search through memory blocks */
for(q = (mcb FAR *)0, *size = 0, found = FALSE; !found; )
{
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
/* Test for largest fit/available */
if((p -> m_psp == FREE_PSP) && (p -> m_size > *size))
{
*size = p -> m_size;
q = p;
}
/* not free - bump the pointer */
if(p -> m_type != MCB_LAST)
p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
/* was there no room (q == 0)? */
else if(p -> m_type == MCB_LAST && q == (mcb FAR *)0)
return DE_NOMEM;
/* something was found - continue */
else
found = TRUE;
}
if( q != 0)
return SUCCESS;
else
return DE_NOMEM;
}
COUNT
DosMemFree (UWORD para)
{
REG mcb FAR *p, FAR *q;
COUNT i;
/* Initialize */
p = (mcb FAR *)(MK_FP(para, 0));
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_INVLDMCB;
/* Mark the mcb as free so that we can later */
/* merge with other surrounding free mcb's */
p -> m_psp = FREE_PSP;
for(i = 0; i < 8; i++)
p -> m_name[i] = '\0';
/* Now merge free blocks */
for(p = (mcb FAR *)(MK_FP(first_mcb, 0)); p -> m_type != MCB_LAST; p = q)
{
/* make q a pointer to the next block */
q = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
/* and test for corruption */
if(q -> m_type != MCB_NORMAL && q -> m_type != MCB_LAST)
return DE_MCBDESTRY;
if(p -> m_psp != FREE_PSP)
continue;
/* test if next is free - if so merge */
if(q -> m_psp == FREE_PSP)
{
/* Always flow type down on free */
p -> m_type = q -> m_type;
p -> m_size += q -> m_size + 1;
/* and make pointers the same */
/* since the next free is now */
/* this block */
q = p;
}
}
return SUCCESS;
}
COUNT
DosMemChange (UWORD para, UWORD size, UWORD *maxSize)
{
REG mcb FAR *p, FAR *q;
REG COUNT i;
/* Initialize */
p = (mcb FAR *)(MK_FP(--para, 0));
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
/* check for wrong allocation */
if(size > p -> m_size)
{
REG UCOUNT delta;
if (p -> m_type == MCB_LAST)
{
if (maxSize) *maxSize = p -> m_size + q -> m_size;
return DE_NOMEM;
}
/* make q a pointer to the next block */
q = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
/* check for corruption */
if(q -> m_type != MCB_NORMAL && q -> m_type != MCB_LAST)
return DE_MCBDESTRY;
/* if next mcb is not free, error no memory */
if(q -> m_psp != FREE_PSP)
{
if (maxSize) *maxSize = p -> m_size;
return DE_NOMEM;
}
/* reduce the size of q and add difference to p */
/* but check that q is big enough first */
delta = size - p -> m_size;
if(q -> m_size < delta)
{
if (maxSize) *maxSize = p -> m_size + q -> m_size;
return DE_NOMEM;
}
q -> m_size -= delta;
p -> m_size += delta;
/* Now go back and adjust q, we'll make p new q */
p = MK_FP(far2para((VOID FAR *)q) + delta, 0);
p -> m_type = q -> m_type;
p -> m_psp = q -> m_psp;
p -> m_size = q -> m_size;
for(i = 0; i < 8; i++)
p -> m_name[i] = q -> m_name[i];
/* and finished */
return SUCCESS;
}
/* else, shrink it down */
else if(size < p -> m_size)
{
/* make q a pointer to the new next block */
q = MK_FP(far2para((VOID FAR *)p) + size + 1, 0);
/* reduce the size of p and add difference to q */
q -> m_type = p -> m_type;
q -> m_size = p -> m_size - size - 1;
p -> m_size = size;
/* Make certian the old psp is not last (if it was) */
p -> m_type = MCB_NORMAL;
/* Mark the mcb as free so that we can later */
/* merge with other surrounding free mcb's */
q -> m_psp = FREE_PSP;
for(i = 0; i < 8; i++)
q -> m_name[i] = '\0';
/* now free it so that we have a complete block */
return DosMemFree(far2para((VOID FAR *)q));
}
/* otherwise, its a no-op */
else
return SUCCESS;
}
COUNT
DosMemCheck (void)
{
REG mcb FAR *p;
/* Initialize */
p = (mcb FAR *)(MK_FP(first_mcb, 0));
/* Search through memory blocks */
for( ; ; )
{
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
/* not corrupted - if last we're OK! */
if(p -> m_type == MCB_LAST)
return SUCCESS;
/* not corrupted - but not end, bump the pointer */
else if(p -> m_type != MCB_LAST)
p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
/* totally lost - bad exit */
else
return DE_MCBDESTRY;
}
}
COUNT
FreeProcessMem (UWORD ps)
{
mcb FAR *p;
/* Initialize */
p = (mcb FAR *)(MK_FP(first_mcb, 0));
/* Search through memory blocks */
for( ; ; )
{
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
if(p -> m_psp == ps)
DosMemFree( FP_SEG(p) );
/* not corrupted - if last we're OK! */
if(p -> m_type == MCB_LAST) break;
p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
}
return SUCCESS;
}
COUNT
DosGetLargestBlock(UWORD FAR *block)
{
UWORD sz = 0;
mcb FAR *p;
*block = sz;
/* Initialize */
p = (mcb FAR *)(MK_FP(first_mcb, 0));
/* Search through memory blocks */
for( ; ; )
{
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
if (p -> m_psp == FREE_PSP && p -> m_size > sz)
sz = p -> m_size;
/* not corrupted - if last we're OK! */
if(p -> m_type == MCB_LAST) break;
p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
}
*block = sz;
return SUCCESS;
}
VOID
show_chain (void)
{
mcb FAR *p = (mcb FAR *)(MK_FP(first_mcb, 0));
for(;;)
{
mcb_print(p);
if(p -> m_type == MCB_LAST || p -> m_type != MCB_NORMAL)
return;
else
p = (mcb FAR *)(MK_FP(far2para((VOID FAR *)p)+p -> m_size+1,0));
}
}
VOID
mcb_print (mcb FAR *mcbp)
{
static BYTE buff[9];
VOID _fmemcpy();
_fmemcpy((BYTE FAR *)buff, (BYTE FAR *)(mcbp -> m_name), 8);
buff[8] = '\0';
printf("%04x:%04x -> |%s| m_type = 0x%02x; m_psp = 0x%04x; m_size = 0x%04x\n",
FP_SEG(mcbp),
FP_OFF(mcbp),
*buff == '\0' ? "*NO-ID*" : buff,
mcbp -> m_type,
mcbp -> m_psp,
mcbp -> m_size);
}
VOID _fmemcpy(BYTE FAR *d, BYTE FAR *s, REG COUNT n)
{
while(n--)
*d++ = *s++;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -