xref: /dflybsd-src/share/man/man9/objcache.9 (revision 8a7a7510cdfb76f81f3e3d993e8ab09b4a310bf2)
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