Commit | Line | Data |
---|---|---|
b6b9d458 | 1 | .\" -*-nroff-*- |
2 | .de VS | |
3 | .sp 1 | |
d66d7727 | 4 | .RS |
b6b9d458 | 5 | .nf |
6 | .ft B | |
7 | .. | |
8 | .de VE | |
9 | .ft R | |
10 | .fi | |
11 | .RE | |
12 | .sp 1 | |
13 | .. | |
fbf20b5b | 14 | .TH sub 3 "8 May 1999" "Straylight/Edgeware" "mLib utilities library" |
b6b9d458 | 15 | .SH NAME |
16 | sub \- efficient allocation and freeing of small blocks | |
c5775f49 | 17 | .\" @subarena_create |
18 | .\" @subarena_destroy | |
19 | .\" @subarena_alloc | |
20 | .\" @subarena_free | |
08da152e | 21 | .\" @sub_alloc |
22 | .\" @sub_free | |
23 | .\" @sub_init | |
24 | .\" | |
c5775f49 | 25 | .\" @A_CREATE |
26 | .\" @A_DESTROY | |
08da152e | 27 | .\" @CREATE |
28 | .\" @DESTROY | |
29 | .\" | |
b6b9d458 | 30 | .SH SYNOPSIS |
31 | .nf | |
32 | .B "#include <mLib/sub.h>" | |
33 | ||
4729aa69 MW |
34 | .B "typedef struct { ...\& } subarena;" |
35 | ||
c5775f49 | 36 | .BI "void subarena_create(subarena *" s ", arena *" a ); |
37 | .BI "void subarena_destroy(subarena *" s ); | |
38 | .BI "void subarena_alloc(subarena *" s ", size_t " sz ); | |
39 | .BI "void subarena_free(subarena *" s ", void *" p ", size_t " sz ); | |
40 | ||
b6b9d458 | 41 | .B "void sub_init(void);" |
42 | .BI "void *sub_alloc(size_t " sz ); | |
43 | .BI "void sub_free(void *" p ", size_t " sz ); | |
44 | ||
c5775f49 | 45 | .BI "void *A_CREATE(subarena *" s ", " type ); |
46 | .BI "void A_DESTROY(subarena *" s ", " type " *" p ); | |
b6b9d458 | 47 | .BI "void *CREATE(" type ); |
48 | .BI "void DESTROY(" type " *" p ); | |
49 | .fi | |
50 | .SH DESCRIPTION | |
51 | The | |
c5775f49 | 52 | .B subarena |
b6b9d458 | 53 | collection of functions and macros implement an efficient allocator for |
c5775f49 | 54 | small blocks of known sizes, constructed from a general allocator |
55 | implemented by an | |
56 | .BR arena (3). | |
57 | Free blocks of the same size are linked together in list, making freeing | |
58 | and allocation fast. The `free' operation requires the block size as an | |
59 | argument, so there's no data overhead for an allocated block. The | |
60 | system takes advantage of this by allocating big chunks from the | |
61 | underlying arena and splitting the chunks into smaller blocks of the | |
62 | right size, so the space and time overhead from the underlying allocator | |
63 | is divided over many blocks. | |
b6b9d458 | 64 | .PP |
65 | Calling | |
c5775f49 | 66 | .B subarena_alloc |
b6b9d458 | 67 | allocates a block of |
68 | .I sz | |
c5775f49 | 69 | bytes from the subarena |
d4efbcd9 | 70 | .IR s . |
c5775f49 | 71 | If there isn't enough memory to allocate the block, the |
b6b9d458 | 72 | exception |
73 | .B EXC_NOMEM | |
74 | is raised. | |
75 | .PP | |
76 | The | |
c5775f49 | 77 | .B subarena_free |
b6b9d458 | 78 | function frees a block allocated by |
c5775f49 | 79 | .B subarena_alloc |
80 | from the same subarena. You must know the size of the block in advance. | |
81 | Note that | |
82 | .B subarena_free | |
b6b9d458 | 83 | never gives memory back to the underlying allocator. Free sub-blocks |
84 | are just made available to later calls of | |
c5775f49 | 85 | .BR subarena_alloc . |
b6b9d458 | 86 | .PP |
c5775f49 | 87 | Don't try to free blocks allocated by |
88 | .B subarena_alloc | |
89 | to the underlying arena's | |
90 | .I free | |
91 | function, or to try freeing blocks obtained directly from the arena's | |
d4efbcd9 | 92 | .I alloc |
c5775f49 | 93 | function using |
94 | .BR subarena_free . | |
b6b9d458 | 95 | If you do, you'll get what you deserve. |
96 | .PP | |
97 | The pair of macros | |
c5775f49 | 98 | .B A_CREATE |
b6b9d458 | 99 | and |
c5775f49 | 100 | .B A_DESTROY |
b6b9d458 | 101 | are intended to provide a slightly more natural interface to |
102 | allocation. The call | |
103 | .VS | |
c5775f49 | 104 | mystruct *p = subarena_alloc(s, sizeof(mystruct)); |
b6b9d458 | 105 | .VE |
106 | can be replaced by | |
107 | .VS | |
c5775f49 | 108 | mystruct p = A_CREATE(s, mystruct); |
b6b9d458 | 109 | .VE |
110 | Similarly, the block can be freed by saying | |
111 | .VS | |
c5775f49 | 112 | A_DESTROY(s, p) |
b6b9d458 | 113 | .VE |
d2a91066 | 114 | rather than the more cumbersome |
b6b9d458 | 115 | .VS |
c5775f49 | 116 | subarena_free(s, p, sizeof(*p)); |
b6b9d458 | 117 | .VE |
c5775f49 | 118 | There is a standard subarena |
119 | .B sub_global | |
120 | which uses | |
121 | .B arena_global | |
122 | as its underlying allocator (obtained the first time the subarena is | |
123 | used). The functions | |
124 | .B sub_alloc | |
125 | and | |
126 | .B sub_free | |
127 | and the macros | |
128 | .B CREATE | |
129 | and | |
130 | .B DESTROY | |
131 | use this subarena. | |
132 | .PP | |
b6b9d458 | 133 | The function |
134 | .B sub_init | |
c5775f49 | 135 | ought to be called before any of the other functions as a matter of good |
136 | taste, but actually the system will initialize itself the first time | |
137 | it's used. | |
08da152e | 138 | .SH "SEE ALSO" |
c5775f49 | 139 | .BR arena (3), |
08da152e | 140 | .BR exc (3), |
141 | .BR alloc (3), | |
142 | .BR mLib (3). | |
b6b9d458 | 143 | .SH AUTHOR |
9b5ac6ff | 144 | Mark Wooding, <mdw@distorted.org.uk> |