1fc76f6aeSSascha Wildner.\" 2fc76f6aeSSascha Wildner.\" Copyright (c) 2009 3fc76f6aeSSascha Wildner.\" The DragonFly Project. All rights reserved. 4fc76f6aeSSascha Wildner.\" 5fc76f6aeSSascha Wildner.\" Redistribution and use in source and binary forms, with or without 6fc76f6aeSSascha Wildner.\" modification, are permitted provided that the following conditions 7fc76f6aeSSascha Wildner.\" are met: 8fc76f6aeSSascha Wildner.\" 9fc76f6aeSSascha Wildner.\" 1. Redistributions of source code must retain the above copyright 10fc76f6aeSSascha Wildner.\" notice, this list of conditions and the following disclaimer. 11fc76f6aeSSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright 12fc76f6aeSSascha Wildner.\" notice, this list of conditions and the following disclaimer in 13fc76f6aeSSascha Wildner.\" the documentation and/or other materials provided with the 14fc76f6aeSSascha Wildner.\" distribution. 15fc76f6aeSSascha Wildner.\" 3. Neither the name of The DragonFly Project nor the names of its 16fc76f6aeSSascha Wildner.\" contributors may be used to endorse or promote products derived 17fc76f6aeSSascha Wildner.\" from this software without specific, prior written permission. 18fc76f6aeSSascha Wildner.\" 19fc76f6aeSSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fc76f6aeSSascha Wildner.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fc76f6aeSSascha Wildner.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22fc76f6aeSSascha Wildner.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23fc76f6aeSSascha Wildner.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24fc76f6aeSSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 25fc76f6aeSSascha Wildner.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26fc76f6aeSSascha Wildner.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27fc76f6aeSSascha Wildner.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28fc76f6aeSSascha Wildner.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29fc76f6aeSSascha Wildner.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30fc76f6aeSSascha Wildner.\" SUCH DAMAGE. 31fc76f6aeSSascha Wildner.\" 32*8a7a7510SAaron LI.Dd December 22, 2023 33fc76f6aeSSascha Wildner.Dt OBJCACHE 9 34fb5b3747SSascha Wildner.Os 35fc76f6aeSSascha Wildner.Sh NAME 36fc76f6aeSSascha Wildner.Nm objcache_create , 37fc76f6aeSSascha Wildner.Nm objcache_create_mbacked , 38fc76f6aeSSascha Wildner.Nm objcache_create_simple , 39fc76f6aeSSascha Wildner.Nm objcache_destroy , 40fc76f6aeSSascha Wildner.Nm objcache_dtor , 41fc76f6aeSSascha Wildner.Nm objcache_get , 42fc76f6aeSSascha Wildner.Nm objcache_malloc_alloc , 43fc76f6aeSSascha Wildner.Nm objcache_malloc_free , 44fc76f6aeSSascha Wildner.Nm objcache_nop_alloc , 45fc76f6aeSSascha Wildner.Nm objcache_nop_free , 46fc76f6aeSSascha Wildner.\" .Nm objcache_populate_linear , 47fc76f6aeSSascha Wildner.Nm objcache_put , 485f861a3bSSascha Wildner.Nm objcache_reclaimlist 49fc76f6aeSSascha Wildner.Nd "object caching facility" 50fc76f6aeSSascha Wildner.Sh SYNOPSIS 51fc76f6aeSSascha Wildner.In sys/objcache.h 52fc76f6aeSSascha Wildner.Ft struct objcache * 53fc76f6aeSSascha Wildner.Fo objcache_create 54fc76f6aeSSascha Wildner.Fa "const char *name" 55d91f660cSStathis Kamperis.Fa "int cluster_limit" 56fc76f6aeSSascha Wildner.Fa "int mag_capacity" 57fc76f6aeSSascha Wildner.Fa "objcache_ctor_fn *ctor" 58fc76f6aeSSascha Wildner.Fa "objcache_dtor_fn *dtor" 59fc76f6aeSSascha Wildner.Fa "void *privdata" 60fc76f6aeSSascha Wildner.Fa "objcache_alloc_fn *alloc" 61fc76f6aeSSascha Wildner.Fa "objcache_free_fn *free" 62fc76f6aeSSascha Wildner.Fa "void *allocator_args" 63fc76f6aeSSascha Wildner.Fc 64fc76f6aeSSascha Wildner.Ft struct objcache * 65fc76f6aeSSascha Wildner.Fo objcache_create_mbacked 66fc76f6aeSSascha Wildner.Fa "malloc_type_t mtype" 67fc76f6aeSSascha Wildner.Fa "size_t objsize" 68d91f660cSStathis Kamperis.Fa "int cluster_limit" 69fc76f6aeSSascha Wildner.Fa "int mag_capacity" 70fc76f6aeSSascha Wildner.Fa "objcache_ctor_fn *ctor" 71fc76f6aeSSascha Wildner.Fa "objcache_dtor_fn *dtor" 72fc76f6aeSSascha Wildner.Fa "void *privdata" 73fc76f6aeSSascha Wildner.Fc 74fc76f6aeSSascha Wildner.Ft struct objcache * 75fc76f6aeSSascha Wildner.Fn objcache_create_simple "malloc_type_t mtype" "size_t objsize" 76fc76f6aeSSascha Wildner.Ft void 77fc76f6aeSSascha Wildner.Fn objcache_destroy "struct objcache *oc" 78fc76f6aeSSascha Wildner.Ft void 79fc76f6aeSSascha Wildner.Fn objcache_dtor "struct objcache *oc" "void *obj" 80fc76f6aeSSascha Wildner.Ft void * 81fc76f6aeSSascha Wildner.Fn objcache_get "struct objcache *oc" "int ocflags" 82fc76f6aeSSascha Wildner.Ft void * 83fc76f6aeSSascha Wildner.Fn objcache_malloc_alloc "void *allocator_args" "int ocflags" 84fc76f6aeSSascha Wildner.Ft void 85fc76f6aeSSascha Wildner.Fn objcache_malloc_free "void *obj" "void *allocator_args" 86fc76f6aeSSascha Wildner.Ft void * 87fc76f6aeSSascha Wildner.Fn objcache_nop_alloc "void *allocator_args" "int ocflags" 88fc76f6aeSSascha Wildner.Ft void 89fc76f6aeSSascha Wildner.Fn objcache_nop_free "void *obj" "void *allocator_args" 90fc76f6aeSSascha Wildner.\" .Ft void 91fc76f6aeSSascha Wildner.\" .Fo objcache_populate_linear 92fc76f6aeSSascha Wildner.\" .Fa "struct objcache *oc" 93fc76f6aeSSascha Wildner.\" .Fa "void *elts" 94fc76f6aeSSascha Wildner.\" .Fa "int nelts" 95fc76f6aeSSascha Wildner.\" .Fa "int size" 96fc76f6aeSSascha Wildner.\" .Fc 97fc76f6aeSSascha Wildner.Ft void 98fc76f6aeSSascha Wildner.Fn objcache_put "struct objcache *oc" "void *obj" 99fc76f6aeSSascha Wildner.Ft boolean_t 100*8a7a7510SAaron LI.Fn objcache_reclaimlist "struct objcache *oc[]" "int nlist" 101fc76f6aeSSascha Wildner.Sh DESCRIPTION 102fc76f6aeSSascha WildnerObject caching is a technique for manipulating objects that are frequently 103fc76f6aeSSascha Wildnerallocated and freed. 104fc76f6aeSSascha WildnerThe idea behind caching is to preserve the invariant portion of an object's 105fc76f6aeSSascha Wildnerinitial state between uses, so it does not have to be destroyed and reborn 106fc76f6aeSSascha Wildnerevery time the object is used. 107fc76f6aeSSascha Wildner.Pp 108fc76f6aeSSascha Wildner.Fn objcache_create 109fc76f6aeSSascha Wildnercreates a new object cache. 110fc76f6aeSSascha WildnerIt is identified by 111fc76f6aeSSascha Wildner.Fa name , 112fc76f6aeSSascha Wildnerwhich is used to distinguish the object in diagnostic output. 113fc76f6aeSSascha WildnerThe 114d91f660cSStathis Kamperis.Fa cluster_limit 115fc76f6aeSSascha Wildnerdetermines the number of available magazines in the depot layer. 116fc76f6aeSSascha WildnerIt must be at least 117fc76f6aeSSascha Wildner.Fa mag_capacity * 118fc76f6aeSSascha Wildnerncpus * 8. 119fc76f6aeSSascha WildnerIf 0 is given, then there is no limit to the number of magazines the depot 120fc76f6aeSSascha Wildnercan have (aside from the inherent limitation imposed by the restricted nature 121fc76f6aeSSascha Wildnerof the back end allocator). 122fc76f6aeSSascha WildnerThe 123fc76f6aeSSascha Wildner.Fa mag_capacity 124fc76f6aeSSascha Wildnerdescribes the capacity of the magazine, that is the largest number of objects 125fc76f6aeSSascha Wildnerit can hold. 126fc76f6aeSSascha WildnerIf set to 0, the default value is used as defined in 1270280bae0SSascha Wildner.Pa sys/kern/kern_objcache.c . 128fc76f6aeSSascha WildnerCurrently, the default value is 64. 129fc76f6aeSSascha WildnerThe object caching system itself may adjust the cluster limit and/or 130fc76f6aeSSascha Wildnermagazines' capacity based on the number of available CPUs. 131fc76f6aeSSascha Wildner.Fa ctor 132fc76f6aeSSascha Wildnerspecifies a function that constructs (i.e., performs the one-time 133fc76f6aeSSascha Wildnerinitialization of) an object in the cache. 134fc76f6aeSSascha WildnerIt is defined as: 135fc76f6aeSSascha Wildner.Bd -literal 136fc76f6aeSSascha Wildnerboolean_t foo_ctor(void *obj, void *privdata, int ocflags); 137fc76f6aeSSascha Wildner.Ed 138fc76f6aeSSascha Wildner.Pp 139fc76f6aeSSascha WildnerIf no constructor is needed, it must be set to 140fc76f6aeSSascha Wildner.Dv NULL . 141fc76f6aeSSascha Wildner.Fa dtor 142fc76f6aeSSascha Wildnerspecifies a deconstructor function that destroys the cached object, before it 143fc76f6aeSSascha Wildneris released to the back end that manages the flow of real memory. 144fc76f6aeSSascha WildnerIt is defined as: 145fc76f6aeSSascha Wildner.Bd -literal 146fc76f6aeSSascha Wildnervoid foo_dtor(void *obj, void *privdata); 147fc76f6aeSSascha Wildner.Ed 148fc76f6aeSSascha Wildner.Pp 149fc76f6aeSSascha WildnerIf no deconstructor is needed, it must be set to 150fc76f6aeSSascha Wildner.Dv NULL . 151fc76f6aeSSascha WildnerThe interface to underlying allocator is provided by 152fc76f6aeSSascha Wildner.Fa alloc , 153fc76f6aeSSascha Wildner.Fa free 154fc76f6aeSSascha Wildnerand 155fc76f6aeSSascha Wildner.Fa allocator_args . 156fc76f6aeSSascha WildnerIt must adhere to the following form: 157fc76f6aeSSascha Wildner.Bd -literal 158fc76f6aeSSascha Wildnervoid *foo_alloc(void *allocator_args, int ocflags); 159fc76f6aeSSascha Wildnervoid foo_free(void *obj, void *allocator_args); 160fc76f6aeSSascha Wildner.Ed 161fc76f6aeSSascha Wildner.Pp 162fc76f6aeSSascha Wildner.Fn objcache_malloc_alloc 163fc76f6aeSSascha Wildnerand 164fc76f6aeSSascha Wildner.Fn objcache_malloc_free 165fc76f6aeSSascha Wildnerare wrappers for 166fc76f6aeSSascha Wildner.Xr kmalloc 9 167fc76f6aeSSascha Wildnerallocation functions. 168fc76f6aeSSascha WildnerWhereas, 169fc76f6aeSSascha Wildner.Fn objcache_nop_alloc 170fc76f6aeSSascha Wildnerand 171fc76f6aeSSascha Wildner.Fn objcache_nop_free 172fc76f6aeSSascha Wildnerare wrappers for allocation policies that pre-allocate at initialization time 173fc76f6aeSSascha Wildnerinstead of doing run-time allocation. 174fc76f6aeSSascha Wildner.Pp 175fc76f6aeSSascha Wildner.Fn objcache_create_mbacked 176fc76f6aeSSascha Wildnercreates a new object cache of size 177fc76f6aeSSascha Wildner.Fa objsize , 178fc76f6aeSSascha Wildnerbacked with a 179fc76f6aeSSascha Wildner.Vt malloc_type_t 180fc76f6aeSSascha Wildnerargument. 181fc76f6aeSSascha WildnerThe latter is used to perform statistics in memory usage and for basic sanity 182fc76f6aeSSascha Wildnerchecks. 183fc76f6aeSSascha WildnerFor the underlying allocator, 184fc76f6aeSSascha Wildner.Xr kmalloc 9 185fc76f6aeSSascha Wildnerfunctions are employed. 186fc76f6aeSSascha Wildner.Pp 187fc76f6aeSSascha Wildner.Fn objcache_create_simple 188fc76f6aeSSascha Wildnercreates a new object cache of size 189fc76f6aeSSascha Wildner.Fa objsize , 190fc76f6aeSSascha Wildnerbacked with a 1914a77bba4SSascha Wildner.Vt malloc_type_t 192fc76f6aeSSascha Wildnerargument. 193fc76f6aeSSascha WildnerThe 194d91f660cSStathis Kamperis.Fa cluster_limit 195fc76f6aeSSascha Wildneris set to 0 and the default value for magazines' capacity is used. 196fc76f6aeSSascha Wildner.Fa ctor 197fc76f6aeSSascha Wildnerand 198fc76f6aeSSascha Wildner.Fa dtor 199fc76f6aeSSascha Wildnerare set to 200fc76f6aeSSascha Wildner.Dv NULL . 201fc76f6aeSSascha Wildner.Fa privdata 202fc76f6aeSSascha Wildneris set to 203fc76f6aeSSascha Wildner.Dv NULL 204fc76f6aeSSascha Wildneras well. 205fc76f6aeSSascha WildnerFor the underlying allocator, 206fc76f6aeSSascha Wildner.Xr kmalloc 9 207fc76f6aeSSascha Wildnerfunctions are employed. 208fc76f6aeSSascha Wildner.Pp 209fc76f6aeSSascha Wildner.Fn objcache_get 210fc76f6aeSSascha Wildnerreturns an object from the 211fc76f6aeSSascha Wildner.Fa oc 212fc76f6aeSSascha Wildnerobject cache. 213fc76f6aeSSascha WildnerThe object is in its initialized state. 214fc76f6aeSSascha WildnerNewly allocated objects are subjected to the object cache's constructor 215fc76f6aeSSascha Wildnerfunction, if not 216fc76f6aeSSascha Wildner.Dv NULL , 217fc76f6aeSSascha Wildnerprior to being returned. 218fc76f6aeSSascha Wildner.Fa ocflags 219fc76f6aeSSascha Wildneris only used when the depot does not have any non-empty magazines and a new 220fc76f6aeSSascha Wildnerobject needs to be allocated using the back end allocator. 221fc76f6aeSSascha WildnerIn this case we cannot depend on flags such as 222fc76f6aeSSascha Wildner.Dv M_ZERO . 223fc76f6aeSSascha WildnerIf the back end allocator fails, or if the depot's object limit has been 224fc76f6aeSSascha Wildnerreached and 225fc76f6aeSSascha Wildner.Dv M_WAITOK 226fc76f6aeSSascha Wildneris not specified, 227fc76f6aeSSascha Wildner.Dv NULL 228fc76f6aeSSascha Wildneris returned. 229fc76f6aeSSascha Wildner.Pp 230fc76f6aeSSascha Wildner.Fn objcache_put 231fc76f6aeSSascha Wildnerreturns 232fc76f6aeSSascha Wildner.Fa obj 233fc76f6aeSSascha Wildnerto the 234fc76f6aeSSascha Wildner.Fa oc 235fc76f6aeSSascha Wildnerobject cache. 236fc76f6aeSSascha WildnerThe object must be in its initialized state prior to this call. 237fc76f6aeSSascha WildnerIf there is no empty magazine, the object deconstructor is called and 238fc76f6aeSSascha Wildnerthe object is freed. 239fc76f6aeSSascha Wildner.Pp 240fc76f6aeSSascha Wildner.Fn objcache_dtor 241fc76f6aeSSascha Wildnerputs 242fc76f6aeSSascha Wildner.Fa obj 243fc76f6aeSSascha Wildnerback into the 244fc76f6aeSSascha Wildner.Fa oc 245fc76f6aeSSascha Wildnerobject cache, indicating that the object is not in any shape to be reused and 246fc76f6aeSSascha Wildnershould be deconstructed and freed immediately. 247fc76f6aeSSascha Wildner.Pp 248fc76f6aeSSascha Wildner.Fn objcache_reclaimlist 249fc76f6aeSSascha Wildneriterates over the 250fc76f6aeSSascha Wildner.Fa oclist[] 251fc76f6aeSSascha Wildnerlist with 252fc76f6aeSSascha Wildner.Fa nlist 253fc76f6aeSSascha Wildnerelements and tries to free up some memory. 254fc76f6aeSSascha WildnerFor each object cache in the reclaim list, the current per-CPU cache is tried 255fc76f6aeSSascha Wildnerfirst and then the full magazine depot. 256fc76f6aeSSascha WildnerThe function returns 257fc76f6aeSSascha Wildner.Dv TRUE 258fc76f6aeSSascha Wildneras soon as some free memory is found 259fc76f6aeSSascha Wildnerand 260fc76f6aeSSascha Wildner.Dv FALSE 261fc76f6aeSSascha Wildnerotherwise. 262fc76f6aeSSascha Wildner.Pp 263fc76f6aeSSascha Wildner.Fn objcache_destroy 264fc76f6aeSSascha Wildnerdestroys the 265fc76f6aeSSascha Wildner.Fa oc 266fc76f6aeSSascha Wildnerobject cache. 267fc76f6aeSSascha WildnerThe object must have no existing references. 268fc76f6aeSSascha Wildner.\" .Pp 269fc76f6aeSSascha Wildner.\" .Fn objcache_populate_linear 270fc76f6aeSSascha Wildner.\" populates the per-cluster depot with elements from a linear block of memory. 271fc76f6aeSSascha Wildner.\" Must be called for individually for each cluster. 272fc76f6aeSSascha Wildner.\" Populated depots should not be destroyed. 273fc76f6aeSSascha Wildner.\" Currently this function is unimplemented. 274fc76f6aeSSascha Wildner.Sh IMPLEMENTATION NOTES 275fc76f6aeSSascha Wildner.Ss Magazine 276fc76f6aeSSascha WildnerA magazine is the very basic functional unit of the object caching scheme. 277fc76f6aeSSascha WildnerThe number of objects it can hold is fixed and determined by its capacity. 278fc76f6aeSSascha WildnerThe term magazine is used as an analogy with automatic weapon 279fc76f6aeSSascha Wildner(a firearm that can fire several rounds without reloading). 280fc76f6aeSSascha Wildner.Ss Per-CPU object cache 281fc76f6aeSSascha WildnerThe reasoning behind per-CPU caches is to allow CPUs to perform their 282fc76f6aeSSascha Wildnertransactions (i.e., allocations, frees) in a parallel, yet lockless manner. 283fc76f6aeSSascha Wildner.Pp 284fc76f6aeSSascha WildnerEach CPU is given two magazines, an active and a backup. 285fc76f6aeSSascha WildnerThis is done in order to avoid a situation where a tight loop of 286fc76f6aeSSascha Wildnertwo allocations followed by two frees can cause thrashing at the 287fc76f6aeSSascha Wildnermagazine boundary. 288fc76f6aeSSascha Wildner.Pp 289fc76f6aeSSascha WildnerIf we need to add an object to the cache and the active magazine is full, 290fc76f6aeSSascha Wildnerroom is searched in the backup magazine. 291fc76f6aeSSascha WildnerIf the backup has room, we swap active with backup and add the object. 292fc76f6aeSSascha WildnerIf both magazines are full, we get an empty magazine from the depot 293fc76f6aeSSascha Wildnerand move a fully loaded magazine to the depot. 294fc76f6aeSSascha Wildner.Ss Magazine depot 295fc76f6aeSSascha WildnerEach object cache manages a global supply of magazines, the depot, that is 296fc76f6aeSSascha Wildneravailable across all CPUs. 297fc76f6aeSSascha WildnerThe depot maintains two lists of magazines. 298fc76f6aeSSascha WildnerOne for completely full and one for completely free magazines. 299fc76f6aeSSascha WildnerThe per-CPU object caches only exchange completely full or 300fc76f6aeSSascha Wildnercompletely empty magazines with the depot layer. 301fc76f6aeSSascha Wildner.Sh EXAMPLES 302fc76f6aeSSascha Wildner.Bd -literal 303fc76f6aeSSascha Wildner/* This is the data structure we are going to cache. */ 304fc76f6aeSSascha Wildnerstruct foo { 305fc76f6aeSSascha Wildner int x; 306fc76f6aeSSascha Wildner char str[32]; 307fc76f6aeSSascha Wildner}; 308fc76f6aeSSascha Wildner 309fc76f6aeSSascha WildnerMALLOC_DEFINE(M_FOOBUF, "foobuf", "Buffer to my little precious data"); 310fc76f6aeSSascha Wildner 311fc76f6aeSSascha Wildnerstruct objcache_malloc_args foo_malloc_args = { 312fc76f6aeSSascha Wildner sizeof(struct foo), M_FOOBUF }; 313fc76f6aeSSascha Wildner 314fc76f6aeSSascha Wildnerstruct objcache *foo_cache; 315fc76f6aeSSascha Wildner 316fc76f6aeSSascha Wildner/* 317fc76f6aeSSascha Wildner * Object cache constructor. 318fc76f6aeSSascha Wildner */ 319fc76f6aeSSascha Wildnerstatic boolean_t 320fc76f6aeSSascha Wildnerfoo_cache_ctor(void *obj, void *privdata, int ocflags) 321fc76f6aeSSascha Wildner{ 322fc76f6aeSSascha Wildner struct foo *myfoo = obj; 323fc76f6aeSSascha Wildner 324fc76f6aeSSascha Wildner /* 325fc76f6aeSSascha Wildner * Do any initialization of the object here. Let's just zero out 326fc76f6aeSSascha Wildner * the data structure for the fun of it. 327fc76f6aeSSascha Wildner */ 328fc76f6aeSSascha Wildner bzero(myfoo, sizeof(*myfoo)); 329fc76f6aeSSascha Wildner 330fc76f6aeSSascha Wildner return (TRUE); 331fc76f6aeSSascha Wildner} 332fc76f6aeSSascha Wildner 333fc76f6aeSSascha Wildner/* 334fc76f6aeSSascha Wildner * Object cache deconstructor. 335fc76f6aeSSascha Wildner */ 336fc76f6aeSSascha Wildnerstatic void 337fc76f6aeSSascha Wildnerfoo_cache_dtor(void *obj, void *privdata) 338fc76f6aeSSascha Wildner{ 339fc76f6aeSSascha Wildner struct foo *myfoo = obj; 340fc76f6aeSSascha Wildner 341fc76f6aeSSascha Wildner /* 342fc76f6aeSSascha Wildner * Do any clean up here. E.g., if you have kmalloc'ed() inside 343fc76f6aeSSascha Wildner * the constructor, this is the right place and time to kfree(). 344fc76f6aeSSascha Wildner */ 345fc76f6aeSSascha Wildner} 346fc76f6aeSSascha Wildner 347fc76f6aeSSascha Wildner/* 348fc76f6aeSSascha Wildner * Initialize our subsystem. 349fc76f6aeSSascha Wildner */ 350fc76f6aeSSascha Wildnerstatic void 351fc76f6aeSSascha Wildnerfoo_init(void) 352fc76f6aeSSascha Wildner{ 353fc76f6aeSSascha Wildner /* Create the object cache. */ 354fc76f6aeSSascha Wildner foo_cache = objcache_create("foo", 355fc76f6aeSSascha Wildner 0, /* infinite depot's capacity */ 356fc76f6aeSSascha Wildner 0, /* default magazine's capacity */ 357fc76f6aeSSascha Wildner foo_ctor, foo_dtor, NULL, 358fc76f6aeSSascha Wildner objcache_malloc_alloc, 359fc76f6aeSSascha Wildner objcache_malloc_free, 360fc76f6aeSSascha Wildner &foo_malloc_args); 361fc76f6aeSSascha Wildner} 362fc76f6aeSSascha Wildner 363fc76f6aeSSascha Wildner/* 364fc76f6aeSSascha Wildner * Random function. 365fc76f6aeSSascha Wildner */ 366fc76f6aeSSascha Wildnerstatic void 367fc76f6aeSSascha Wildnerfoo_random(...) 368fc76f6aeSSascha Wildner{ 369fc76f6aeSSascha Wildner struct foo *myfoo; 370fc76f6aeSSascha Wildner 371fc76f6aeSSascha Wildner /* Get a `foo' object from the object cache. */ 372fc76f6aeSSascha Wildner myfoo = objcache_get(foo_cache, M_WAITOK); 373fc76f6aeSSascha Wildner 374fc76f6aeSSascha Wildner /* Do stuff with it. */ 375fc76f6aeSSascha Wildner /* ... */ 376fc76f6aeSSascha Wildner 377fc76f6aeSSascha Wildner /* We don't need it anymore. Put it back in object cache. */ 378fc76f6aeSSascha Wildner objcache_put(foo_cache, myfoo); 379fc76f6aeSSascha Wildner} 380fc76f6aeSSascha Wildner 381fc76f6aeSSascha Wildner/* 382fc76f6aeSSascha Wildner * Shutdown our subsystem. 383fc76f6aeSSascha Wildner */ 384fc76f6aeSSascha Wildnerstatic void 385fc76f6aeSSascha Wildnerfoo_uninit(void) 386fc76f6aeSSascha Wildner{ 387fc76f6aeSSascha Wildner /* Destroy the object cache. */ 388fc76f6aeSSascha Wildner objcache_destroy(foo_cache); 389fc76f6aeSSascha Wildner} 390fc76f6aeSSascha Wildner.Ed 391fc76f6aeSSascha Wildner.Sh SEE ALSO 392ae03fd51SSascha Wildner.Xr memory 9 393fc76f6aeSSascha Wildner.Rs 394fc76f6aeSSascha Wildner.%A "Jeff Bonwick" 395fc76f6aeSSascha Wildner.%T "The Slab Allocator: An Object-Caching Kernel Memory Allocator" 396fc76f6aeSSascha Wildner.%R "USENIX Summer 1994 Technical Conference" 397fc76f6aeSSascha Wildner.Re 398fc76f6aeSSascha Wildner.Rs 399fc76f6aeSSascha Wildner.%A "Jeff Bonwick" 400fc76f6aeSSascha Wildner.%A "Jonathan Adams" 401fc76f6aeSSascha Wildner.%T "Magazines and Vmem: Extending the Slab Allocator to Many CPUs and Arbitrary Resources" 402fc76f6aeSSascha Wildner.%R "USENIX 2001 Technical Conference" 403fc76f6aeSSascha Wildner.Re 404fc76f6aeSSascha Wildner.Sh HISTORY 405fc76f6aeSSascha WildnerThe object caching system appeared in 406fc76f6aeSSascha Wildner.Dx 1.3 . 407fc76f6aeSSascha Wildner.Sh AUTHORS 408fc76f6aeSSascha WildnerThe object caching system was written by 409fc76f6aeSSascha Wildner.An -nosplit 410c616d378SFranco Fichtner.An Jeffrey M. Hsu Aq Mt hsu@freebsd.org . 411fc76f6aeSSascha WildnerThis manual page was written by 412c616d378SFranco Fichtner.An Stathis Kamperis Aq Mt ekamperi@gmail.com . 413