1
0
Files
irix-657m-src/irix/cmd/icrash_old/include/alloc.h
2022-09-29 17:59:04 +03:00

174 lines
6.3 KiB
C

#ident "$Header: /proj/irix6.5.7m/isms/irix/cmd/icrash_old/include/RCS/alloc.h,v 1.1 1999/05/25 19:19:20 tjm Exp $"
#ifndef ALLOC_H
#define ALLOC_H
#endif
/* Block Memory Allocator
* ----------------------
*
* Blocks of memory are allocated from an array of buckets. Requests
* for blocks of memory larger than one page are allocated in
* full-page increments -- to the next largest page. Such blocks are
* not allocated from a bucket. Instead, they are are malloced
* directly from the system. The last bucket in buckt table controls
* these oversize blocks while they are active. Oversized blocks may
* be freed back to the system when they are no longer needed, or
* they can be left linked into the pagelist of the last bucket (yet
* to be implemented). Note that with oversized blocks, a "page"
* consists of more than one page (IO_NBPC) of memory.
*
* Free blocks (for each page) are are linked together using a block
* header structure. For blocks on a page's freelist, the beginning
* portion of the block is used as a header (to link the blocks on
* the freelist). For blocks that are allocated on a temporary basis
* (B_TEMP), a block header is obtained from the mempool.blkhdrs
* freelist and placed on a doubly linked list (temp_blks). This
* allows us to free all temporary blocks in the event of a
* longjmp() (that occurs when Ctrl-C is pressed). Perminent blocks
* are not linked together in any way. We COULD walk the currently
* active pages and determine exactly which blocks are allocated if
* we wanted to, but we wouldn't be able to determine who owns the
* blocks. To do this would require too much memory for the
* aditional block header structs.
*/
/* Block header
*/
typedef struct block_s {
struct block_s *next; /* next block on list */
struct block_s *prev; /* previous block on list */
caddr_t *addr; /* pointer to block of memory */
#ifdef ICRASH_DEBUG
int flag; /* flag indicating state of block */
struct page_s *page; /* pointer to page block is part of */
caddr_t *alloc_pc; /* program counter of calling function */
#endif
} block_t;
/* Page header
*/
typedef struct page_s {
struct page_s *next; /* pointer to next page */
struct page_s *prev; /* pointer to previous page */
caddr_t *addr; /* start address of page */
block_t *blklist; /* linked list of free blocks from this page */
unsigned blksz; /* size of blocks page is broken up into */
unsigned short nblocks; /* number of blocks per page */
unsigned short nfree; /* number of size blocks free on this page */
unsigned short state; /* current state of this page (see below) */
unsigned short index; /* index of bucket page is allocated to */
struct page_s *hash; /* has table forward pointer */
} page_t;
/* Values for state field
*/
#define P_FREE 0 /* Page header on freelist -- no page allocated */
#define P_AVAIL 1 /* Page allocated, currently in memory pool */
#define P_INUSE 2 /* Page in use (on bucket pagelist) */
#define P_OVRSZ 3 /* Memory not from memory pool (oversized block) */
/* Memory allocation stats
*/
typedef struct stat_s {
unsigned alloc; /* total allocations */
unsigned free; /* total frees */
unsigned high; /* high water mark -- max allocated at one time */
} stat_t;
/* Memory bucket
*/
typedef struct bucket_s {
page_t *pagelist; /* linked list of pages */
int blksize; /* size of each block in this bucket */
int npages; /* Number of pages allocated to this bucket */
int nblks; /* total blocks allocated for this bucket */
int freeblks; /* number of free blocks in bucket */
stat_t stats; /* memory allocation stats for bucket */
} bucket_t;
#define s_alloc stats.alloc
#define s_free stats.free
#define s_high stats.high
/* Memory pool
*
* Available memory pages are held in the mempool structure. In
* adition to the linked list of free pages, the mempool struct also
* contains statistical information on page memory utilization.
*/
typedef struct mempool_s {
page_t *pgs; /* linked list of available pages */
page_t *ovrszpgs; /* linked list of oversized blocks */
int npgs; /* Total number of pages allocated */
int free_pgs; /* number of free pages */
stat_t stats; /* page utalization stats */
page_t *pghdrs; /* list of available page headers */
int npghdrs; /* number of page headers allocated */
int free_pghdrs; /* number of available page headers */
block_t *blkhdrs; /* free block headers */
int nblkhdrs; /* number of block headers allocated */
int free_blkhdrs; /* number of available block headers */
} mempool_t;
#define m_alloc stats.alloc
#define m_free stats.free
#define m_high stats.high
/* Defines for controlling allocation of page/block resources
*/
#define PAGE_INIT 10 /* number of pages to allocate at startup */
#define PAGE_ALLOC 1 /* number of pages to allocate when low */
#define PGHDR_INIT 20 /* number of page headers to allocate at startup */
#define PGHDR_ALLOC 10 /* number of page headers to allocate when low */
#define BLKHDR_INIT 32 /* number of block headers to allocate at startup */
#define BLKHDR_ALLOC 16 /* number of block headers to allocate when low */
/* Defines that relate to the page hash table
*/
#define PHASHSIZE 32
#define PHASH(X) (&phash[((X)>>12)%PHASHSIZE])
#define NBUCKETS 11
#define OVRSZBKT (NBUCKETS - 1)
/* External variables
*/
extern page_t *phash[];
extern bucket_t bucket[];
extern mempool_t mempool;
extern block_t *temp_blks; /* List of block headers for B_TEMP blocks */
extern int bucket_size[];
#ifdef ICRASH_DEBUG
extern block_t *perm_blks;
#endif
/* cmds/cmd_block.c
*/
void block_banner(FILE *, int);
int block_print(block_t *, int, FILE *);
int block_cmd(command_t);
int block_parse(command_t);
void block_usage(command_t);
/* cmds/cmd_bucket.c
*/
void bucket_banner(FILE *, int);
void bucket_print(int, bucket_t *, int, FILE *);
int bucket_cmd(command_t);
int bucket_parse(command_t);
void bucket_usage(command_t);
/* cmds/cmd_mempool.c
*/
int mempool_cmd(command_t);
int mempool_parse(command_t);
void mempool_help(command_t);
void mempool_usage(command_t);
/* cmds/cmd_page.c
*/
void page_banner(FILE *, int);
int page_print(page_t *, int, FILE *);
int page_cmd(command_t);
int page_parse(command_t);
void page_help(command_t);
void page_usage(command_t);