|
|
1.1 ! root 1: #ifndef __KERNEL_ST_ALLOC_H__ ! 2: #define __KERNEL_ST_ALLOC_H__ ! 3: ! 4: /* ! 5: *-IMPORTS: ! 6: * <common/ccompat.h> ! 7: * __CONST__ ! 8: * __PROTO__ ! 9: * __VOID__ ! 10: * __PROTO () ! 11: * <common/xdebug.h> ! 12: * __LOCAL__ ! 13: */ ! 14: ! 15: #include <limits.h> ! 16: #include <common/ccompat.h> ! 17: #include <common/xdebug.h> ! 18: #include <common/_size.h> ! 19: ! 20: ! 21: /* ! 22: * Definitions/declarations for the quick arena manager. ! 23: * ! 24: * The quick arena manager's basic algorithm utilizes a heap (in the sense ! 25: * defined below) to implement a binary-searchable index of block buckets ! 26: * ordered by size. ! 27: * ! 28: * The primariy characteristic of this algorithm is its' speed ; the growth ! 29: * rate of the execution time is O (log W), where W is the number of words in ! 30: * the arena being managed. ! 31: * ! 32: * This implementation is directly derived from the article in which this ! 33: * algorithm first appeared; ! 34: * ! 35: * "Efficient Implementation of the First-Fit Strategy for Dynamic ! 36: * Storage Allocation" ! 37: * R. P. Brent, Australian National University ! 38: * ACM Transactions on Programming Languages and Systems ! 39: * Volume 11, No. 3, July 1989 pp 388-403. ! 40: */ ! 41: ! 42: ! 43: /* ! 44: * This source code deviates somewhat from the terminology used in the ! 45: * article, due to the large number of ambiguous terms here. The following ! 46: * definitions are used exclusively in the commentary and selection of ! 47: * identifiers within this source code : ! 48: * ! 49: * heap a balanced binary tree with implicit links, esp. ! 50: * used to perform max/min calculations or binary search ! 51: * ! 52: * arena the memory area being managed ! 53: * ! 54: * block a single unit of contiguous allocated or free memory ! 55: * ! 56: * bucket a subsection of the heap containing zero or more ! 57: * blocks ! 58: */ ! 59: ! 60: ! 61: /* ! 62: * Definition of the type of an underlying machine address for each one of ! 63: * the pointer types used in the arena control structure. ! 64: * ! 65: * An interesting question : what type should be being used for the heap ! 66: * control words, short or long? If a short is used for the size of a ! 67: * control word, then we are limited to 64k bytes for the size of a single ! 68: * allocation arena. ! 69: */ ! 70: ! 71: typedef int _ST_WORD_T; ! 72: ! 73: #if INT_MAX > SHRT_MAX ! 74: #define _ST_SIZE_MASK 0x7FFFFFFF ! 75: #define _ST_FREE_MASK 0x80000000 ! 76: #else ! 77: #define _ST_SIZE_MASK 0x7FFF ! 78: #define _ST_FREE_MASK 0x8000 ! 79: #endif ! 80: ! 81: typedef _ST_WORD_T * _ST_ADDR_T; ! 82: ! 83: #define _ST_HEAP_ADDR(q,a) (a) ! 84: #define _ST_HEAP_BUCKET(q,a) (((char *) (a) - (char *) (q)->_arena_base) / ((q)->_words_per_bucket * sizeof (_ST_WORD_T))) ! 85: ! 86: ! 87: /* ! 88: * For the control word of a block, it is *vital* that all used blocks ! 89: * compare as "<" with a free block, and that free blocks test as normal ! 90: * integers. ! 91: */ ! 92: ! 93: #define _ST_BLOCK_CONTROL(q,a) (* _ST_HEAP_ADDR (q, (a))) ! 94: #define _ST_BLOCK_SIZE(c) ((c) & _ST_SIZE_MASK) ! 95: #define _ST_BLOCK_FREE(c) (((c) & _ST_FREE_MASK) == 0) ! 96: #define _ST_BLOCK_SET_FREE(q,a,n) (void) (_ST_BLOCK_CONTROL (q, (a)) = (n) & ~ _ST_FREE_MASK) ! 97: #define _ST_BLOCK_SET_USED(q,a,n) (void) (_ST_BLOCK_CONTROL (q, (a)) = (n) | _ST_FREE_MASK) ! 98: ! 99: ! 100: #define _ST_HEAP_BIGGEST(q,s) ((q)->_bucket_biggest [s]) ! 101: #define _ST_HEAP_FIRST(q,s) ((q)->_bucket_first [s]) ! 102: ! 103: #define _ST_BUCKET_SIBLING(b) (b ^ 1) ! 104: #define _ST_BUCKET_PARENT(b) (b >>= 1) ! 105: ! 106: #define _ST_HEAP_NEXT(a,c) ((_ST_ADDR_T) ((a) + _ST_BLOCK_SIZE (c))) ! 107: #define _ST_HEAP_NEXT_RAW(a,c) ((_ST_ADDR_T) ((a) + (c))) ! 108: ! 109: #define _ST_SET_ERROR(q,e) ((q)->_heap_error = (e)) ! 110: #define _ST_HEAP_ERROR(q) ((q)->_heap_error) ! 111: ! 112: ! 113: /* ! 114: * Help clients initialise the arena. ! 115: */ ! 116: ! 117: #define _ST_HEAP_CONTROL_SIZE(segs)\ ! 118: (sizeof (struct _st_heap_control) + \ ! 119: (segs) * (2 * sizeof (_ST_WORD_T) + sizeof (_ST_ADDR_T))) ! 120: ! 121: /* ! 122: * Allocation control block. This block is normally followed by vectors ! 123: * containing a maximum block size heap and a vector defining the first free ! 124: * block in an allocation bucket. ! 125: */ ! 126: ! 127: struct _st_heap_control { ! 128: ! 129: int _buckets_inuse; /* number of active buckets */ ! 130: int _buckets_maximum; /* maximum possible buckets */ ! 131: int _words_per_bucket; /* memory words per bucket */ ! 132: size_t _arena_size; /* total bytes in arena */ ! 133: ! 134: _ST_WORD_T * _bucket_biggest; /* bucket size ordered heap */ ! 135: _ST_ADDR_T * _bucket_first; /* address of first block */ ! 136: _ST_ADDR_T _arena_base; ! 137: /* ! 138: * base address of the first ! 139: * word in the arena, same as ! 140: * _bucket_first [0] ! 141: */ ! 142: _ST_ADDR_T _arena_end; ! 143: /* ! 144: * Address of last word in ! 145: * the arena +1 ! 146: */ ! 147: __CONST__ char * _heap_error; ! 148: /* ! 149: * If this heap is corrupt, ! 150: * points to a string that ! 151: * describes the problem ! 152: */ ! 153: }; ! 154: ! 155: typedef struct _st_heap_control _ST_HEAP_CONTROL, * _ST_HEAP_CONTROL_P; ! 156: ! 157: ! 158: /* ! 159: * As an additional check, we can make clients of st_disp () pass in the ! 160: * size of the block to free as (i) an additional assertion check against ! 161: * bugs, and (ii) because a faster/less overhead implementation of the ! 162: * algorithm might be possible where there is no header for allocated blocks ! 163: * (the free blocks contain a size and a pointer to the next free block). ! 164: */ ! 165: ! 166: #define USE_ST_SIZE ! 167: ! 168: #ifdef USE_ST_SIZE ! 169: #define ST_FREE_SIZE(x) , x ! 170: #else ! 171: #define ST_FREE_SIZE(x) ! 172: #endif ! 173: ! 174: ! 175: /* ! 176: * Public function prototypes ! 177: */ ! 178: ! 179: __EXTERN_C_BEGIN__ ! 180: ! 181: int st_assert __PROTO ((_ST_HEAP_CONTROL_P _q)); ! 182: __VOID__ * st_alloc __PROTO ((_ST_HEAP_CONTROL_P _q, ! 183: size_t _size)); ! 184: int st_free __PROTO ((_ST_HEAP_CONTROL_P _q, ! 185: __VOID__ * _a ! 186: ST_FREE_SIZE (size_t _size))); ! 187: __VOID__ * st_realloc __PROTO ((_ST_HEAP_CONTROL_P _q, ! 188: __VOID__ * _a, size_t _newsize ! 189: ST_FREE_SIZE (size_t _oldsize))); ! 190: void st_init __PROTO ((_ST_HEAP_CONTROL_P _q)); ! 191: void st_ctor __PROTO ((_ST_HEAP_CONTROL_P _q, int _segs, ! 192: size_t _arensize, ! 193: _ST_ADDR_T _arenabase)); ! 194: size_t st_maxavail __PROTO ((_ST_HEAP_CONTROL_P _q)); ! 195: ! 196: __EXTERN_C_END__ ! 197: ! 198: #endif /* ! defined (__KERNEL_ST_ALLOC_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.