?? skeleton.c
字號:
{
if(--size >= 0)
{
unsigned int c = *d++;
if(isprint(c))
side1[i] = c;
else
side1[i] = '.';
hex1[j++] = hexbyte(c>>4);
hex1[j++] = hexbyte(c);
++j;
}
else break;
}
for(i=0,j=0; i < 8; ++i)
{
if(--size >= 0)
{
unsigned int c = *d++;
if(isprint(c))
side2[i] = c;
else
side2[i] = '.';
hex2[j++] = hexbyte(c>>4);
hex2[j++] = hexbyte(c);
++j;
}
else break;
}
BUGPRINTF("%s %s%s%s %s%s%s\n",addr,hex1," | ",hex2,side1,"|",side2);
vaddr += 16;
}
}
#endif
/*
* Returns a really good 31-bit random number.
*/
static long
lrandom()
{
long i;
*fptr += *rptr;
i = (*fptr >> 1) & 0x7fffffffUL;
if(++fptr > &randtbl[31])
{
fptr = &randtbl[1];
++rptr;
}
else
{
if(++rptr > &randtbl[31])
rptr = &randtbl[1];
}
return( i );
}
static void *
do_sbrk(unsigned amount)
{
void *address;
address = VSBRK(amount); /* OR WHATEVER TO ACCESS THE OPERATING SYSTEM */
if(address == (void*)-1)
{
VCRASH("\nskel: system out of memory, requested %u bytes\n", amount);
}
return address;
}
static struct _catlocs *
new_catloc(void)
{
struct _catlocs *p;
if((p=freecatlocs))
{
freecatlocs = p->fptr;
return p;
}
if(binsize < sizeof(struct _catlocs))
{
binbase = THEWELL(4096);
binsize = 4096;
MPRINTF("NEWCATLOC at:%p size=4096\n", binbase);
}
binsize -= sizeof(struct _catlocs);
p = (void*)binbase;
binbase += sizeof(struct _catlocs);
return p;
}
static void
free_catloc(struct _catlocs *p)
{
p->fptr = freecatlocs;
freecatlocs = p;
}
static void *
new_chunk(struct _bins *bp, int size, int type)
{
char *p;
if(bp->chunksize[type] < size)
{
if(bp->bincat == 0) {
bp->chunkbase[type] = THEWELL(chunksizes[type]);
bp->chunksize[type] = chunksizes[type];
MPRINTF("NEWCHUNK0 at:%p size=%d\n", bp->chunkbase[type], bp->chunksize[type]);
}
else {
struct _catlocs *cl;
bp->chunkbase[type] = mallocC(0,chunksizes[type]-zbp.guarded);
bp->chunksize[type] = chunksizes[type]-zbp.guarded;
cl = new_catloc();
cl->addr = bp->chunkbase[type];
cl->fptr = bp->catlocs;
bp->catlocs = cl;
MPRINTF("NEWCHUNK%d at:%p size=%d\n", bp->bincat, bp->chunkbase[type], bp->chunksize[type]);
}
}
bp->chunksize[type] -= size;
p = bp->chunkbase[type];
bp->chunkbase[type] += size;
return p;
}
static void *
new_Mnode(struct _bins *bp, int levels, int type)
{
int size;
NodePM p;
if((p=bp->freenodes[type][levels]))
{
bp->freenodes[type][levels] = p->fptr[0];
p->value = 0;
return p;
}
size = sizeof(struct _nodeM) + levels * sizeof(void*);
p = new_chunk(bp, size, type);
p->levels = levels;
p->value = 0;
return p;
}
static void
free_Mnode(struct _bins *bp, NodePM p, int type)
{
p->fptr[0] = bp->freenodes[type][p->levels];
bp->freenodes[type][p->levels] = p;
}
static struct _addr *
new_addr(struct _bins *bp)
{
struct _addr *p;
if((p=bp->freeaddrlocs))
{
bp->freeaddrlocs = p->fptr;
return p;
}
return new_chunk(bp, sizeof(struct _addr), FREEH);
}
static void
free_addr(struct _bins *bp, struct _addr *p)
{
p->fptr = bp->freeaddrlocs;
bp->freeaddrlocs = p;
}
static struct _bins *
new_bins(void)
{
struct _bins *p;
if((p=freebinlocs))
{
freebinlocs = p->fptr;
return p;
}
if(binsize < sizeof(struct _bins))
{
binbase = THEWELL(4096);
binsize = 4096;
MPRINTF("NEWBINS at:%p size=4096\n", binbase);
}
binsize -= sizeof(struct _bins);
p = (struct _bins*)binbase;
binbase += sizeof(struct _bins);
return p;
}
static void
free_bins(struct _bins *p)
{
p->fptr = freebinlocs;
freebinlocs = p;
}
static int
getMlevel (struct _bins *p, int binlevel)
{
int level = -1;
int bits = 0;
while(bits == 0)
{
if (p->nbits == 0)
{
p->bits = lrandom();
p->nbits = 15;
}
bits = p->bits & 3;
p->bits >>= 2;
p->nbits--;
if(++level > binlevel)
break;
}
return (level > MAL_MAXLEVEL) ? MAL_MAXLEVEL : level;
}
static void
init_bins(struct _bins *bp, int category)
{
int i;
int binnum = category % 1009;
bzero(bp, sizeof(struct _bins));
bp->bincat = category;
bp->minloc = 0xffffffff;
bp->fptr = hmap[binnum];
hmap[binnum] = bp;
bp->SIZEHheader = new_Mnode(bp, MAL_MAXLEVEL+1, SIZEH);
bp->FREEHheader = new_Mnode(bp, MAL_MAXLEVEL+1, FREEH);
bp->USEDHheader = new_Mnode(bp, MAL_MAXLEVEL+1, USEDH);
for(i = 0; i <= MAL_MAXLEVEL; ++i)
{
bp->SIZEHheader->fptr[i] = _NILLL;
bp->FREEHheader->fptr[i] = _NILLL;
bp->USEDHheader->fptr[i] = _NILLL;
}
}
static struct _bins*
getcat(int category)
{
struct _bins *hbp;
hbp = hmap[category % 1009];
while(hbp)
{
if(hbp->bincat == category)
return hbp;
hbp = hbp->fptr;
}
return 0;
}
static struct _bins *
initcat(int category)
{
struct _bins *bp;
if(category == 0)
{
bp = &zbp;
if(zbp.SIZEHheader == 0)
init_bins(bp, category);
return bp;
}
/* do this to set zbp.guarded properly on startup */
if(zbp.SIZEHheader == 0)
initcat(0);
if((bp = new_bins()))
{
init_bins(bp, category);
return bp;
}
return 0;
}
static void *
getspace(struct _bins *bp, unsigned size, unsigned *remainder)
{
unsigned desired;
void *address;
desired = ((size+ALLOCSIZE-1)/ALLOCSIZE)*ALLOCSIZE;
if(bp->bincat == 0)
{
address = THEWELL(desired);
*remainder = desired - size;
MPRINTF("GETSPACE at:%p size=%d\n", address, desired);
}
else
{
struct _catlocs *cl;
if((desired-size) > zbp.guarded)
desired -= zbp.guarded;
address = mallocC(0, desired);
*remainder = desired - size;
/* save the gross allocations for the category */
cl = new_catloc();
cl->addr = address;
cl->fptr = bp->catlocs;
bp->catlocs = cl;
}
/* maintain address range info */
if((unsigned)address < bp->minloc)
bp->minloc = (unsigned)address;
if(((unsigned)address + desired) > bp->maxloc)
bp->maxloc = (unsigned)address + desired;
if(bp->minloc < minloc)
minloc = bp->minloc;
if(bp->maxloc > maxloc)
maxloc = bp->maxloc;
return address;
}
static void
addto_sizelist(struct _bins *bp, AddrP ap)
{
SKIPVARS;
/* INSERT IN SIZE LIST */
FINDKEY(SIZEH, ap->size)
if(node->key == ap->size)
{/* size node exists */
ap->fptr = (AddrP)node->value;
ap->bptr = (AddrP)&node->value;
if(ap->fptr) ap->fptr->bptr = ap;
node->value = (unsigned)ap;
}
else
{/* create new size node */
SETLEVEL(SIZEH)
node = new_Mnode(bp, level, SIZEH);
node->key = ap->size;
node->value = (unsigned)ap;
ap->fptr = 0;
ap->bptr = (AddrP)&node->value;
INSERT()
}
}
static void
addto_freelist(struct _bins *bp, void *addr, unsigned size)
{
SKIPVARS;
AddrP ap,sp;
unsigned dsize[2];
/* GET NEW ADDR STRUCT */
ap = new_addr(bp);
ap->size = size;
dsize[1] = dsize[0] = 0; /* sizenode deletion markers */
/* CHECK FREE LIST */
FINDKEY(FREEH, (unsigned)addr)
/* CHECK FOR MERGE OR INSERT */
if(prev->value && prev->key+((AddrP)prev->value)->size == (unsigned)addr)
{/* merge with previous block */
ap->size += ((AddrP)prev->value)->size;
if(prev->key + ap->size == node->key)
{/* merge with previous and next block */
sp = (AddrP) node->value;;
ap->size += sp->size;
/* delete size struct for next block */
UNLINK(sp, 0)
/* delete next block */
DELETENODE(FREEH);
}
/* delete size struct for prev block */
sp = (AddrP)prev->value;
UNLINK(sp, 1)
/* set new address struct */
prev->value = (unsigned)ap;
ap->maddr = prev;
}
else if(node->value && (char*)addr + size == (void*)node->key)
{/* merge with next block */
sp = (AddrP) node->value;;
node->key = (unsigned)addr;
ap->size += sp->size;
/* unlink size struct for next block */
UNLINK(sp,0)
/* set new address struct */
node->value = (unsigned)ap;
ap->maddr = node;
}
else
{/* insert in free list */
SETLEVEL(FREEH)
node = new_Mnode(bp, level, FREEH);
node->key = (unsigned)addr;
node->value = (unsigned)ap;
ap->maddr = node;
INSERT()
}
addto_sizelist(bp, ap);
/* Remove sizenodes eliminated by merge */
if(dsize[0])
{
FINDKEY(SIZEH, dsize[0])
if(node->value == 0)
DELETENODE(SIZEH)
}
if(dsize[1])
{
FINDKEY(SIZEH, dsize[1])
if(node->value == 0)
DELETENODE(SIZEH)
}
}
void*
memalignC(int category, unsigned alignment, unsigned req)
{
SKIPVARS;
NodePM fnode;
unsigned remainder;
unsigned *address;
struct _bins *bp;
unsigned mask, size;
if(!(bp = getcat(category)))
if(!(bp = initcat(category)))
return 0;
HEAPCHECK
if(req == 0)
req = ALIGNMENTM;
else
req += ROUNDINGM(req);
size = req += bp->guarded;
if(alignment)
{
alignment += ROUNDINGM(alignment);
if(alignment > ALIGNMENTM)
{
mask = alignment -1;
size = req + alignment + bp->guarded;
}
else
{
alignment = 0;
}
}
/* check sizelist for candidate */
FINDKEY(SIZEH, size)
fnode = node;
trynext:
if(node->key != 0xffffffff)
{/* found an appropriately sized block */
AddrP sp = (AddrP)node->value;
if(!sp && node == fnode)
{
NodePM q;
q = node->fptr[0];
DELETENODE(SIZEH)
node = q;
goto trynext;
}
if(!sp)
{/* no available space at this size */
node = node->fptr[0];
goto trynext;
}
/* extract some space from this block */
remainder = node->key - size;
address = (void*)sp->maddr->key;
sp->maddr->key += size;
DETACH(sp);
if(node->value == 0)
{/* no more blocks of this size, delete sizenode */
if(node != fnode)
FINDKEY(SIZEH, size)
DELETENODE(SIZEH)
}
if(remainder == 0)
{/* no remaining space,the node in freelist is exhausted, delete it */
FINDKEY(FREEH, sp->maddr->key)
DELETENODE(FREEH)
free_addr(bp, sp);
}
else
{/* space remains in block, move it to new size loc */
sp->size = remainder;
addto_sizelist(bp, sp);
}
}
else
{
address = getspace(bp, size, &remainder);
if(remainder)
addto_freelist(bp, ((char*)address)+size, remainder);
}
if(alignment)
{
unsigned diff;
if((diff = (unsigned)address & mask))
{/* move address forward */
char *naddress;
unsigned lose;
lose = alignment - diff;
naddress = (char*)address + lose;
addto_freelist(bp, address, lose);
address = (unsigned*)naddress;
}
}
if(bp->guarded)
{
*address = FRNTGUARD;
*((unsigned*)(((char*)address)+req-ALIGNMENTM)) = BACKGUARD;
}
FINDKEY(USEDH, (unsigned)address)
if(node->key == (unsigned)address) {
VCRASH("allocC:%d: bookkeeping nodes are corrupted at:0x%x\n",
category, address);
}
SETLEVEL(USEDH)
node = new_Mnode(bp, level, USEDH);
node->key = (unsigned)address;
node->value = req;
INSERT()
return address+bp->addrbump;
}
void*
callocC(int category, unsigned cnt, unsigned elem_size)
{
unsigned size = cnt * elem_size;
void* buf;;
if((buf = mallocC(category, size)))
bzero(buf, size);
return buf;
};
void
freeC(int category, void* addr)
{
unsigned cursize;
unsigned *address;
struct _bins *bp;
SKIPVARS;
if(addr)
{
if(!(bp = getcat(category))) {
VCRASH("freeC:%d: non-existant category at:0x%x\n",category,addr);
}
HEAPCHECK
address = (void*) ((unsigned*)addr - bp->addrbump);
FINDKEY(USEDH, (unsigned)address)
if(node->key != (unsigned)address) {
VCRASH("freeC:%d: bogus address=0x%x\n", category, addr);
}
cursize = node->value;
CHECKGUARDS(freeC)
DELETENODE(USEDH)
addto_freelist(bp, address, cursize);
}
else VCRASH("freeC:%d: null pointer\n", category);
}
void*
reallocC(int category, void* addr, unsigned newsize)
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -