1a8806e5eSIngo Weinhold /*
2453a2bddSIngo Weinhold * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
354f3267eSAxel Dörfler * Copyright 2008-2010, Axel Dörfler. All Rights Reserved.
4a8806e5eSIngo Weinhold * Copyright 2007, Hugo Santos. All Rights Reserved.
5a8806e5eSIngo Weinhold *
6a8806e5eSIngo Weinhold * Distributed under the terms of the MIT License.
7a8806e5eSIngo Weinhold */
8a8806e5eSIngo Weinhold
9a8806e5eSIngo Weinhold
10a8806e5eSIngo Weinhold #include <slab/ObjectDepot.h>
11a8806e5eSIngo Weinhold
12a8806e5eSIngo Weinhold #include <algorithm>
13a8806e5eSIngo Weinhold
14453a2bddSIngo Weinhold #include <int.h>
15bb439b87SIngo Weinhold #include <slab/Slab.h>
16453a2bddSIngo Weinhold #include <smp.h>
17a8806e5eSIngo Weinhold #include <util/AutoLock.h>
18a8806e5eSIngo Weinhold
19*e1c6140eSIngo Weinhold #include "slab_debug.h"
20a8806e5eSIngo Weinhold #include "slab_private.h"
21a8806e5eSIngo Weinhold
22a8806e5eSIngo Weinhold
23825566f8SIngo Weinhold struct DepotMagazine {
24825566f8SIngo Weinhold DepotMagazine* next;
25825566f8SIngo Weinhold uint16 current_round;
26825566f8SIngo Weinhold uint16 round_count;
27a8806e5eSIngo Weinhold void* rounds[0];
28825566f8SIngo Weinhold
29825566f8SIngo Weinhold public:
30825566f8SIngo Weinhold inline bool IsEmpty() const;
31825566f8SIngo Weinhold inline bool IsFull() const;
32825566f8SIngo Weinhold
33825566f8SIngo Weinhold inline void* Pop();
34825566f8SIngo Weinhold inline bool Push(void* object);
3572156a40SMichael Lotz
3672156a40SMichael Lotz #if PARANOID_KERNEL_FREE
3772156a40SMichael Lotz bool ContainsObject(void* object) const;
3872156a40SMichael Lotz #endif
39a8806e5eSIngo Weinhold };
40a8806e5eSIngo Weinhold
41a8806e5eSIngo Weinhold
42a8806e5eSIngo Weinhold struct depot_cpu_store {
43825566f8SIngo Weinhold DepotMagazine* loaded;
44825566f8SIngo Weinhold DepotMagazine* previous;
45a8806e5eSIngo Weinhold };
46a8806e5eSIngo Weinhold
47a8806e5eSIngo Weinhold
RANGE_MARKER_FUNCTION_BEGIN(SlabObjectDepot)48*e1c6140eSIngo Weinhold RANGE_MARKER_FUNCTION_BEGIN(SlabObjectDepot)
49*e1c6140eSIngo Weinhold
50*e1c6140eSIngo Weinhold
51825566f8SIngo Weinhold bool
52825566f8SIngo Weinhold DepotMagazine::IsEmpty() const
53a8806e5eSIngo Weinhold {
54825566f8SIngo Weinhold return current_round == 0;
55a8806e5eSIngo Weinhold }
56a8806e5eSIngo Weinhold
57a8806e5eSIngo Weinhold
58825566f8SIngo Weinhold bool
IsFull() const59825566f8SIngo Weinhold DepotMagazine::IsFull() const
60a8806e5eSIngo Weinhold {
61825566f8SIngo Weinhold return current_round == round_count;
62a8806e5eSIngo Weinhold }
63a8806e5eSIngo Weinhold
64a8806e5eSIngo Weinhold
65825566f8SIngo Weinhold void*
Pop()66825566f8SIngo Weinhold DepotMagazine::Pop()
67a8806e5eSIngo Weinhold {
68825566f8SIngo Weinhold return rounds[--current_round];
69a8806e5eSIngo Weinhold }
70a8806e5eSIngo Weinhold
71a8806e5eSIngo Weinhold
72825566f8SIngo Weinhold bool
Push(void * object)73825566f8SIngo Weinhold DepotMagazine::Push(void* object)
74a8806e5eSIngo Weinhold {
75825566f8SIngo Weinhold if (IsFull())
76a8806e5eSIngo Weinhold return false;
77825566f8SIngo Weinhold
78825566f8SIngo Weinhold rounds[current_round++] = object;
79a8806e5eSIngo Weinhold return true;
80a8806e5eSIngo Weinhold }
81a8806e5eSIngo Weinhold
82a8806e5eSIngo Weinhold
8372156a40SMichael Lotz #if PARANOID_KERNEL_FREE
8472156a40SMichael Lotz
8572156a40SMichael Lotz bool
ContainsObject(void * object) const8672156a40SMichael Lotz DepotMagazine::ContainsObject(void* object) const
8772156a40SMichael Lotz {
8872156a40SMichael Lotz for (uint16 i = 0; i < current_round; i++) {
8972156a40SMichael Lotz if (rounds[i] == object)
9072156a40SMichael Lotz return true;
9172156a40SMichael Lotz }
9272156a40SMichael Lotz
9372156a40SMichael Lotz return false;
9472156a40SMichael Lotz }
9572156a40SMichael Lotz
9672156a40SMichael Lotz #endif // PARANOID_KERNEL_FREE
9772156a40SMichael Lotz
9872156a40SMichael Lotz
9954f3267eSAxel Dörfler // #pragma mark -
10054f3267eSAxel Dörfler
10154f3267eSAxel Dörfler
102825566f8SIngo Weinhold static DepotMagazine*
alloc_magazine(object_depot * depot,uint32 flags)103ff59ce68SAxel Dörfler alloc_magazine(object_depot* depot, uint32 flags)
104a8806e5eSIngo Weinhold {
105825566f8SIngo Weinhold DepotMagazine* magazine = (DepotMagazine*)slab_internal_alloc(
106ff59ce68SAxel Dörfler sizeof(DepotMagazine) + depot->magazine_capacity * sizeof(void*),
107ff59ce68SAxel Dörfler flags);
108a8806e5eSIngo Weinhold if (magazine) {
109a8806e5eSIngo Weinhold magazine->next = NULL;
110a8806e5eSIngo Weinhold magazine->current_round = 0;
111ff59ce68SAxel Dörfler magazine->round_count = depot->magazine_capacity;
112a8806e5eSIngo Weinhold }
113a8806e5eSIngo Weinhold
114a8806e5eSIngo Weinhold return magazine;
115a8806e5eSIngo Weinhold }
116a8806e5eSIngo Weinhold
117a8806e5eSIngo Weinhold
118a8806e5eSIngo Weinhold static void
free_magazine(DepotMagazine * magazine,uint32 flags)11986c794e5SIngo Weinhold free_magazine(DepotMagazine* magazine, uint32 flags)
120a8806e5eSIngo Weinhold {
12186c794e5SIngo Weinhold slab_internal_free(magazine, flags);
122a8806e5eSIngo Weinhold }
123a8806e5eSIngo Weinhold
124a8806e5eSIngo Weinhold
125a8806e5eSIngo Weinhold static void
empty_magazine(object_depot * depot,DepotMagazine * magazine,uint32 flags)12686c794e5SIngo Weinhold empty_magazine(object_depot* depot, DepotMagazine* magazine, uint32 flags)
127a8806e5eSIngo Weinhold {
128a8806e5eSIngo Weinhold for (uint16 i = 0; i < magazine->current_round; i++)
12986c794e5SIngo Weinhold depot->return_object(depot, depot->cookie, magazine->rounds[i], flags);
13086c794e5SIngo Weinhold free_magazine(magazine, flags);
131a8806e5eSIngo Weinhold }
132a8806e5eSIngo Weinhold
133a8806e5eSIngo Weinhold
134a8806e5eSIngo Weinhold static bool
exchange_with_full(object_depot * depot,DepotMagazine * & magazine)135825566f8SIngo Weinhold exchange_with_full(object_depot* depot, DepotMagazine*& magazine)
136a8806e5eSIngo Weinhold {
137ff59ce68SAxel Dörfler ASSERT(magazine->IsEmpty());
138ff59ce68SAxel Dörfler
139453a2bddSIngo Weinhold SpinLocker _(depot->inner_lock);
140a8806e5eSIngo Weinhold
141a8806e5eSIngo Weinhold if (depot->full == NULL)
142a8806e5eSIngo Weinhold return false;
143a8806e5eSIngo Weinhold
144a8806e5eSIngo Weinhold depot->full_count--;
145a8806e5eSIngo Weinhold depot->empty_count++;
146a8806e5eSIngo Weinhold
147a8806e5eSIngo Weinhold _push(depot->empty, magazine);
148a8806e5eSIngo Weinhold magazine = _pop(depot->full);
149a8806e5eSIngo Weinhold return true;
150a8806e5eSIngo Weinhold }
151a8806e5eSIngo Weinhold
152a8806e5eSIngo Weinhold
153a8806e5eSIngo Weinhold static bool
exchange_with_empty(object_depot * depot,DepotMagazine * & magazine,DepotMagazine * & freeMagazine)154ff59ce68SAxel Dörfler exchange_with_empty(object_depot* depot, DepotMagazine*& magazine,
155ff59ce68SAxel Dörfler DepotMagazine*& freeMagazine)
156a8806e5eSIngo Weinhold {
157ff59ce68SAxel Dörfler ASSERT(magazine == NULL || magazine->IsFull());
158ff59ce68SAxel Dörfler
159453a2bddSIngo Weinhold SpinLocker _(depot->inner_lock);
160a8806e5eSIngo Weinhold
161a8806e5eSIngo Weinhold if (depot->empty == NULL)
162a8806e5eSIngo Weinhold return false;
163453a2bddSIngo Weinhold
164a8806e5eSIngo Weinhold depot->empty_count--;
165a8806e5eSIngo Weinhold
166ff59ce68SAxel Dörfler if (magazine != NULL) {
167ff59ce68SAxel Dörfler if (depot->full_count < depot->max_count) {
168a8806e5eSIngo Weinhold _push(depot->full, magazine);
169a8806e5eSIngo Weinhold depot->full_count++;
1702a196c63SIngo Weinhold freeMagazine = NULL;
171ff59ce68SAxel Dörfler } else
172ff59ce68SAxel Dörfler freeMagazine = magazine;
173a8806e5eSIngo Weinhold }
174a8806e5eSIngo Weinhold
175a8806e5eSIngo Weinhold magazine = _pop(depot->empty);
176a8806e5eSIngo Weinhold return true;
177a8806e5eSIngo Weinhold }
178a8806e5eSIngo Weinhold
179a8806e5eSIngo Weinhold
180453a2bddSIngo Weinhold static void
push_empty_magazine(object_depot * depot,DepotMagazine * magazine)181453a2bddSIngo Weinhold push_empty_magazine(object_depot* depot, DepotMagazine* magazine)
182453a2bddSIngo Weinhold {
183453a2bddSIngo Weinhold SpinLocker _(depot->inner_lock);
184453a2bddSIngo Weinhold
185453a2bddSIngo Weinhold _push(depot->empty, magazine);
18654f3267eSAxel Dörfler depot->empty_count++;
187453a2bddSIngo Weinhold }
188453a2bddSIngo Weinhold
189453a2bddSIngo Weinhold
190a8806e5eSIngo Weinhold static inline depot_cpu_store*
object_depot_cpu(object_depot * depot)191a8806e5eSIngo Weinhold object_depot_cpu(object_depot* depot)
192a8806e5eSIngo Weinhold {
193a8806e5eSIngo Weinhold return &depot->stores[smp_get_current_cpu()];
194a8806e5eSIngo Weinhold }
195a8806e5eSIngo Weinhold
196a8806e5eSIngo Weinhold
197453a2bddSIngo Weinhold // #pragma mark - public API
198453a2bddSIngo Weinhold
199453a2bddSIngo Weinhold
200453a2bddSIngo Weinhold status_t
object_depot_init(object_depot * depot,size_t capacity,size_t maxCount,uint32 flags,void * cookie,void (* return_object)(object_depot * depot,void * cookie,void * object,uint32 flags))201ff59ce68SAxel Dörfler object_depot_init(object_depot* depot, size_t capacity, size_t maxCount,
202ff59ce68SAxel Dörfler uint32 flags, void* cookie, void (*return_object)(object_depot* depot,
203ff59ce68SAxel Dörfler void* cookie, void* object, uint32 flags))
204a8806e5eSIngo Weinhold {
205453a2bddSIngo Weinhold depot->full = NULL;
206453a2bddSIngo Weinhold depot->empty = NULL;
207453a2bddSIngo Weinhold depot->full_count = depot->empty_count = 0;
208ff59ce68SAxel Dörfler depot->max_count = maxCount;
209ff59ce68SAxel Dörfler depot->magazine_capacity = capacity;
210453a2bddSIngo Weinhold
211453a2bddSIngo Weinhold rw_lock_init(&depot->outer_lock, "object depot");
212453a2bddSIngo Weinhold B_INITIALIZE_SPINLOCK(&depot->inner_lock);
213453a2bddSIngo Weinhold
214453a2bddSIngo Weinhold int cpuCount = smp_get_num_cpus();
215453a2bddSIngo Weinhold depot->stores = (depot_cpu_store*)slab_internal_alloc(
216453a2bddSIngo Weinhold sizeof(depot_cpu_store) * cpuCount, flags);
217453a2bddSIngo Weinhold if (depot->stores == NULL) {
218453a2bddSIngo Weinhold rw_lock_destroy(&depot->outer_lock);
219453a2bddSIngo Weinhold return B_NO_MEMORY;
220453a2bddSIngo Weinhold }
221453a2bddSIngo Weinhold
222453a2bddSIngo Weinhold for (int i = 0; i < cpuCount; i++) {
223453a2bddSIngo Weinhold depot->stores[i].loaded = NULL;
224453a2bddSIngo Weinhold depot->stores[i].previous = NULL;
225453a2bddSIngo Weinhold }
226453a2bddSIngo Weinhold
227453a2bddSIngo Weinhold depot->cookie = cookie;
228453a2bddSIngo Weinhold depot->return_object = return_object;
229453a2bddSIngo Weinhold
230453a2bddSIngo Weinhold return B_OK;
231453a2bddSIngo Weinhold }
232453a2bddSIngo Weinhold
233453a2bddSIngo Weinhold
234453a2bddSIngo Weinhold void
object_depot_destroy(object_depot * depot,uint32 flags)23586c794e5SIngo Weinhold object_depot_destroy(object_depot* depot, uint32 flags)
236453a2bddSIngo Weinhold {
23786c794e5SIngo Weinhold object_depot_make_empty(depot, flags);
238453a2bddSIngo Weinhold
23986c794e5SIngo Weinhold slab_internal_free(depot->stores, flags);
240453a2bddSIngo Weinhold
241453a2bddSIngo Weinhold rw_lock_destroy(&depot->outer_lock);
242453a2bddSIngo Weinhold }
243453a2bddSIngo Weinhold
244453a2bddSIngo Weinhold
245453a2bddSIngo Weinhold void*
object_depot_obtain(object_depot * depot)246453a2bddSIngo Weinhold object_depot_obtain(object_depot* depot)
247453a2bddSIngo Weinhold {
248453a2bddSIngo Weinhold ReadLocker readLocker(depot->outer_lock);
249453a2bddSIngo Weinhold InterruptsLocker interruptsLocker;
250453a2bddSIngo Weinhold
251453a2bddSIngo Weinhold depot_cpu_store* store = object_depot_cpu(depot);
252a8806e5eSIngo Weinhold
253a8806e5eSIngo Weinhold // To better understand both the Alloc() and Free() logic refer to
254a8806e5eSIngo Weinhold // Bonwick's ``Magazines and Vmem'' [in 2001 USENIX proceedings]
255a8806e5eSIngo Weinhold
256a8806e5eSIngo Weinhold // In a nutshell, we try to get an object from the loaded magazine
257a8806e5eSIngo Weinhold // if it's not empty, or from the previous magazine if it's full
258a8806e5eSIngo Weinhold // and finally from the Slab if the magazine depot has no full magazines.
259a8806e5eSIngo Weinhold
260a8806e5eSIngo Weinhold if (store->loaded == NULL)
261a8806e5eSIngo Weinhold return NULL;
262a8806e5eSIngo Weinhold
263a8806e5eSIngo Weinhold while (true) {
264825566f8SIngo Weinhold if (!store->loaded->IsEmpty())
265825566f8SIngo Weinhold return store->loaded->Pop();
266a8806e5eSIngo Weinhold
267825566f8SIngo Weinhold if (store->previous
268825566f8SIngo Weinhold && (store->previous->IsFull()
269825566f8SIngo Weinhold || exchange_with_full(depot, store->previous))) {
270a8806e5eSIngo Weinhold std::swap(store->previous, store->loaded);
271825566f8SIngo Weinhold } else
272a8806e5eSIngo Weinhold return NULL;
273a8806e5eSIngo Weinhold }
274a8806e5eSIngo Weinhold }
275a8806e5eSIngo Weinhold
276a8806e5eSIngo Weinhold
277464d9f12SIngo Weinhold void
object_depot_store(object_depot * depot,void * object,uint32 flags)27886c794e5SIngo Weinhold object_depot_store(object_depot* depot, void* object, uint32 flags)
279a8806e5eSIngo Weinhold {
280453a2bddSIngo Weinhold ReadLocker readLocker(depot->outer_lock);
281453a2bddSIngo Weinhold InterruptsLocker interruptsLocker;
282453a2bddSIngo Weinhold
283453a2bddSIngo Weinhold depot_cpu_store* store = object_depot_cpu(depot);
284a8806e5eSIngo Weinhold
285a8806e5eSIngo Weinhold // We try to add the object to the loaded magazine if we have one
286a8806e5eSIngo Weinhold // and it's not full, or to the previous one if it is empty. If
287a8806e5eSIngo Weinhold // the magazine depot doesn't provide us with a new empty magazine
288a8806e5eSIngo Weinhold // we return the object directly to the slab.
289a8806e5eSIngo Weinhold
290a8806e5eSIngo Weinhold while (true) {
291ff59ce68SAxel Dörfler if (store->loaded != NULL && store->loaded->Push(object))
292464d9f12SIngo Weinhold return;
293a8806e5eSIngo Weinhold
2942a196c63SIngo Weinhold DepotMagazine* freeMagazine = NULL;
295ff59ce68SAxel Dörfler if ((store->previous != NULL && store->previous->IsEmpty())
296ff59ce68SAxel Dörfler || exchange_with_empty(depot, store->previous, freeMagazine)) {
297a8806e5eSIngo Weinhold std::swap(store->loaded, store->previous);
298ff59ce68SAxel Dörfler
299ff59ce68SAxel Dörfler if (freeMagazine != NULL) {
300ff59ce68SAxel Dörfler // Free the magazine that didn't have space in the list
301ff59ce68SAxel Dörfler interruptsLocker.Unlock();
302ff59ce68SAxel Dörfler readLocker.Unlock();
303ff59ce68SAxel Dörfler
304ff59ce68SAxel Dörfler empty_magazine(depot, freeMagazine, flags);
305ff59ce68SAxel Dörfler
306ff59ce68SAxel Dörfler readLocker.Lock();
307ff59ce68SAxel Dörfler interruptsLocker.Lock();
308ff59ce68SAxel Dörfler
309ff59ce68SAxel Dörfler store = object_depot_cpu(depot);
310ff59ce68SAxel Dörfler }
311453a2bddSIngo Weinhold } else {
312453a2bddSIngo Weinhold // allocate a new empty magazine
313453a2bddSIngo Weinhold interruptsLocker.Unlock();
314453a2bddSIngo Weinhold readLocker.Unlock();
315453a2bddSIngo Weinhold
316ff59ce68SAxel Dörfler DepotMagazine* magazine = alloc_magazine(depot, flags);
317462dd94aSIngo Weinhold if (magazine == NULL) {
318462dd94aSIngo Weinhold depot->return_object(depot, depot->cookie, object, flags);
319464d9f12SIngo Weinhold return;
320462dd94aSIngo Weinhold }
321453a2bddSIngo Weinhold
322453a2bddSIngo Weinhold readLocker.Lock();
323453a2bddSIngo Weinhold interruptsLocker.Lock();
324453a2bddSIngo Weinhold
325453a2bddSIngo Weinhold push_empty_magazine(depot, magazine);
326453a2bddSIngo Weinhold store = object_depot_cpu(depot);
327a8806e5eSIngo Weinhold }
328a8806e5eSIngo Weinhold }
329a8806e5eSIngo Weinhold }
330a8806e5eSIngo Weinhold
331a8806e5eSIngo Weinhold
332a8806e5eSIngo Weinhold void
object_depot_make_empty(object_depot * depot,uint32 flags)33386c794e5SIngo Weinhold object_depot_make_empty(object_depot* depot, uint32 flags)
334a8806e5eSIngo Weinhold {
335453a2bddSIngo Weinhold WriteLocker writeLocker(depot->outer_lock);
336453a2bddSIngo Weinhold
337453a2bddSIngo Weinhold // collect the store magazines
338453a2bddSIngo Weinhold
339453a2bddSIngo Weinhold DepotMagazine* storeMagazines = NULL;
340453a2bddSIngo Weinhold
341bcf73b3aSIngo Weinhold int cpuCount = smp_get_num_cpus();
342bcf73b3aSIngo Weinhold for (int i = 0; i < cpuCount; i++) {
343453a2bddSIngo Weinhold depot_cpu_store& store = depot->stores[i];
344a8806e5eSIngo Weinhold
345453a2bddSIngo Weinhold if (store.loaded) {
346453a2bddSIngo Weinhold _push(storeMagazines, store.loaded);
347453a2bddSIngo Weinhold store.loaded = NULL;
348a8806e5eSIngo Weinhold }
349a8806e5eSIngo Weinhold
350453a2bddSIngo Weinhold if (store.previous) {
351453a2bddSIngo Weinhold _push(storeMagazines, store.previous);
352453a2bddSIngo Weinhold store.previous = NULL;
353453a2bddSIngo Weinhold }
354453a2bddSIngo Weinhold }
355a8806e5eSIngo Weinhold
356453a2bddSIngo Weinhold // detach the depot's full and empty magazines
357a8806e5eSIngo Weinhold
358453a2bddSIngo Weinhold DepotMagazine* fullMagazines = depot->full;
359453a2bddSIngo Weinhold depot->full = NULL;
360453a2bddSIngo Weinhold
361453a2bddSIngo Weinhold DepotMagazine* emptyMagazines = depot->empty;
362453a2bddSIngo Weinhold depot->empty = NULL;
363453a2bddSIngo Weinhold
364453a2bddSIngo Weinhold writeLocker.Unlock();
365453a2bddSIngo Weinhold
366453a2bddSIngo Weinhold // free all magazines
367453a2bddSIngo Weinhold
368453a2bddSIngo Weinhold while (storeMagazines != NULL)
36986c794e5SIngo Weinhold empty_magazine(depot, _pop(storeMagazines), flags);
370453a2bddSIngo Weinhold
371453a2bddSIngo Weinhold while (fullMagazines != NULL)
37286c794e5SIngo Weinhold empty_magazine(depot, _pop(fullMagazines), flags);
373453a2bddSIngo Weinhold
374453a2bddSIngo Weinhold while (emptyMagazines)
37586c794e5SIngo Weinhold free_magazine(_pop(emptyMagazines), flags);
376a8806e5eSIngo Weinhold }
37754f3267eSAxel Dörfler
37854f3267eSAxel Dörfler
37972156a40SMichael Lotz #if PARANOID_KERNEL_FREE
38072156a40SMichael Lotz
38172156a40SMichael Lotz bool
object_depot_contains_object(object_depot * depot,void * object)38272156a40SMichael Lotz object_depot_contains_object(object_depot* depot, void* object)
38372156a40SMichael Lotz {
38472156a40SMichael Lotz WriteLocker writeLocker(depot->outer_lock);
38572156a40SMichael Lotz
38672156a40SMichael Lotz int cpuCount = smp_get_num_cpus();
38772156a40SMichael Lotz for (int i = 0; i < cpuCount; i++) {
38872156a40SMichael Lotz depot_cpu_store& store = depot->stores[i];
38972156a40SMichael Lotz
39072156a40SMichael Lotz if (store.loaded != NULL && !store.loaded->IsEmpty()) {
39172156a40SMichael Lotz if (store.loaded->ContainsObject(object))
39272156a40SMichael Lotz return true;
39372156a40SMichael Lotz }
39472156a40SMichael Lotz
39572156a40SMichael Lotz if (store.previous != NULL && !store.previous->IsEmpty()) {
39672156a40SMichael Lotz if (store.previous->ContainsObject(object))
39772156a40SMichael Lotz return true;
39872156a40SMichael Lotz }
39972156a40SMichael Lotz }
40072156a40SMichael Lotz
40172156a40SMichael Lotz for (DepotMagazine* magazine = depot->full; magazine != NULL;
40272156a40SMichael Lotz magazine = magazine->next) {
40372156a40SMichael Lotz if (magazine->ContainsObject(object))
40472156a40SMichael Lotz return true;
40572156a40SMichael Lotz }
40672156a40SMichael Lotz
40772156a40SMichael Lotz return false;
40872156a40SMichael Lotz }
40972156a40SMichael Lotz
41072156a40SMichael Lotz #endif // PARANOID_KERNEL_FREE
41172156a40SMichael Lotz
41272156a40SMichael Lotz
41354f3267eSAxel Dörfler // #pragma mark - private kernel API
41454f3267eSAxel Dörfler
41554f3267eSAxel Dörfler
41654f3267eSAxel Dörfler void
dump_object_depot(object_depot * depot)41754f3267eSAxel Dörfler dump_object_depot(object_depot* depot)
41854f3267eSAxel Dörfler {
41954f3267eSAxel Dörfler kprintf(" full: %p, count %lu\n", depot->full, depot->full_count);
42054f3267eSAxel Dörfler kprintf(" empty: %p, count %lu\n", depot->empty, depot->empty_count);
4216426413dSAxel Dörfler kprintf(" max full: %lu\n", depot->max_count);
4226426413dSAxel Dörfler kprintf(" capacity: %lu\n", depot->magazine_capacity);
42354f3267eSAxel Dörfler kprintf(" stores:\n");
42454f3267eSAxel Dörfler
42554f3267eSAxel Dörfler int cpuCount = smp_get_num_cpus();
42654f3267eSAxel Dörfler
42754f3267eSAxel Dörfler for (int i = 0; i < cpuCount; i++) {
42854f3267eSAxel Dörfler kprintf(" [%d] loaded: %p\n", i, depot->stores[i].loaded);
42954f3267eSAxel Dörfler kprintf(" previous: %p\n", depot->stores[i].previous);
43054f3267eSAxel Dörfler }
43154f3267eSAxel Dörfler }
43254f3267eSAxel Dörfler
43354f3267eSAxel Dörfler
43454f3267eSAxel Dörfler int
dump_object_depot(int argCount,char ** args)43554f3267eSAxel Dörfler dump_object_depot(int argCount, char** args)
43654f3267eSAxel Dörfler {
43754f3267eSAxel Dörfler if (argCount != 2)
43854f3267eSAxel Dörfler kprintf("usage: %s [address]\n", args[0]);
43954f3267eSAxel Dörfler else
44054f3267eSAxel Dörfler dump_object_depot((object_depot*)parse_expression(args[1]));
44154f3267eSAxel Dörfler
44254f3267eSAxel Dörfler return 0;
44354f3267eSAxel Dörfler }
44454f3267eSAxel Dörfler
44554f3267eSAxel Dörfler
44654f3267eSAxel Dörfler int
dump_depot_magazine(int argCount,char ** args)44754f3267eSAxel Dörfler dump_depot_magazine(int argCount, char** args)
44854f3267eSAxel Dörfler {
44954f3267eSAxel Dörfler if (argCount != 2) {
45054f3267eSAxel Dörfler kprintf("usage: %s [address]\n", args[0]);
45154f3267eSAxel Dörfler return 0;
45254f3267eSAxel Dörfler }
45354f3267eSAxel Dörfler
45454f3267eSAxel Dörfler DepotMagazine* magazine = (DepotMagazine*)parse_expression(args[1]);
45554f3267eSAxel Dörfler
45654f3267eSAxel Dörfler kprintf("next: %p\n", magazine->next);
45754f3267eSAxel Dörfler kprintf("current_round: %u\n", magazine->current_round);
45854f3267eSAxel Dörfler kprintf("round_count: %u\n", magazine->round_count);
45954f3267eSAxel Dörfler
46054f3267eSAxel Dörfler for (uint16 i = 0; i < magazine->current_round; i++)
46154f3267eSAxel Dörfler kprintf(" [%i] %p\n", i, magazine->rounds[i]);
46254f3267eSAxel Dörfler
46354f3267eSAxel Dörfler return 0;
46454f3267eSAxel Dörfler }
465*e1c6140eSIngo Weinhold
466*e1c6140eSIngo Weinhold
467*e1c6140eSIngo Weinhold RANGE_MARKER_FUNCTION_END(SlabObjectDepot)
468