📄 memalloc.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 + -