?? skeleton.c
字號:
SKIPVARS;
unsigned cursize;
unsigned *address;
struct _bins *bp;
NodePM onode;
if(addr == 0)
return mallocC(category, newsize);
else
{
if(!(bp = getcat(category))) {
VCRASH("reallocC:%d: non-existant category at:%x\n",category,addr);
}
HEAPCHECK
if(newsize == 0)
newsize = ALIGNMENTM;
else
newsize += ROUNDINGM(newsize);
newsize += bp->guarded;
address = (void*)(((char*)addr)-(bp->guarded/2));
FINDKEY(USEDH, (unsigned)address)
if(node->key != (unsigned)address) {
VCRASH("reallocC:%d: bogus address=0x%x\n", category, addr);
}
cursize = node->value;
node->value = newsize;
onode = node;
CHECKGUARDS(reallocC)
if(newsize == cursize)
return addr;
if(newsize > cursize)
{/* check if block can be extended */
void *taddr = ((char*)address) + cursize;
unsigned extendsize = newsize-cursize;
/* check freelist for an available block at the right address */
FINDKEY(FREEH, (unsigned)taddr)
if(node->key == (unsigned)taddr)
{
AddrP sp = (AddrP)node->value;
if(sp->size >= extendsize)
{/* BLOCK CAN BE EXTENDED INTERNALLY */
node->key += extendsize;
sp->size -= extendsize;
DETACH(sp)
if(sp->size == 0)
{/* the extension block is used up, delete this node */
free_addr(bp, sp);
DELETENODE(FREEH)
}
else
{/* shift the remainder in the sizelist */
addto_sizelist(bp, sp);
}
/* SUCCESS */
if(bp->guarded)
{
*((unsigned*)(((char*)address)+newsize-ALIGNMENTM))
= BACKGUARD;
}
return addr;
}
}
/* HERE WE COULD CHECK OTHER SOURCES OF SPACE */
/* can't extend block, malloc some new space */
if((taddr = mallocC(category,newsize-bp->guarded)))
{
memmove(taddr,addr,cursize-bp->guarded);
onode->value = cursize;
freeC(category, addr);
}
/* SUCCESS */
return taddr;
}
else
{/* shrink block */
if(bp->guarded)
{
*((unsigned*)(((char*)address)+newsize-ALIGNMENTM))
= BACKGUARD;
}
addto_freelist(bp, ((char*)address)+newsize, cursize-newsize);
return addr;
}
}
}
void
freecat(int category)
{
struct _bins *bp;
if(category == 0)
return;
if((bp = getcat(category)))
{
struct _catlocs *cl = bp->catlocs;
struct _bins *hbp;
struct _bins *prev;
while(cl)
{/* Space allocated to the category is moved to category 0 */
void *ql = cl->fptr;
freeC(0, cl->addr);
free_catloc(cl);
cl = ql;
}
/* space for the _bins struct is placed on a free list */
hbp = hmap[category % 1009];
prev = 0;
while(hbp)
{
if(hbp->bincat == category)
{
if(prev == 0)
hmap[category % 1009] = hbp->fptr;
else
prev->fptr = hbp->fptr;
free_bins(hbp);
return;
}
prev = hbp;
hbp = hbp->fptr;
}
}
}
int
memrangeC(int category, unsigned *min, unsigned *max)
{
struct _bins *bp;
if((bp = getcat(category)))
{
*min = bp->minloc;
*max = bp->maxloc;
return 1;
}
return 0;
}
int
usedrangeC(int category, unsigned *min, unsigned *max)
{
struct _bins *bp;
NodePM node;
int level;
if((bp = getcat(category)))
{
node = bp->USEDHheader;
*min = node->fptr[0]->key;
for(level = bp->USEDHlevel; level >= 0; level--)
while(node->fptr[level]->key < 0xffffffff)
node = node->fptr[level];
*max = node->key;
return 1;
}
return 0;
}
void
totrangeC(unsigned *min, unsigned *max)
{
*min = minloc;
*max = maxloc;
}
void
guardC(int category)
{
struct _bins *bp;
if(!(bp = getcat(category)))
if(!(bp = initcat(category)))
return;
if(!bp->guarded)
{
bp->guarded = 2*ALIGNMENTM;
bp->addrbump = 1;
}
}
void*
heapcheckC(int category, void *start)
{
struct _bins *bp;
NodePM node,prev;
unsigned *p1,*p2;
if((bp = getcat(category)))
{
if(bp->guarded)
{
prev = 0;
node = bp->USEDHheader;
while( (node = node->fptr[0]) != (NodePM)0xffffffff
&& node->key != 0xffffffffUL)
{
if((void*)node->key > start)
{
p1 = (unsigned*)node->key;
if(*p1 != FRNTGUARD)
{
if(prev)
return (char*)prev->key+ALIGNMENTM;
else
return (void*)1;
}
p2 = (unsigned*)(((char*)p1)+node->value-ALIGNMENTM);
if(*p2 != BACKGUARD)
return (char*)node->key+ALIGNMENTM;
}
prev = node;
}
}
}
return 0;
}
void*
mallocC(int category, unsigned size)
{
return memalignC(category, 0, size);
}
void*
vallocC(int category, unsigned bytes)
{
return memalignC (category, PAGESIZE, bytes);
}
unsigned
mallocsizeC(int category, void* addr)
{
struct _bins *bp;
SKIPVARS;
if(addr && (bp = getcat(category)))
{
unsigned address = (unsigned)((unsigned*)addr - bp->addrbump);
FINDKEY(USEDH, address)
if(node->key == address)
return node->value - bp->guarded;
}
return 0;
}
int
NewMallocCategory(void)
{
static unsigned int cat = BASE_CATEGORY;
return ++cat;
}
/* ====================== END MULTI-HEAP MALLOC ============================ */
/* These are here to prevent the system malloc from being linked */
void *
malloc(unsigned a)
{
void *result = mallocC(BASE_CATEGORY, a);
MPRINTF("malloc %d bytes at %p caller=%x\n", a, result, ((unsigned *)&a)[-1]);
return result;
}
void
free(void *a)
{
MPRINTF("free at %p caller=%x\n", a, ((unsigned*)&a)[-1]);
freeC(BASE_CATEGORY,a);
}
void *
realloc(void *a, unsigned b)
{
void *result = reallocC(BASE_CATEGORY,a,b);
MPRINTF("realloc %d bytes at %p old=%p caller=%x\n",
b, result, a, ((unsigned*)&a)[-1]);
return result;
}
void *
calloc(unsigned a, unsigned b)
{
void *result = callocC(BASE_CATEGORY,a,b);
MPRINTF("calloc %d bytes at %p caller=%x\n", a*b, result, ((unsigned*)&a)[-1]);
return result;
}
void *
valloc(unsigned a)
{
void *result = vallocC(BASE_CATEGORY,a);
MPRINTF("valloc %d bytes at %p caller=%x\n", a, result, ((unsigned *)&a)[-1]);
return result;
}
void *
memalign(unsigned a, unsigned b)
{
void *result = memalignC(BASE_CATEGORY,a,b);
MPRINTF("memalign(%u) %u bytes at %p caller=%x\n",
a,b,result,((unsigned *)&a)[-1]);
return result;
}
unsigned
mallocsize(void *a)
{
return mallocsizeC(BASE_CATEGORY, a);
}
static int
lnulfunc()
{
return 0;
}
static void
lhash(void *keyptr, int cnt, CAT *cat)
{/* THIS FUNCTION IS IDENTICAL TO 'key_hash' in CFF */
STOR value;
int i;
cat->c0.item = 0;
if(cnt <= 8)
for (i = 0; i < cnt; ++i)
cat->c0.a5.b[i] = *((unsigned char *)keyptr)++;
else
for (i = 0; i < cnt; ++i)
cat->c0.a5.b[i&7] ^= *((unsigned char *)keyptr)++;
/* THE CONSTANTS WERE CAREFULLY CHOSEN BY THEORY */
/* value.item is a long long (use gcc only) */
value.item = ((1103515245LL)*(cat->c0.a4.s0 ^ cat->c0.a4.s1))+453816693LL;
if(value.a0 == 0) value.a0 = 1;
value.a0 &= 0x0fffffff;
if(cnt <= 8) value.a0 |= 0x80000000; /* exact key chunk */
cat->c1.a0 = value.a0;
}
static int linkup_complete;
static int
laccess(char *a, int b)
{/* suppress use of 'access', it links in too many other functions */
if(linkup_complete)
return ((VOBTYPE(a) & (OB_XFILE|OB_TREEDIR|OB_HASHDIR)) ? 0 : 1);
else {
int fd = VOPEN(a,O_RDONLY|O_BINARY);
if(fd > 0)
{
VCLOSE(fd);
return 0;
}
return 1;
}
}
static int
lpagesize()
{
return 4096;
}
static int
lprintchar(int c)
{
return VWRITE(1,&c,1);
}
static void
lprintstr(char *str)
{
while(*str)
lprintchar(*str++);
}
#if EARLY_PRINT == 1
struct parameters
{
int number_of_output_chars;
int (*output_function)(void *, int);
void *output_pointer;
short minimum_field_width;
short edited_string_length;
short leading_zeros;
char options;
#define MINUS_SIGN 1
#define RIGHT_JUSTIFY 2
#define ZERO_PAD 4
#define CAPITAL_HEX 8
};
static void output_and_count(struct parameters *p, int c)
{
if (p->number_of_output_chars >= 0)
{
int n = (*p->output_function)(p->output_pointer, c);
if (n>=0) p->number_of_output_chars++;
else p->number_of_output_chars = n;
}
}
static void output_field(struct parameters *p, char *s)
{
short justification_length =
p->minimum_field_width - p->leading_zeros - p->edited_string_length;
if (p->options & MINUS_SIGN)
{
if (p->options & ZERO_PAD)
output_and_count(p, '-');
justification_length--;
}
if (p->options & RIGHT_JUSTIFY)
while (--justification_length >= 0)
output_and_count(p, p->options & ZERO_PAD ? '0' : ' ');
if (p->options & MINUS_SIGN && !(p->options & ZERO_PAD))
output_and_count(p, '-');
while (--p->leading_zeros >= 0)
output_and_count(p, '0');
while (--p->edited_string_length >= 0)
output_and_count(p, *s++);
while (--justification_length >= 0)
output_and_count(p, ' ');
}
static int
gprintf(int (*output_function)(void *, int), void *output_pointer,
char *control_string, int *argument_pointer)
{
struct parameters p;
char control_char;
p.number_of_output_chars = 0;
p.output_function = output_function;
p.output_pointer = output_pointer;
control_char = *control_string++;
while (control_char != '\0')
{
if (control_char == '%')
{
short precision = -1;
short long_argument = 0;
short base = 0;
control_char = *control_string++;
p.minimum_field_width = 0;
p.leading_zeros = 0;
p.options = RIGHT_JUSTIFY;
if (control_char == '-')
{
p.options = 0;
control_char = *control_string++;
}
if (control_char == '0')
{
p.options |= ZERO_PAD;
control_char = *control_string++;
}
if (control_char == '*')
{
p.minimum_field_width = *argument_pointer++;
control_char = *control_string++;
}
else
{
while ('0' <= control_char && control_char <= '9')
{
p.minimum_field_width =
p.minimum_field_width * 10 + control_char - '0';
control_char = *control_string++;
}
}
if (control_char == '.')
{
control_char = *control_string++;
if (control_char == '*')
{
precision = *argument_pointer++;
control_char = *control_string++;
}
else
{
precision = 0;
while ('0' <= control_char && control_char <= '9')
{
precision = precision * 10 + control_char - '0';
control_char = *control_string++;
}
}
}
if (control_char == 'l')
{
long_argument = 1;
control_char = *control_string++;
}
if (control_char == 'd')
base = 10;
else if (control_char == 'x' || control_char == 'p')
base = 16;
else if (control_char == 'X')
{
base = 16;
p.options |= CAPITAL_HEX;
}
else if (control_char == 'u')
base = 10;
else if (control_char == 'o')
base = 8;
else if (control_char == 'b')
base = 2;
else if (control_char == 'c')
{
base = -1;
p.options &= ~ZERO_PAD;
}
else if (control_char == 's')
{
base = -2;
p.options &= ~ZERO_PAD;
}
if (base == 0) /* invalid conversion type */
{
if (control_char != '\0')
{
output_and_count(&p, control_char);
control_char = *control_string++;
}
}
else
{
if (base == -1) /* conversion type c */
{
char c = *argument_pointer++;
p.edited_string_length = 1;
output_field(&p, &c);
}
else if (base == -2) /* conversion type s */
{
char *string;
p.edited_string_length = 0;
string = * (char **) argument_pointer;
argument_pointer += sizeof(char *) / sizeof(int);
while (string[p.edited_string_length] != 0)
p.edited_string_length++;
if (precision >= 0 && p.edited_string_length > precision)
p.edited_string_length = precision;
output_field(&p, string);
}
else /* conversion type d, b, o or x */
{
unsigned long x;
char buffer[64];
p.edited_string_length = 0;
if (long_argument)
{
x = * (unsigned long *) argument_pointer;
argument_pointer += sizeof(unsigned long) / sizeof(int);
}
else if (control_char == 'd')
x = (long) *argument_pointer++;
else
x = (unsigned) *argument_pointer++;
if (control_char == 'd' && (long) x < 0)
{
p.options |= MINUS_SIGN;
x = - (long) x;
}
do
{
int c;
c = x % base + '0';
if (c > '9')
{
if (p.options & CAPITAL_HEX)
c += 'A'-'9'-1;
else
c += 'a'-'9'-1;
}
buffer[sizeof(buffer) - 1 - p.edited_string_length++] = c;
}
while ((x/=base) != 0);
if (precision >= 0 && precision > p.edited_string_length)
p.leading_zeros = precision - p.edited_string_length;
output_field(&p, buffer + sizeof(buffer) - p.edited_string_length);
}
control_char = *control_string++;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -