2 * Copyright 2008-2010, Axel Dörfler. All Rights Reserved.
3 * Copyright 2007, Hugo Santos. All Rights Reserved.
5 * Distributed under the terms of the MIT License.
11 #include <condition_variable.h>
13 #include <slab/ObjectDepot.h>
14 #include <slab/Slab.h>
15 #include <util/DoublyLinkedList.h>
17 #include "kernel_debug_config.h"
18 #include "slab_debug.h"
25 struct object_link
* next
;
28 struct slab
: DoublyLinkedListLinkImpl
<slab
> {
30 size_t size
; // total number of objects
31 size_t count
; // free objects
34 #if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
35 AllocationTrackingInfo
* tracking
;
39 typedef DoublyLinkedList
<slab
> SlabList
;
41 struct ObjectCacheResizeEntry
{
42 ConditionVariable condition
;
46 struct ObjectCache
: DoublyLinkedListLinkImpl
<ObjectCache
> {
51 size_t cache_color_cycle
;
55 size_t total_objects
; // total number of objects
56 size_t used_count
; // used objects
57 size_t empty_count
; // empty slabs
59 size_t min_object_reserve
;
60 // minimum number of free objects
67 ResizeRequest
* resize_request
;
69 ObjectCacheResizeEntry
* resize_entry_can_wait
;
70 ObjectCacheResizeEntry
* resize_entry_dont_wait
;
72 DoublyLinkedListLink
<ObjectCache
> maintenance_link
;
73 bool maintenance_pending
;
74 bool maintenance_in_progress
;
75 bool maintenance_resize
;
76 bool maintenance_delete
;
79 object_cache_constructor constructor
;
80 object_cache_destructor destructor
;
81 object_cache_reclaimer reclaimer
;
86 virtual ~ObjectCache();
88 status_t
Init(const char* name
, size_t objectSize
,
89 size_t alignment
, size_t maximum
,
90 size_t magazineCapacity
,
91 size_t maxMagazineCount
, uint32 flags
,
93 object_cache_constructor constructor
,
94 object_cache_destructor destructor
,
95 object_cache_reclaimer reclaimer
);
96 virtual void Delete() = 0;
98 virtual slab
* CreateSlab(uint32 flags
) = 0;
99 virtual void ReturnSlab(slab
* slab
, uint32 flags
) = 0;
100 virtual slab
* ObjectSlab(void* object
) const = 0;
102 slab
* InitSlab(slab
* slab
, void* pages
,
103 size_t byteCount
, uint32 flags
);
104 void UninitSlab(slab
* slab
);
106 void ReturnObjectToSlab(slab
* source
, void* object
,
108 void* ObjectAtIndex(slab
* source
, int32 index
) const;
110 bool Lock() { return mutex_lock(&lock
) == B_OK
; }
111 void Unlock() { mutex_unlock(&lock
); }
113 status_t
AllocatePages(void** pages
, uint32 flags
);
114 void FreePages(void* pages
);
115 status_t
EarlyAllocatePages(void** pages
, uint32 flags
);
116 void EarlyFreePages(void* pages
);
118 #if PARANOID_KERNEL_FREE
119 bool AssertObjectNotFreed(void* object
);
122 status_t
AllocateTrackingInfos(slab
* slab
,
123 size_t byteCount
, uint32 flags
);
124 void FreeTrackingInfos(slab
* slab
, uint32 flags
);
126 #if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
127 AllocationTrackingInfo
*
128 TrackingInfoFor(void* object
) const;
134 link_to_object(object_link
* link
, size_t objectSize
)
136 return ((uint8
*)link
) - (objectSize
- sizeof(object_link
));
140 static inline object_link
*
141 object_to_link(void* object
, size_t objectSize
)
143 return (object_link
*)(((uint8
*)object
)
144 + (objectSize
- sizeof(object_link
)));
149 lower_boundary(const void* object
, size_t byteCount
)
151 return (void*)((addr_t
)object
& ~(byteCount
- 1));
156 check_cache_quota(ObjectCache
* cache
)
158 if (cache
->maximum
== 0)
161 return (cache
->usage
+ cache
->slab_size
) <= cache
->maximum
;
165 #if !SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
168 ObjectCache::AllocateTrackingInfos(slab
* slab
, size_t byteCount
, uint32 flags
)
175 ObjectCache::FreeTrackingInfos(slab
* slab
, uint32 flags
)
179 #endif // !SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
181 #endif // OBJECT_CACHE_H