⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memalloc.c

📁 地球模拟器
💻 C
字号:
/* memalloc.c   9-9-92 memory allocation routines for the Tierra Simulator *//* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */#ifndef lintstatic char     memalloc_sccsid[] = "@(#)memalloc.c        1.5     7/21/92";#endif#include <sys/types.h>#include "license.h"#include "tierra.h"#include "extern.h"#ifdef ALCOMM#include "tmonitor.h"#include "trequest.h"#include <mlayer.h>#endif#ifdef MEM_CHK#include <memcheck.h>#endif/* check to see if cell has write privelage at address */I8s  IsPriv(ce, a)Pcells  ce;I32s  a;{#ifdef ERROR    if(a >= SoupSize || a < 0)        FEError(-600,EXIT,WRITE,            "Tierra IsPriv() error: address %ld not in soup", a);#endif    if(IsInsideCell(ce, a)) return 1;    return IsFree(a);}I8s IsBitPriv(ce,a,mode,track)Pcells  ce;I32s     a; /* address being checked */I32s    mode, track; /* modes: 1 bit = execute, 2 bit = write, 4 bit = read */{   if(a < 0 || a >= SoupSize)        return 0;    if(IsInsideCell(ce,a))        return 1;    else        switch(mode)        {#if PLOIDY == 1            case 1: return !soup[a].exec;            case 2: return !soup[a].write;            case 4: return !soup[a].read;            case 6: return (!soup[a].read) && (!soup[a].write);#else /* PLOIDY > 1 */            case 1: return !soup[a][track].exec;            case 2: return !soup[a][track].write;            case 4: return !soup[a][track].read;            case 6: return (!soup[a][track].read) && (!soup[a][track].write);#endif /* PLOIDY > 1 */            default: return 0;        }}/* check to see if address is inside allocated memory cell ce */I8s  IsInsideCell(ce, a)Pcells  ce;I32s  a;{#ifdef ERROR    if(a >= SoupSize || a < 0)        FEError(-601,EXIT,WRITE,            "Tierra IsInsideCell() error: address %ld not in soup", a);#endif    if((ce->mm.p <= a && a < ce->mm.p + ce->mm.s) ||       (ce->md.s > 0 &&       (ce->md.p <= a && a < ce->md.p + ce->md.s)))        return 1;    return 0;}void  WhichCell(a, ce, md) /* find cell with address a */I32s        a;    /* note: a must be in a cell!, call IsFree() before */Pcells Fp  ce;   /* WhichCell() to find out if a is in a cell or not */I8s        *md;{   I32s  ar, ci;    Pcells  te;    for(ar = 0; ar < NumCelAr; ar++) for(ci = 0; ci < CelArSiz; ci++)    {   if (ar == 0 && ci < 2)            continue;        te = &cells[ar][ci];        if (te->ld)        {   if(te->mm.p <= a && (te->mm.p + te->mm.s) > a)            {   *ce = te; *md = 'm'; return; }            if(te->md.p <= a && (te->md.p + te->md.s) > a)            {   *ce = te; *md = 'd'; return; }        }    }    FEError(-601,EXIT,NOWRITE,        "Tierra WhichCell() error: address %ld not found in a cell", a);}/* ----------------------------------------------------------------------- */ /* 1 bit = execute, 2 bit = write, 4 bit = read */ /* only owner of memory has chmod privelages */ /* return 0 on success, return 1 on error */I8s chmode(ce, start, size, mode)    Pcells  ce;    I32s start, /* where in the soup to start */         size,  /* how far to go, (will wrap around end of soup) */         mode;  /* chmod bits, like unix, see above */{    I32s a = 0, t;    I8s exec, write, read, ret = 0;    exec =  IsBit(mode, 0);    write = IsBit(mode, 1);    read =  IsBit(mode, 2);    while (a < size)    {   t = ad(start + a);        if (IsInsideCell(ce, t))        {#if PLOIDY == 1            soup[t].exec = exec;            soup[t].write = write;            soup[t].read = read;#else  /* PLOIDY > 1 */            soup[t][ce->c.tr].exec = exec;            soup[t][ce->c.tr].write = write;            soup[t][ce->c.tr].read = read;#endif  /* PLOIDY > 1 */        }        else ret = 1;        a++;    }    return ret;}/* ----------------------------------------------------------------------- */I32s mal(ce,sug_addr,sug_size,mode) /* allocate space for a new cell */    Pcells  ce;    I32s *sug_addr, /* returns actuall address of block, */                    /* also suggested address for mal */         sug_size,  /* size of block to get */                    /* function returns actual size, or 0 on failure */         mode;      /* which mode to use, see switch below */{    I32s p;    I32s size, osize, sad;    if (sug_size <= 0 || sug_size == ce->md.s ||         sug_size > MaxMalMult * ce->mm.s)        return 0;    size = (I32s) sug_size + flaw(ce);    if (!size)        return 0;    if (ce->md.s)    {#ifdef ERROR        if (ce->md.p < 0 || ce->md.p >= SoupSize)            FEError(-613,EXIT,WRITE, "Tierra mal() error 1");#endif  /* DAN should check return val */        chmode(ce, ce->md.p, ce->md.s, MemModeFree);         MemDealloc(ce->md.p, ce->md.s);        ce->d.mov_daught = 0;        ce->md.s = 0;    }    switch (mode)    {   case 0: /* first fit */        {   while ((p = MemAlloc(size, 0, SoupSize - 1)) < 0)                reaper(1,0);            break;        }        case 2: /* random preference */        {   while ((p = MemAlloc(size, sad = tlrand() % (SoupSize - size),                    MalLimit)) < 0)                reaper(1,sad);            break;        }        case 3: /* preference for mother's address */        {   while ((p = MemAlloc(size, ce->mm.p, MalLimit)) < 0)                reaper(1,ce->mm.p);            break;        }        case 4: /* preference for dx address */        {   while ((p = MemAlloc(size, sad = mo(ce->c.re[3], SoupSize - size),                    MalLimit)) < 0)                reaper(1,sad);            break;        }        case 5: /* preference for top of stack address */        {   while ((p = MemAlloc(size, sad = mo(ce->c.st[ce->c.sp],                    SoupSize - size), MalLimit)) < 0)                reaper(1,sad);            break;        }        case 6: /* preference for suggested address (*sug_addr) */        {   while ((p = MemAlloc(size, sad = mo(*sug_addr, SoupSize - size),                    MalLimit)) < 0)                reaper(1,sad);            break;        }        case 1: default: /* better fit */        {   while ((p = MemAlloc(size, -1, 0)) < 0)                reaper(1,-1);        }    }#ifdef ERROR    if (p < 0 || p >= SoupSize)        FEError(-614,EXIT,WRITE, "Tierra mal() error 2");#endif    if (!size)        return 0;    /* got a block, pass location (sug_addr) and size back  */    *(sug_addr) = ce->md.p = ad(p);    ce->md.s = size;    ce->c.fl = 0;    DownReperIf(ce);    return size;}/* ----------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -