1
0
Files
irix-657m-src/eoe/lib/libmalloc/mallint.h
2022-09-29 17:59:04 +03:00

257 lines
8.3 KiB
C

/**************************************************************************
* *
* Copyright (C) 1989-1994 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef __MALLINT_H__
#define __MALLINT_H__
#ident "$Revision: 1.14 $ $Author: jwag $"
#include "ulocks.h"
/* template for the header */
struct header {
struct header *nextblk;
struct header *prevblk;
struct header *nextfree;
struct header *prevfree;
};
/*
template for a small block
*/
struct lblk {
union {
struct lblk *nextfree; /* the next free little block in this
holding block. This field is used
when the block is free */
struct holdblk *holder; /* the holding block containing this
little block. This field is used
when the block is allocated */
} header;
char byte; /* There is no telling how big this
field freally is. */
};
#define MINSMALLHEAD ((int)sizeof(struct lblk *))
/*
template for holding block
*/
struct holdblk {
struct holdblk *nexthblk; /* next holding block */
struct holdblk *prevhblk; /* previous holding block */
struct lblk *lfreeq; /* head of free queue within block */
struct lblk *unused; /* pointer to 1st little block never used */
int blksz; /* size of little blocks contained */
int holdsz; /* useful holdblk constant */
char head[MINSMALLHEAD];/* maybe header for first small block
* in hold group (depends on alignment) */
};
/*
The following manipulate the free queue
DELFREEQ will remove x from the free queue
ADDFREEQ will add an element to the head
or tail of the free queue.
MOVEHEAD will move the free pointers so that
x is at the front of the queue
COMPACTFWD - if 'n' is free, compact with 'b'
'b's nextblk must already have been CLRBUSY
COMPACTBACK - if 'b's predecessor is free coalesce
note that 'b' is changed to point to new block
*/
#define ADDFREEQ(fptr,x) if (AP(addtotail)) addtail(fptr,x); \
else addhead(fptr,x);
#define DELFREEQ(x) (x)->prevfree->nextfree = (x)->nextfree;\
(x)->nextfree->prevfree = (x)->prevfree;\
(x)->prevfree = (x)->nextfree = 0; \
assert((x)->nextfree != (x));\
assert((x)->prevfree != (x));
#define MOVEHEAD(x) AP(freeptr)[1].prevfree->nextfree = \
AP(freeptr)[0].nextfree;\
AP(freeptr)[0].nextfree->prevfree = \
AP(freeptr)[1].prevfree;\
(x)->prevfree->nextfree = &(AP(freeptr)[1]);\
AP(freeptr)[1].prevfree = (x)->prevfree;\
(x)->prevfree = &(AP(freeptr)[0]);\
AP(freeptr)[0].nextfree = (x);\
assert((x)->nextfree != (x));\
assert((x)->prevfree != (x));
#define COMPACTFWD(b,n) { \
register struct header *nextnext; \
if (!TESTBUSY(nextnext = (n)->nextblk)) { \
DELFREEQ(n); \
(b)->nextblk = nextnext; \
nextnext->prevblk = (b); \
} \
}
#define COMPACTBACK(b) { \
register struct header *next; \
if (!TESTBUSY((next = (b)->prevblk)->nextblk)) { \
DELFREEQ(next); \
next->nextblk = (b)->nextblk; \
(b)->nextblk->prevblk = next; \
(b) = next; \
} \
}
#ifndef MAX
#define MAX(a,b) (a > b ? a : b)
#endif
#define ALIGNIT(x) (((__psint_t)(x) + ALIGNSZ - 1) & ~(ALIGNSZ - 1))
#define ISALIGNED(x) (((__psint_t)(x) & (ALIGNSZ - 1)) == 0)
/*
* Determine minimum size of regular block that should be
* put on free list. Blocks smaller than this, but large
* enough to accomodate a header, are put on the ignore
* free list to be (possibly) coalesced later.
*/
#define SETIGNSZ AP(ignoresz) = (int)ALIGNIT(AP(maxfast) + 1 + AP(minhead));
/*
The following manipulate the busy flag
*/
#define BUSY 1L
#define SETBUSY(x) ((struct header *)((__psint_t)(x) | BUSY))
#define CLRBUSY(x) ((struct header *)((__psint_t)(x) & ~BUSY))
#define TESTBUSY(x) ((__psint_t)(x) & BUSY)
/*
The following manipulate the small block flag
*/
#define SMAL 2L
#define SETSMAL(x) ((struct lblk *)((__psint_t)(x) | SMAL))
#define CLRSMAL(x) ((struct lblk *)((__psint_t)(x) & ~SMAL))
#define TESTSMAL(x) ((__psint_t)(x) & SMAL)
/*
The following manipulate both flags. They must be
type coerced
*/
#define SETALL(x) ((__psint_t)(x) | (SMAL | BUSY))
#define CLRALL(x) ((__psint_t)(x) & ~(SMAL | BUSY))
/*
Other useful constants
*/
#define TRUE 1
#define FALSE 0
/* number of bytes to align to (must be at least 4, because lower 2 bits
are used for flags */
#ifdef LIBMALLOC
#if (_MIPS_SZLONG == 32)
#define ALIGNSZ 8
#else
#define ALIGNSZ 16 /* 2*(sizeof(struct header *)) Min size */
#endif /* _MIPS_SZLONG */
#else
#define ALIGNSZ 16
#endif /* LIBMALLOC */
/*
* minhead is the larger of either:
* sizeof an allocated block header OR
* the alignment factor
*/
/*#define MINHEAD 8 UNUSED - sizeof allocated block header */
#define HEADSZ ((int)sizeof(struct header)) /* size of unallocated block header */
#define MINBLKSZ HEADSZ
#define BLOCKSZ (8*1024) /* memory is gotten from sbrk in
multiples of BLOCKSZ */
#define GROUND (struct header *)0
#define LGROUND (struct lblk *)0 /* ground for a queue within a holding
block */
#define HGROUND (struct holdblk *)0 /* ground for the holding block queue */
#ifndef NULL
#define NULL 0
#endif
/*
Structures and constants describing the holding blocks
*/
#define NUMLBLKS 100 /* default # of small blocks per
holding block */
/* size of a holding block with small blocks of size blksz */
#define AHOLDSZ (ALIGNIT(sizeof(struct holdblk)))
#define HOLDSZ(blksz) (AHOLDSZ + (blksz)*AP(numlblks))
#define MAXFAST 28 /* default maximum size block for fast
allocation */
/*
* Default maximum number of blocks to check
* before giving up and calling sbrk().
*/
#define MAXCHECK 100
#if (_MIPS_SZLONG == 32)
#define MAXALLOC 0x80000000 /* maximum bytes/malloc call */
#else
#define MAXALLOC 0x8000000000000000 /* maximum bytes/malloc call */
#endif
#ifdef LIBMALLOC
#define CHECKQ if (AP(m_debug)) __checkq();
#else
#define CHECKQ if (AP(m_debug)) __checkq(ap);
#endif
/*
* declaration of arena header for multiple arena malloc
*/
typedef struct arena_s {
int a_flags; /* various flags - see malloc.h */
/*
Variables controlling algorithm, esp. how holding blocs are
used
*/
int a_numlblks;
int a_minhead;
int a_change; /* != 0, once param changes are no
longer allowed */
int a_fastct;
int a_maxfast;
int a_ignoresz;
int a_blocksz;
int a_maxcheck;
int a_addtotail;
/* number of small block sizes to map to one size */
int a_grain;
struct header a_arena[2]; /* the second word is a minimal block to
start the arena. The first is a busy
block to be pointed to by the last
block. */
struct header a_freeptr[2]; /* first and last entry in free list */
struct header a_ignorefp[2]; /* first and last entry in list of
free blocks too small to consider */
struct header *a_arenaend; /* ptr to block marking high end of arena */
struct holdblk **a_holdhead; /* pointer to array of head pointers
to holding block chains */
/* In order to save time calculating indices, the array is 1 too
large, and the first element is unused */
int a_m_debug; /* whether to check arena each action */
usptr_t *a_usptr; /* pointer to header for user sync */
ulock_t a_lock; /* lock */
void *(*a_grow)(size_t, void *); /* grow function */
size_t a_size; /* max size in bytes for arena */
void *a_brk; /* brk value for adefgrow */
int a_grain2; /* if a_grain is pow2 then this is grain-1 */
int a_grain2shift; /* if a_grain is pow2 then this is shift val */
int a_clronfree; /* if set then clear block on free */
int a_clronfreevalue; /* set to this char value */
int a_padbuf[7]; /* some padding for shared lib compatibility */
} arena_t;
#endif /*__MALLINT_H__*/