📄 memmgr.c
字号:
/****************************************************************/
/* */
/* memmgr.c */
/* */
/* Memory Manager for Core Allocation */
/* */
/* Copyright (c) 1995 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
#include "../../hdr/portab.h"
#include "globals.h"
/* $Logfile*/
#ifdef VERSION_STRING
static BYTE *memmgrRcsId = "$Header: C:/dos-c/src/kernel/memmgr.c_v 1.6 04 Jan 1998 23:15:18 patv $";
#endif
/* $Log: C:/dos-c/src/kernel/memmgr.c_v $
*
* Rev 1.6 04 Jan 1998 23:15:18 patv
* Changed Log for strip utility
*
* Rev 1.5 16 Jan 1997 12:47:00 patv
* pre-Release 0.92 feature additions
*
* Rev 1.4 29 May 1996 21:03:34 patv
* bug fixes for v0.91a
*
* Rev 1.3 19 Feb 1996 3:21:36 patv
* Added NLS, int2f and config.sys processing
*
* Rev 1.2 01 Sep 1995 17:54:20 patv
* First GPL release.
*
* Rev 1.1 30 Jul 1995 20:51:58 patv
* Eliminated version strings in ipl
*
* Rev 1.0 02 Jul 1995 8:33:08 patv
* Initial revision.
*/
/* $EndLog$ */
VOID mcb_init();
VOID mcb_print();
VOID show_chain();
/* The following code is 8086 dependant */
#ifdef KERNEL
VOID
mcb_init (mcb FAR *mcbp, UWORD size)
{
COUNT i;
mcbp -> m_type = MCB_LAST;
mcbp -> m_psp = FREE_PSP;
mcbp -> m_size = size;
for(i = 0; i < 8; i++)
mcbp -> m_name[i] = '\0';
mem_access_mode = FIRST_FIT;
}
#endif
seg
far2para (VOID FAR *p)
{
seg u1 = FP_SEG(p);
offset u2 = FP_OFF(p);
ULONG phy_addr;
phy_addr = (((long)u1) << 4) + u2;
return (phy_addr>>4);
}
seg
long2para (LONG size)
{
return ((size + 0x0f)>>4);
}
VOID FAR *
add_far (VOID FAR *fp, ULONG off)
{
UWORD seg_val;
UWORD off_val;
/* Break far pointer into components */
seg_val = FP_SEG(fp);
off_val = FP_OFF(fp);
/* add the offset to the fp's offset part */
off += off_val;
/* make off_val equal to lower part of new value */
off_val = off & 0xffff;
/* and add top part into seg */
seg_val += ((off & 0x000f0000l) / 0x10);
/* and send back the new pointer */
return (VOID FAR *)MK_FP(seg_val, off_val);
}
VOID FAR *
adjust_far (VOID FAR *fp)
{
ULONG linear;
UWORD seg_val;
UWORD off_val;
/* First, convert the segmented pointer to a linear address */
linear = (((ULONG)FP_SEG(fp)) << 4) + FP_OFF(fp);
/* Break it into segments. */
seg_val = (UWORD)(linear >> 4);
off_val = (UWORD)(linear & 0xf);
/* and return an adddress adjusted to the nearest paragraph */
/* boundary. */
return MK_FP(seg_val, off_val);
}
#undef REG
#define REG
#ifdef KERNEL
COUNT
DosMemAlloc (UWORD size, COUNT mode, seg FAR *para, UWORD FAR *asize)
{
REG mcb FAR *p;
mcb FAR *q;
COUNT i;
BOOL found;
/* Initialize */
p = (mcb FAR *)(MK_FP(first_mcb, 0));
/* Search through memory blocks */
for(q = (mcb FAR *)0, i = 0, found = FALSE; !found; )
{
/* check for corruption */
if(p -> m_type != MCB_NORMAL && p -> m_type != MCB_LAST)
return DE_MCBDESTRY;
/* Test if free based on mode rules */
switch(mode)
{
case LAST_FIT:
default:
/* Check for a last fit candidate */
if(p -> m_size >= size && p -> m_psp == FREE_PSP)
/* keep the last know fit */
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;
break;
case FIRST_FIT:
/* Check for a first fit candidate */
if(p -> m_size >= size && p -> m_psp == FREE_PSP)
{
q = p;
found = TRUE;
break;
}
/* not free - bump the pointer */
if(p -> m_type != MCB_LAST)
p = MK_FP(far2para((VOID FAR *)p) + p -> m_size + 1, 0);
/* nothing found till end - no room */
else
return DE_NOMEM;
break;
case BEST_FIT:
/* Check for a best fit candidate */
if(p -> m_size >= size && p -> m_psp == FREE_PSP)
{
if(i == 0 || p -> m_size < i)
{
i = 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;
break;
case LARGEST:
/* Check for a first fit candidate */
if((p -> m_psp == FREE_PSP) && (i == 0 || p -> m_size > i))
{
size = *asize = i = 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;
break;
}
}
p = q;
/* Larger fit case */
if(p -> m_size > size)
{
if(mode != LAST_FIT)
{
q = MK_FP(far2para((VOID FAR *)p) + size + 1, 0);
/* Always flow m_type up */
/* on alloc */
q -> m_type = p -> m_type;
p -> m_type = MCB_NORMAL;
p -> m_psp = cu_psp;
q -> m_psp = FREE_PSP;
q -> m_size = p -> m_size - size - 1;
p -> m_size = size;
for(i = 0; i < 8; i++)
p -> m_name[i] = q -> m_name[i] = '\0';
}
else
{
q = MK_FP(far2para((VOID FAR *)p) + (p -> m_size - size), 0);
/* Always flow m_type up */
/* on alloc */
q -> m_type = p -> m_type;
p -> m_type = MCB_NORMAL;
q -> m_psp = cu_psp;
p -> m_psp = FREE_PSP;
p -> m_size = p -> m_size - size - 1;
q -> m_size = size;
for(i = 0; i < 8; i++)
p -> m_name[i] = q -> m_name[i] = '\0';
}
/* Found - return good */
*para = far2para((VOID FAR *)(mode == LAST_FIT ? (VOID FAR *)q : (VOID FAR *)p));
return SUCCESS;
}
/* Exact fit case */
else if(p -> m_size == size)
{
p -> m_psp = cu_psp;
for(i = 0; i < 8; i++)
p -> m_name[i] = '\0';
/* Found - return good */
*para = far2para((VOID FAR *)(BYTE FAR *)p);
return SUCCESS;
}
else
return DE_MCBDESTRY;
}
seg
DosMemLargest (seg FAR *size)
{
REG mcb FAR *p;
mcb FAR *q;
COUNT found;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -