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