3 #include <ddekit/lock.h>
4 #include <ddekit/memory.h>
5 #include <ddekit/panic.h>
6 #include <ddekit/pgtab.h>
7 #include <ddekit/inline.h>
8 #include <ddekit/types.h>
10 #ifdef DDEKIT_DEBUG_MEM
12 #define DDEBUG DDEKIT_DEBUG_MEM
17 #define SLAB_SIZE (4096*4)
21 struct ddekit_slab_slab
{
22 struct ddekit_slab
* cache
;
26 struct ddekit_slab_slab
*next
;
27 struct ddekit_slab_slab
*prev
;
32 void * data
; /* user pointer */
33 int contiguous
; /* is it coniguous mem*/
34 unsigned size
; /* the size of he objects */
35 unsigned number
; /* the number of objects stored per slab */
36 struct ddekit_slab_slab full
;
37 struct ddekit_slab_slab partial
;
38 struct ddekit_slab_slab empty
;
41 static void ddekit_slab_lock(struct ddekit_slab
* sc
);
42 static void ddekit_slab_unlock(struct ddekit_slab
* sc
);
43 static struct ddekit_slab_slab
* ddekit_slab_find_slab(struct
44 ddekit_slab
* sc
, void * obj
);
45 static void ddekit_slab_slab_insert(struct ddekit_slab_slab
*list
,
46 struct ddekit_slab_slab
*s
);
47 static void ddekit_slab_slab_remove(struct ddekit_slab_slab
*s
);
48 static void ddekit_slab_grow(struct ddekit_slab
* sc
);
49 static void *ddekit_slab_getobj(struct ddekit_slab_slab
*s
);
50 static void ddekit_slab_free_slab(struct ddekit_slab_slab
* sl
, int
53 /******************************************************************************
54 * ddekit_simple_malloc *
55 *****************************************************************************/
56 void *ddekit_simple_malloc(unsigned size
)
58 /* Simple memory allocation... malloc and free should be ok... */
59 void * r
= malloc(size
);
61 ddekit_panic("out of mem?");
63 DDEBUG_MSG_VERBOSE("%p", r
);
67 /******************************************************************************
68 * ddekit_simple_free *
69 *****************************************************************************/
70 void ddekit_simple_free(void *p
)
72 DDEBUG_MSG_VERBOSE("%p", p
);
76 /******************************************************************************
77 * ddekit_large_malloc *
78 *****************************************************************************/
79 void *ddekit_large_malloc(int size
)
82 /* allocate a piece of coniguous memory */
83 void * r
= alloc_contig(size
, AC_ALIGN4K
, &phys
);
85 ddekit_panic("out of mem?");
87 ddekit_pgtab_set_region_with_size(r
, phys
, size
, PTE_TYPE_LARGE
);
88 DDEBUG_MSG_VERBOSE("%p, phys: %p, size: %p.",r
, phys
, size
);
89 DDEBUG_MSG_VERBOSE("%p", r
);
93 /******************************************************************************
95 *****************************************************************************/
96 void ddekit_large_free(void *p
)
99 DDEBUG_MSG_VERBOSE("get size of region %x", p
);
100 len
= ddekit_pgtab_get_size(p
);
101 DDEBUG_MSG_VERBOSE("freeing %x, len %d...", p
, len
);
102 ddekit_pgtab_clear_region(p
, 0); /* type is not used here... */
103 DDEBUG_MSG_VERBOSE("cleared region", p
, len
);
105 DDEBUG_MSG_VERBOSE("freed mem", p
, len
);
106 DDEBUG_MSG_VERBOSE("%p", p
);
109 /******************************************************************************
110 * ddekit_contig_malloc *
111 *****************************************************************************/
112 void *ddekit_contig_malloc(unsigned long size
, unsigned long low
,
113 unsigned long high
, unsigned long aligment
,
114 unsigned long boundary
)
120 /******************************************************************************
122 *****************************************************************************/
123 static DDEKIT_INLINE
void ddekit_slab_lock(struct ddekit_slab
* sc
) {
124 ddekit_lock_lock(&sc
->lock
);
127 /******************************************************************************
128 * ddekit_slab_unlock *
129 *****************************************************************************/
130 static DDEKIT_INLINE
void ddekit_slab_unlock(struct ddekit_slab
* sc
) {
131 ddekit_lock_unlock(&sc
->lock
);
134 /******************************************************************************
135 * ddekit_slab_find_slab *
136 *****************************************************************************/
137 static struct ddekit_slab_slab
*
138 ddekit_slab_find_slab(struct ddekit_slab
* sc
, void * obj
)
141 struct ddekit_slab_slab
*s
;
143 for( s
= sc
->full
.next
; s
!=&sc
->full
; s
= s
->next
)
145 if (s
->mem
<= obj
&& obj
< s
->mem
+(SLAB_SIZE
))
151 for( s
= sc
->partial
.next
; s
!=&sc
->partial
; s
= s
->next
)
153 if (s
->mem
<= obj
&& obj
< s
->mem
+(SLAB_SIZE
))
162 /******************************************************************************
163 * ddekit_slab_slab_insert *
164 *****************************************************************************/
165 static void ddekit_slab_slab_insert(struct ddekit_slab_slab
*list
,
166 struct ddekit_slab_slab
*s
)
169 s
->next
= list
->next
;
170 list
->next
->prev
= s
;
174 /******************************************************************************
175 * ddekit_slab_slab_remove *
176 *****************************************************************************/
177 static void ddekit_slab_slab_remove(struct ddekit_slab_slab
*s
)
179 s
->next
->prev
= s
->prev
;
180 s
->prev
->next
= s
->next
;
181 s
->next
= s
->prev
= 0;
185 /******************************************************************************
187 *****************************************************************************/
188 static void ddekit_slab_grow(struct ddekit_slab
*sc
)
192 * As it doesn't seem to make problems ddekit_slabs are disregarding
193 * alignment. However this should be revisited, maybe this leads to
194 * performance degregation somewhere.
195 * Further the ddekit_slab doesn't have to be real slab, as the entries are
196 * initialized in the personalized DDEs. (slab is simple the wrong name.)
201 struct ddekit_slab_slab
*s
;
203 /* allocate slab control structure */
205 s
= (struct ddekit_slab_slab
*)
206 ddekit_simple_malloc(sizeof(struct ddekit_slab_slab
));
211 s
->mem
= ddekit_large_malloc(SLAB_SIZE
);
213 s
->mem
= ddekit_simple_malloc(SLAB_SIZE
);
215 /* setup the object list */
217 s
->free
= sc
->number
;
219 /* put obj into list */
224 DDEBUG_MSG_VERBOSE("obj size: %d, memory at: %p , first obj: %p, %p ",
225 sc
->size
, s
->mem
, s
->objects
);
227 for (i
= 0; i
< s
->free
; i
++)
230 p1
= (void **) (p
+ sc
->size
);
232 if ( i
!= s
->free
-1 )
235 DDEBUG_MSG_VERBOSE("%p, %p -> %p", p
, p1
, *p1
);
240 DDEBUG_MSG_VERBOSE("%p, %p -> %p", p
, p1
, *p1
);
244 /* add new slab to free list */
245 ddekit_slab_slab_insert(&sc
->empty
, s
);
249 /******************************************************************************
250 * ddekit_slab_getobj *
251 *****************************************************************************/
252 static void *ddekit_slab_getobj(struct ddekit_slab_slab
*s
)
254 struct ddekit_slab
*sc
;
260 /* get pointer to next object */
262 s
->objects
= *(void **)((char *) ret
+ sc
->size
);
265 DDEBUG_MSG_VERBOSE("old: %p new: %p", ret
, s
->objects
);
267 /* if no more objects move to full */
271 ddekit_slab_slab_remove(s
);
272 ddekit_slab_slab_insert(&sc
->full
,s
);
275 if (s
->free
== sc
->number
-1)
277 ddekit_slab_slab_remove(s
);
278 ddekit_slab_slab_insert(&sc
->partial
,s
);
284 /******************************************************************************
285 * ddekit_slab_alloc *
286 *****************************************************************************/
287 void *ddekit_slab_alloc(struct ddekit_slab
* sc
)
289 struct ddekit_slab_slab
*s
=0;
291 ddekit_slab_lock(sc
);
293 DDEBUG_MSG_VERBOSE("from slab %p", sc
);
295 /* first try from partial */
296 if (sc
->partial
.next
!= &sc
->partial
) {
297 DDEBUG_MSG_VERBOSE("from slab %p partial (next=%p)", sc
,sc
->partial
.next
);
298 s
= sc
->partial
.next
;
302 if (!s
&& (sc
->empty
.next
== &sc
->empty
)){
303 DDEBUG_MSG_VERBOSE("slab %p has to grow", sc
);
304 ddekit_slab_grow(sc
);
307 /* take from free? */
309 DDEBUG_MSG_VERBOSE("from slab %p empty", sc
);
313 ddekit_slab_unlock(sc
);
315 return ddekit_slab_getobj(s
);
318 /******************************************************************************
320 *****************************************************************************/
321 void ddekit_slab_free(struct ddekit_slab
*sc
, void* obj
)
325 struct ddekit_slab_slab
*s
= 0;
327 ddekit_slab_lock(sc
);
328 /* first find slab the obj came from */
330 s
= ddekit_slab_find_slab(sc
, obj
);
332 p
= (void **)((char *) obj
+ sc
->size
);
337 DDEBUG_MSG_VERBOSE("old: %p, new: %p",*p
,s
->objects
);
341 if (s
->free
== sc
->number
) {
342 ddekit_slab_slab_remove(s
);
343 ddekit_slab_slab_insert(&sc
->empty
, s
);
347 ddekit_slab_slab_remove(s
);
348 ddekit_slab_slab_insert(&sc
->partial
, s
);
351 ddekit_slab_unlock(sc
);
354 /******************************************************************************
355 * ddekit_slab_set_data *
356 *****************************************************************************/
357 void ddekit_slab_set_data(struct ddekit_slab
* sc
, void *data
)
359 ddekit_slab_lock(sc
);
361 ddekit_slab_unlock(sc
);
364 /******************************************************************************
365 * ddekit_slab_get_data *
366 *****************************************************************************/
367 void *ddekit_slab_get_data (struct ddekit_slab
*sc
)
370 ddekit_slab_lock(sc
);
372 ddekit_slab_unlock(sc
);
377 /******************************************************************************
379 *****************************************************************************/
380 struct ddekit_slab
* ddekit_slab_init(unsigned size
, int contiguous
)
383 struct ddekit_slab
* sc
= 0;
385 sc
= (struct ddekit_slab
*)
386 ddekit_simple_malloc(sizeof(struct ddekit_slab
));
389 sc
->contiguous
= contiguous
;
391 sc
->number
= SLAB_SIZE
/(size
+sizeof(void*));
393 if (sc
->number
== 0) {
394 ddekit_panic("objects too big!");
397 sc
->empty
.next
= sc
->empty
.prev
= &sc
->empty
;
398 sc
->partial
.next
= sc
->partial
.prev
= &sc
->partial
;
399 sc
->full
.next
= sc
->full
.prev
= &sc
->full
;
401 ddekit_lock_init(&sc
->lock
);
403 DDEBUG_MSG_VERBOSE("initialzed slab cache %p: size %x, number %d ",
404 sc
, sc
->size
, sc
->number
);
406 DDEBUG_MSG_VERBOSE("partial %p next %p", &sc
->partial
, sc
->partial
.next
);
412 /******************************************************************************
413 * ddekit_slab_free_slab *
414 *****************************************************************************/
415 static void ddekit_slab_free_slab(struct ddekit_slab_slab
* sl
, int cont
)
418 struct ddekit_slab_slab
*s
,*t
;
421 ddekit_panic("no slab to free!");
424 for ( s
= sl
->next
; s
!= sl
; )
426 DDEBUG_MSG_VERBOSE("cont: %d, %p, s->mem", cont
, s
->mem
);
429 ddekit_large_free(s
->mem
);
433 ddekit_simple_free(s
->mem
);
437 ddekit_simple_free(t
);
442 /******************************************************************************
443 * ddekit_slab_destroy *
444 *****************************************************************************/
445 void ddekit_slab_destroy(struct ddekit_slab
*sc
)
447 DDEBUG_MSG_VERBOSE("%p full", sc
);
448 ddekit_slab_free_slab(&sc
->full
,sc
->contiguous
);
450 DDEBUG_MSG_VERBOSE("%p empty", sc
);
451 ddekit_slab_free_slab(&sc
->empty
,sc
->contiguous
);
453 DDEBUG_MSG_VERBOSE("%p partial", sc
);
454 ddekit_slab_free_slab(&sc
->partial
,sc
->contiguous
);
456 ddekit_lock_deinit(&sc
->lock
);
458 ddekit_simple_free(sc
);