1.\" Id: memcluster.mdoc,v 1.3 2004/03/09 06:30:08 marka Exp 2.\" 3.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 4.\" Copyright (c) 1995-1999 by Internet Software Consortium 5.\" 6.\" Permission to use, copy, modify, and distribute this software for any 7.\" purpose with or without fee is hereby granted, provided that the above 8.\" copyright notice and this permission notice appear in all copies. 9.\" 10.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 16.\" OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17.\" 18.\" The following six UNCOMMENTED lines are required. 19.Dd Month day, year 20.\"Os OPERATING_SYSTEM [version/release] 21.Os BSD 4 22.\"Dt DOCUMENT_TITLE [section number] [volume] 23.Dt MEMCLUSTER 3 24.Sh NAME 25.Nm meminit , 26.Nm memget , 27.Nm memput , 28.Nm memstats 29.Nd memory allocation/deallocation system 30.Sh SYNOPSIS 31.Fd #include \&<isc/memcluster.h\&> 32.Ft void * 33.Fn memget "size_t size" 34.Ft void 35.Fn memput "void *mem" "size_t size" 36.Ft void 37.Fn memstats "FILE *out" 38.Sh DESCRIPTION 39These functions access a memory management system which allows callers to not 40fragment memory to the extent which can ordinarily occur through many random 41calls to 42.Xr malloc 3 . 43Instead, 44.Fn memget 45gets a large contiguous chunk of blocks of the requested 46.Fa size 47and parcels out these blocks as requested. The symmetric call is 48.Fn memput , 49which callers use to return a piece of memory obtained from 50.Fn memget . 51Statistics about memory usage are returned by 52.Fn memstats , 53which prints a report on the stream 54.Fa out . 55.Ss INTERNALS 56Internally, linked lists of free memory blocks are stored in an array. 57The size of this array is determined by the value 58.Dv MEM_FREECOUNT , 59currently set to 1100. In general, for any requested blocksize 60.Dq Fa size , 61any free blocks will be stored on the linked list at that index. 62No free lists are managed for blocks greater than or equal to 63.Dv MEM_FREECOUNT 64bytes; instead, calls to 65.Xr malloc 3 66or 67.Xr free 3 68are made, directly. 69.Pp 70Since the blocks are actually stored as linked lists, they must at least 71be large enough to hold a pointer to the next block. This size, which is 72.Dv SMALL_SIZE_LIMIT , 73is currently defined as 74.Bd -literal -offset indent 75#define SMALL_SIZE_LIMIT sizeof(struct { void *next; }) 76.Ed 77.Pp 78Both 79.Fn memget 80and 81.Fn memput 82enforce this limit; for example, any call to 83.Fn memget 84requesting a block smaller than 85.Dv SMALL_SIZE_LIMIT 86bytes will actually be considered to be of size 87.Dv SMALL_SIZE_LIMIT 88internally. (Such a caller request will be logged for 89.Fn memstats 90purposes using the caller-requested 91.Fa size ; 92see the discussion of 93.Fn memstats , 94below, for more information.) 95.Pp 96Additionally, the requested 97.Fa size 98will be adjusted so that when a large 99.Xr malloc 3 Ns No -d 100chunk of memory is broken up into a linked list, the blocks will all fall on 101the correct memory alignment boundaries. Thus, one can conceptualize a call 102which mentions 103.Fa size 104as resulting in a 105.Fa new_size 106which is used internally. 107.Pp 108In order to more efficiently allocate memory, there is a 109.Dq target 110size for calls to 111.Xr malloc 3 . 112It is given by the pre-defined value 113.Dv MEM_TARGET , 114which is currently 4096 bytes. 115For any requested block 116.Fa size , 117enough memory is 118.Xr malloc 3 Ns No -d 119in order to fill up a block of about 120.Dv MEM_TARGET 121bytes. 122.No [ Ns Sy NOTE : 123For allocations larger than 124.Dv MEM_TARGET Ns No /2 125bytes, there is a 126.Dq fudge factor 127introduced which boosts the target size by 25% of 128.Dv MEM_TARGET . 129This means that enough memory for two blocks 130will actually be allocated for any 131.Fa size 132such that 133.Pq Dv MEM_TARGET Ns No / 3 134.No < Fa size No < 135.Pq Dv MEM_TARGET Ns No *5/8 , 136provided that the value of 137.Dv MEM_FREECOUNT 138is at least as large as the upper limit shown above.] 139.Pp 140.Ss FUNCTION DESCRIPTIONS 141.Pp 142The function 143.Fn memget 144returns a pointer to a block of memory of at least the requested 145.Fa size . 146After adjusting 147.Fa size 148to the value 149.Va new_size 150as mentioned above in the 151.Sx INTERNALS 152subsection, the internal array of free lists is checked. 153If there is no block of the needed 154.Va new_size , 155then 156.Fn memget 157will 158.Xr malloc 3 159a chunk of memory which is as many times as 160.Va new_size 161will fit into the target size. This memory is then turned into a linked list 162of 163.Va new_size Ns No -sized 164blocks which are given out as requested; the last such block is the first one 165returned by 166.Fn memget . 167If the requested 168.Fa size 169is zero or negative, then 170.Dv NULL 171is returned and 172.Va errno 173is set to 174.Dv EINVAL ; 175if 176.Fa size 177is larger than or equal to the pre-defined maximum size 178.Dv MEM_FREECOUNT , 179then only a single block of exactly 180.Fa size 181will be 182.Xr malloc 3 Ns No -d 183and returned. 184.Pp 185The 186.Fn memput 187call is used to return memory once the caller is finished with it. 188After adjusting 189.Fa size 190the the value 191.Va new_size 192as mentioned in the 193.Sx INTERNALS 194subsection, above, the block is placed at the head of the free list of 195.Va new_size Ns -sized 196blocks. 197If the given 198.Fa size 199is zero or negative, then 200.Va errno 201is set to 202.Dv EINVAL , 203as for 204.Fn memget . 205If 206.Fa size 207is larger than or equal to the pre-defined maximum size 208.Dv MEM_FREECOUNT , 209then the block is immediately 210.Xr free 3 Ns No -d . 211.Pp 212.Sy NOTE : 213It is important that callers give 214.Fn memput 215.Em only 216blocks of memory which were previously obtained from 217.Fn memget 218if the block is 219.Em actually 220less than 221.Dv SMALL_SIZE_LIMIT 222bytes in size. Since all blocks will be added to a free list, any block 223which is not at least 224.Dv SMALL_SIZE_LIMIT 225bytes long will not be able to hold a pointer to the next block in the 226free list. 227.Pp 228The 229.Fn memstats 230function will summarize the number of calls to 231.Fn memget 232and 233.Fn memput 234for any block size from 1 byte up to 235.Pq Dv MEM_FREECOUNT No - 1 236bytes, followed by a single line for any calls using a 237.Fa size 238greater than or equal to 239.Dv MEM_FREECOUNT ; 240a brief header with shell-style comment lines prefaces the report and 241explains the information. The 242.Dv FILE 243pointer 244.Fa out 245identifies the stream which is used for this report. Currently, 246.Fn memstat 247reports the number of calls to 248.Fn memget 249and 250.Fn memput 251using the caller-supplied value 252.Fa size ; 253the percentage of outstanding blocks of a given size (i.e., the percentage 254by which calls to 255.Fn memget 256exceed 257.Fn memput ) 258are also reported on the line for blocks of the given 259.Fa size . 260However, the percent of blocks used is computed using the number of 261blocks allocated according to the internal parameter 262.Va new_size ; 263it is the percentage of blocks used to those available at a given 264.Va new_size , 265and is computed using the 266.Em total 267number of caller 268.Dq gets 269for any caller 270.Fa size Ns No -s 271which map to the internally-computed 272.Va new_size . 273Keep in mind that 274.Va new_size 275is generally 276.Em not 277equal to 278.Fa size , 279which has these implications: 280.Bl -enum -offset indent 281.It 282For 283.Fa size 284smaller than 285.Dv SMALL_SIZE_LIMIT , 286.Fn memstat 287.Em will 288show statistics for caller requests under 289.Fa size , 290but "percent used" information about such blocks will be reported under 291.Dv SMALL_SIZE_LIMIT Ns No -sized 292blocks. 293.It 294As a general case of point 1, internal statistics are reported on the the 295line corresponding to 296.Va new_size , 297so that, for a given caller-supplied 298.Fa size , 299the associated internal information will appear on that line or on the next 300line which shows "percent used" information. 301.El 302.Pp 303.Sy NOTE : 304If the caller returns blocks of a given 305.Fa size 306and requests others of 307.Fa size Ns No -s 308which map to the same internal 309.Va new_size , 310it is possible for 311.Fn memstats 312to report usage of greater than 100% for blocks of size 313.Va new_size . 314This should be viewed as A Good Thing. 315.Sh RETURN VALUES 316The function 317.Fn memget 318returns a 319.No non- Ns Dv NULL 320pointer to a block of memory of the requested 321.Fa size . 322It returns 323.Dv NULL 324if either the 325.Fa size 326is invalid (less than or equal to zero) or a 327.Xr malloc 3 328of a new block of memory fails. In the former case, 329.Va errno 330is set to 331.Dv EINVAL ; 332in the latter, it is set to 333.Dv ENOMEM . 334.Pp 335Neither 336.Fn memput 337nor 338.Fn memstats 339return a value. 340.\" This next request is for sections 1, 6, 7 & 8 only 341.\" .Sh ENVIRONMENT 342.\" .Sh FILES 343.\" .Sh EXAMPLES 344.\" This next request is for sections 1, 6, 7 & 8 only 345.\" (command return values (to shell) and 346.\" fprintf/stderr type diagnostics) 347.\" .Sh DIAGNOSTICS 348.\" The next request is for sections 2 and 3 error 349.\" and signal handling only. 350.Sh ERRORS 351.Va errno 352is set as follows: 353.Bl -tag -width "ENOMEM " -offset indent 354.It Dv EINVAL 355set by both 356.Fn memget 357and 358.Fn memput 359if the 360.Fa size 361is zero or negative 362.It Dv ENOMEM 363set by 364.Fn memget 365if a call to 366.Xr malloc 3 367fails 368.El 369.Sh SEE ALSO 370.Xr free 3 , 371.Xr malloc 3 . 372.\" .Sh STANDARDS 373.\" .Sh HISTORY 374.Sh AUTHORS 375Steven J. Richardson and Paul Vixie, Vixie Enterprises. 376.\" .Sh BUGS 377