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

📄 bget.c

📁 COS 0.0.1.rar Cos操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    b = BFH(((char *) buf) - sizeof(struct bhead));#ifdef BufStats    numrel++;			      /* Increment number of brel() calls */#endif    assert(buf != NULL);#ifdef BECtl    if (b->bh.bsize == 0) {	      /* Directly-acquired buffer? */	struct bdhead *bdh;	bdh = BDH(((char *) buf) - sizeof(struct bdhead));	assert(b->bh.prevfree == 0);#ifdef BufStats	totalloc -= bdh->tsize;	assert(totalloc >= 0);	numdrel++;		      /* Number of direct releases */#endif /* BufStats */#ifdef FreeWipe	V memset((char *) buf, 0x55,		 (MemSize) (bdh->tsize - sizeof(struct bdhead)));#endif /* FreeWipe */	assert(relfcn != NULL);	(*relfcn)((void *) bdh);      /* Release it directly. */	return;    }#endif /* BECtl */    /* Buffer size must be negative, indicating that the buffer is       allocated. */    if (b->bh.bsize >= 0) {	bn = NULL;    }    assert(b->bh.bsize < 0);    /*	Back pointer in next buffer must be zero, indicating the	same thing: */    assert(BH((char *) b - b->bh.bsize)->prevfree == 0);#ifdef BufStats    totalloc += b->bh.bsize;    assert(totalloc >= 0);#endif    /* If the back link is nonzero, the previous buffer is free.  */    if (b->bh.prevfree != 0) {	/* The previous buffer is free.  Consolidate this buffer  with	it	   by  adding  the  length  of	this  buffer  to the previous free	   buffer.  Note that we subtract the size  in	the  buffer  being           released,  since  it's  negative to indicate that the buffer is	   allocated. */	register bufsize size = b->bh.bsize;        /* Make the previous buffer the one we're working on. */	assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree);	b = BFH(((char *) b) - b->bh.prevfree);	b->bh.bsize -= size;    } else {        /* The previous buffer isn't allocated.  Insert this buffer	   on the free list as an isolated free block. */	assert(freelist.ql.blink->ql.flink == &freelist);	assert(freelist.ql.flink->ql.blink == &freelist);	b->ql.flink = &freelist;	b->ql.blink = freelist.ql.blink;	freelist.ql.blink = b;	b->ql.blink->ql.flink = b;	b->bh.bsize = -b->bh.bsize;    }    /* Now we look at the next buffer in memory, located by advancing from       the  start  of  this  buffer  by its size, to see if that buffer is       free.  If it is, we combine  this  buffer  with	the  next  one	in       memory, dechaining the second buffer from the free list. */    bn =  BFH(((char *) b) + b->bh.bsize);    if (bn->bh.bsize > 0) {	/* The buffer is free.	Remove it from the free list and add	   its size to that of our buffer. */	assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize);	assert(bn->ql.blink->ql.flink == bn);	assert(bn->ql.flink->ql.blink == bn);	bn->ql.blink->ql.flink = bn->ql.flink;	bn->ql.flink->ql.blink = bn->ql.blink;	b->bh.bsize += bn->bh.bsize;	/* Finally,  advance  to   the	buffer	that   follows	the  newly	   consolidated free block.  We must set its  backpointer  to  the	   head  of  the  consolidated free block.  We know the next block	   must be an allocated block because the process of recombination	   guarantees  that  two  free	blocks will never be contiguous in	   memory.  */	bn = BFH(((char *) b) + b->bh.bsize);    }#ifdef FreeWipe    V memset(((char *) b) + sizeof(struct bfhead), 0x55,	    (MemSize) (b->bh.bsize - sizeof(struct bfhead)));#endif    assert(bn->bh.bsize < 0);    /* The next buffer is allocated.  Set the backpointer in it  to  point       to this buffer; the previous free buffer in memory. */    bn->bh.prevfree = b->bh.bsize;#ifdef BECtl    /*	If  a  block-release function is defined, and this free buffer	constitutes the entire block, release it.  Note that  pool_len	is  defined  in  such a way that the test will fail unless all	pool blocks are the same size.	*/    if (relfcn != NULL &&	((bufsize) b->bh.bsize) == (pool_len - sizeof(struct bhead))) {	assert(b->bh.prevfree == 0);	assert(BH((char *) b + b->bh.bsize)->bsize == ESent);	assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);	/*  Unlink the buffer from the free list  */	b->ql.blink->ql.flink = b->ql.flink;	b->ql.flink->ql.blink = b->ql.blink;	(*relfcn)(b);#ifdef BufStats	numprel++;		      /* Nr of expansion block releases */	numpblk--;		      /* Total number of blocks */	assert(numpblk == numpget - numprel);#endif /* BufStats */    }#endif /* BECtl */}#ifdef BECtl/*  BECTL  --  Establish automatic pool expansion control  */void bectl(compact, acquire, release, pool_incr)  int (*compact) (bufsize sizereq, int sequence);  void *(*acquire) (bufsize size);  void (*release) (void *buf);  bufsize pool_incr;{    compfcn = compact;    acqfcn = acquire;    relfcn = release;    exp_incr = pool_incr;}#endif/*  BPOOL  --  Add a region of memory to the buffer pool.  */void bpool(buf, len)  void *buf;  bufsize len;{    struct bfhead *b = BFH(buf);    struct bhead *bn;#ifdef SizeQuant    len &= ~(SizeQuant - 1);#endif#ifdef BECtl    if (pool_len == 0) {	pool_len = len;    } else if (len != pool_len) {	pool_len = -1;    }#ifdef BufStats    numpget++;			      /* Number of block acquisitions */    numpblk++;			      /* Number of blocks total */    assert(numpblk == numpget - numprel);#endif /* BufStats */#endif /* BECtl */    /* Since the block is initially occupied by a single free  buffer,       it  had	better	not  be  (much) larger than the largest buffer       whose size we can store in bhead.bsize. */    assert(len - sizeof(struct bhead) <= -((bufsize) ESent + 1));    /* Clear  the  backpointer at  the start of the block to indicate that       there  is  no  free  block  prior  to  this   one.    That   blocks       recombination when the first block in memory is released. */    b->bh.prevfree = 0;    /* Chain the new block to the free list. */    assert(freelist.ql.blink->ql.flink == &freelist);    assert(freelist.ql.flink->ql.blink == &freelist);    b->ql.flink = &freelist;    b->ql.blink = freelist.ql.blink;    freelist.ql.blink = b;    b->ql.blink->ql.flink = b;    /* Create a dummy allocated buffer at the end of the pool.	This dummy       buffer is seen when a buffer at the end of the pool is released and       blocks  recombination  of  the last buffer with the dummy buffer at       the end.  The length in the dummy buffer  is  set  to  the  largest       negative  number  to  denote  the  end  of  the pool for diagnostic       routines (this specific value is  not  counted  on  by  the  actual       allocation and release functions). */    len -= sizeof(struct bhead);    b->bh.bsize = (bufsize) len;#ifdef FreeWipe    V memset(((char *) b) + sizeof(struct bfhead), 0x55,	     (MemSize) (len - sizeof(struct bfhead)));#endif    bn = BH(((char *) b) + len);    bn->prevfree = (bufsize) len;    /* Definition of ESent assumes two's complement! */    assert((~0) == -1);    bn->bsize = ESent;}#ifdef BufStats/*  BSTATS  --	Return buffer allocation free space statistics.  */void bstats(curalloc, totfree, maxfree, nget, nrel)  bufsize *curalloc, *totfree, *maxfree;  long *nget, *nrel;{    struct bfhead *b = freelist.ql.flink;    *nget = numget;    *nrel = numrel;    *curalloc = totalloc;    *totfree = 0;    *maxfree = -1;    while (b != &freelist) {	assert(b->bh.bsize > 0);	*totfree += b->bh.bsize;	if (b->bh.bsize > *maxfree) {	    *maxfree = b->bh.bsize;	}	b = b->ql.flink;	      /* Link to next buffer */    }}#ifdef BECtl/*  BSTATSE  --  Return extended statistics  */void bstatse(pool_incr, npool, npget, nprel, ndget, ndrel)  bufsize *pool_incr;  long *npool, *npget, *nprel, *ndget, *ndrel;{    *pool_incr = (pool_len < 0) ? -exp_incr : exp_incr;    *npool = numpblk;    *npget = numpget;    *nprel = numprel;    *ndget = numdget;    *ndrel = numdrel;}#endif /* BECtl */#endif /* BufStats */#ifdef DumpData/*  BUFDUMP  --  Dump the data in a buffer.  This is called with the  user		 data pointer, and backs up to the buffer header.  It will		 dump either a free block or an allocated one.	*/void bufdump(buf)  void *buf;{    struct bfhead *b;    unsigned char *bdump;    bufsize bdlen;    b = BFH(((char *) buf) - sizeof(struct bhead));    assert(b->bh.bsize != 0);    if (b->bh.bsize < 0) {	bdump = (unsigned char *) buf;	bdlen = (-b->bh.bsize) - sizeof(struct bhead);    } else {	bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));	bdlen = b->bh.bsize - sizeof(struct bfhead);    }    while (bdlen > 0) {	int i, dupes = 0;	bufsize l = bdlen;	char bhex[50], bascii[20];	if (l > 16) {	    l = 16;	}	for (i = 0; i < l; i++) {            V sprintf(bhex + i * 3, "%02X ", bdump[i]);            bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';	}	bascii[i] = 0;        V printf("%-48s   %s\n", bhex, bascii);	bdump += l;	bdlen -= l;	while ((bdlen > 16) && (memcmp((char *) (bdump - 16),				       (char *) bdump, 16) == 0)) {	    dupes++;	    bdump += 16;	    bdlen -= 16;	}	if (dupes > 1) {	    V printf(                "     (%d lines [%d bytes] identical to above line skipped)\n",		dupes, dupes * 16);	} else if (dupes == 1) {	    bdump -= 16;	    bdlen += 16;	}    }}#endif#ifdef BufDump/*  BPOOLD  --	Dump a buffer pool.  The buffer headers are always listed.		If DUMPALLOC is nonzero, the contents of allocated buffers		are  dumped.   If  DUMPFREE  is  nonzero,  free blocks are		dumped as well.  If FreeWipe  checking	is  enabled,  free		blocks	which  have  been clobbered will always be dumped. */void bpoold(buf, dumpalloc, dumpfree)  void *buf;  int dumpalloc, dumpfree;{    struct bfhead *b = BFH(buf);    while (b->bh.bsize != ESent) {	bufsize bs = b->bh.bsize;	if (bs < 0) {	    bs = -bs;            V printf("Allocated buffer: size %6ld bytes.\n", (long) bs);	    if (dumpalloc) {		bufdump((void *) (((char *) b) + sizeof(struct bhead)));	    }	} else {            char *lerr = "";	    assert(bs > 0);	    if ((b->ql.blink->ql.flink != b) ||		(b->ql.flink->ql.blink != b)) {                lerr = "  (Bad free list links)";	    }            V printf("Free block:       size %6ld bytes.%s\n",		(long) bs, lerr);#ifdef FreeWipe	    lerr = ((char *) b) + sizeof(struct bfhead);	    if ((bs > sizeof(struct bfhead)) && ((*lerr != 0x55) ||		(memcmp(lerr, lerr + 1,		  (MemSize) (bs - (sizeof(struct bfhead) + 1))) != 0))) {		V printf(                    "(Contents of above free block have been overstored.)\n");		bufdump((void *) (((char *) b) + sizeof(struct bhead)));	    } else#endif	    if (dumpfree) {		bufdump((void *) (((char *) b) + sizeof(struct bhead)));	    }	}	b = BFH(((char *) b) + bs);    }}#endif /* BufDump */#ifdef BufValid/*  BPOOLV  --  Validate a buffer pool.  If NDEBUG isn't defined,		any error generates an assertion failure.  */int bpoolv(buf)  void *buf;{    struct bfhead *b = BFH(buf);    while (b->bh.bsize != ESent) {	bufsize bs = b->bh.bsize;	if (bs < 0) {	    bs = -bs;	} else {            char *lerr = "";	    assert(bs > 0);	    if (bs <= 0) {		return 0;	    }	    if ((b->ql.blink->ql.flink != b) ||		(b->ql.flink->ql.blink != b)) {                V printf("Free block: size %6ld bytes.  (Bad free list links)\n",		     (long) bs);		assert(0);		return 0;	    }#ifdef FreeWipe	    lerr = ((char *) b) + sizeof(struct bfhead);	    if ((bs > sizeof(struct bfhead)) && ((*lerr != 0x55) ||		(memcmp(lerr, lerr + 1,		  (MemSize) (bs - (sizeof(struct bfhead) + 1))) != 0))) {		V printf(                    "(Contents of above free block have been overstored.)\n");		bufdump((void *) (((char *) b) + sizeof(struct bhead)));		assert(0);		return 0;	    }#endif	}	b = BFH(((char *) b) + bs);    }    return 1;}#endif /* BufValid */ // Test program removed

⌨️ 快捷键说明

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