xref: /minix3/minix/lib/libddekit/src/mem.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #include "common.h"
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc #include <ddekit/lock.h>
4*433d6423SLionel Sambuc #include <ddekit/memory.h>
5*433d6423SLionel Sambuc #include <ddekit/panic.h>
6*433d6423SLionel Sambuc #include <ddekit/pgtab.h>
7*433d6423SLionel Sambuc #include <ddekit/inline.h>
8*433d6423SLionel Sambuc #include <ddekit/types.h>
9*433d6423SLionel Sambuc 
10*433d6423SLionel Sambuc #ifdef DDEKIT_DEBUG_MEM
11*433d6423SLionel Sambuc #undef DDEBUG
12*433d6423SLionel Sambuc #define DDEBUG DDEKIT_DEBUG_MEM
13*433d6423SLionel Sambuc #endif
14*433d6423SLionel Sambuc #include "debug.h"
15*433d6423SLionel Sambuc #include "util.h"
16*433d6423SLionel Sambuc 
17*433d6423SLionel Sambuc #define SLAB_SIZE (4096*4)
18*433d6423SLionel Sambuc 
19*433d6423SLionel Sambuc struct ddekit_slab;
20*433d6423SLionel Sambuc 
21*433d6423SLionel Sambuc struct ddekit_slab_slab {
22*433d6423SLionel Sambuc 	struct ddekit_slab * cache;
23*433d6423SLionel Sambuc 	unsigned long free;
24*433d6423SLionel Sambuc 	void *objects;
25*433d6423SLionel Sambuc 	void *mem;
26*433d6423SLionel Sambuc 	struct ddekit_slab_slab *next;
27*433d6423SLionel Sambuc 	struct ddekit_slab_slab *prev;
28*433d6423SLionel Sambuc };
29*433d6423SLionel Sambuc 
30*433d6423SLionel Sambuc struct ddekit_slab {
31*433d6423SLionel Sambuc 	ddekit_lock_t lock;
32*433d6423SLionel Sambuc 	void * data;    /* user pointer */
33*433d6423SLionel Sambuc 	int contiguous; /* is it coniguous mem*/
34*433d6423SLionel Sambuc 	unsigned size;  /* the size of he objects */
35*433d6423SLionel Sambuc 	unsigned number; /* the number of objects stored per slab */
36*433d6423SLionel Sambuc 	struct ddekit_slab_slab full;
37*433d6423SLionel Sambuc 	struct ddekit_slab_slab partial;
38*433d6423SLionel Sambuc 	struct ddekit_slab_slab empty;
39*433d6423SLionel Sambuc };
40*433d6423SLionel Sambuc 
41*433d6423SLionel Sambuc static void ddekit_slab_lock(struct ddekit_slab * sc);
42*433d6423SLionel Sambuc static void ddekit_slab_unlock(struct ddekit_slab * sc);
43*433d6423SLionel Sambuc static struct ddekit_slab_slab * ddekit_slab_find_slab(struct
44*433d6423SLionel Sambuc 	ddekit_slab * sc, void * obj);
45*433d6423SLionel Sambuc static void ddekit_slab_slab_insert(struct ddekit_slab_slab *list,
46*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s);
47*433d6423SLionel Sambuc static void ddekit_slab_slab_remove(struct ddekit_slab_slab *s);
48*433d6423SLionel Sambuc static void ddekit_slab_grow(struct ddekit_slab * sc);
49*433d6423SLionel Sambuc static void *ddekit_slab_getobj(struct ddekit_slab_slab *s);
50*433d6423SLionel Sambuc static void ddekit_slab_free_slab(struct ddekit_slab_slab * sl, int
51*433d6423SLionel Sambuc 	cont);
52*433d6423SLionel Sambuc 
53*433d6423SLionel Sambuc /******************************************************************************
54*433d6423SLionel Sambuc  *       ddekit_simple_malloc                                                 *
55*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_simple_malloc(unsigned size)56*433d6423SLionel Sambuc void *ddekit_simple_malloc(unsigned size)
57*433d6423SLionel Sambuc {
58*433d6423SLionel Sambuc 	/* Simple memory allocation... malloc and free should be ok... */
59*433d6423SLionel Sambuc 	void * r = malloc(size);
60*433d6423SLionel Sambuc 	if (!r) {
61*433d6423SLionel Sambuc 		ddekit_panic("out of mem?");
62*433d6423SLionel Sambuc 	}
63*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p", r);
64*433d6423SLionel Sambuc 	return r;
65*433d6423SLionel Sambuc }
66*433d6423SLionel Sambuc 
67*433d6423SLionel Sambuc /******************************************************************************
68*433d6423SLionel Sambuc  *       ddekit_simple_free                                                   *
69*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_simple_free(void * p)70*433d6423SLionel Sambuc void ddekit_simple_free(void *p)
71*433d6423SLionel Sambuc {
72*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p", p);
73*433d6423SLionel Sambuc 	free(p);
74*433d6423SLionel Sambuc }
75*433d6423SLionel Sambuc 
76*433d6423SLionel Sambuc /******************************************************************************
77*433d6423SLionel Sambuc  *       ddekit_large_malloc                                                  *
78*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_large_malloc(int size)79*433d6423SLionel Sambuc void *ddekit_large_malloc(int size)
80*433d6423SLionel Sambuc {
81*433d6423SLionel Sambuc 	ddekit_addr_t phys;
82*433d6423SLionel Sambuc 	/* allocate a piece of coniguous memory */
83*433d6423SLionel Sambuc 	void * r = alloc_contig(size, AC_ALIGN4K, &phys);
84*433d6423SLionel Sambuc 	if (!r) {
85*433d6423SLionel Sambuc 		ddekit_panic("out of mem?");
86*433d6423SLionel Sambuc 	}
87*433d6423SLionel Sambuc 	ddekit_pgtab_set_region_with_size(r, phys, size, PTE_TYPE_LARGE);
88*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p, phys: %p, size: %p.",r, phys, size);
89*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p", r);
90*433d6423SLionel Sambuc 	return r;
91*433d6423SLionel Sambuc }
92*433d6423SLionel Sambuc 
93*433d6423SLionel Sambuc /******************************************************************************
94*433d6423SLionel Sambuc  *       ddekit_large_free                                                    *
95*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_large_free(void * p)96*433d6423SLionel Sambuc void ddekit_large_free(void *p)
97*433d6423SLionel Sambuc {
98*433d6423SLionel Sambuc 	unsigned len;
99*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("get size of region %x", p);
100*433d6423SLionel Sambuc 	len= ddekit_pgtab_get_size(p);
101*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("freeing %x, len %d...", p , len);
102*433d6423SLionel Sambuc 	ddekit_pgtab_clear_region(p, 0); /* type is not used here... */
103*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("cleared region", p , len);
104*433d6423SLionel Sambuc 	free_contig(p, len);
105*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("freed mem", p , len);
106*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p", p);
107*433d6423SLionel Sambuc }
108*433d6423SLionel Sambuc 
109*433d6423SLionel Sambuc /******************************************************************************
110*433d6423SLionel Sambuc  *       ddekit_contig_malloc                                                 *
111*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_contig_malloc(unsigned long size,unsigned long low,unsigned long high,unsigned long aligment,unsigned long boundary)112*433d6423SLionel Sambuc void *ddekit_contig_malloc(unsigned long size, unsigned long low,
113*433d6423SLionel Sambuc                                   unsigned long high, unsigned long aligment,
114*433d6423SLionel Sambuc                                   unsigned long boundary)
115*433d6423SLionel Sambuc {
116*433d6423SLionel Sambuc 	WARN_UNIMPL;
117*433d6423SLionel Sambuc 	return 0;
118*433d6423SLionel Sambuc }
119*433d6423SLionel Sambuc 
120*433d6423SLionel Sambuc /******************************************************************************
121*433d6423SLionel Sambuc  *       ddekit_slab_lock                                                     *
122*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_lock(struct ddekit_slab * sc)123*433d6423SLionel Sambuc static DDEKIT_INLINE void ddekit_slab_lock(struct ddekit_slab * sc) {
124*433d6423SLionel Sambuc 	ddekit_lock_lock(&sc->lock);
125*433d6423SLionel Sambuc }
126*433d6423SLionel Sambuc 
127*433d6423SLionel Sambuc /******************************************************************************
128*433d6423SLionel Sambuc  *       ddekit_slab_unlock                                                   *
129*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_unlock(struct ddekit_slab * sc)130*433d6423SLionel Sambuc static DDEKIT_INLINE void ddekit_slab_unlock(struct ddekit_slab * sc) {
131*433d6423SLionel Sambuc 	ddekit_lock_unlock(&sc->lock);
132*433d6423SLionel Sambuc }
133*433d6423SLionel Sambuc 
134*433d6423SLionel Sambuc /******************************************************************************
135*433d6423SLionel Sambuc  *       ddekit_slab_find_slab                                                *
136*433d6423SLionel Sambuc  *****************************************************************************/
137*433d6423SLionel Sambuc static struct ddekit_slab_slab *
ddekit_slab_find_slab(struct ddekit_slab * sc,void * obj)138*433d6423SLionel Sambuc ddekit_slab_find_slab(struct ddekit_slab * sc, void * obj)
139*433d6423SLionel Sambuc {
140*433d6423SLionel Sambuc 
141*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s;
142*433d6423SLionel Sambuc 
143*433d6423SLionel Sambuc 	for( s = sc->full.next; s!=&sc->full; s = s->next )
144*433d6423SLionel Sambuc 	{
145*433d6423SLionel Sambuc 		if (s->mem <= obj && obj < s->mem+(SLAB_SIZE))
146*433d6423SLionel Sambuc 		{
147*433d6423SLionel Sambuc 				return s;
148*433d6423SLionel Sambuc 		}
149*433d6423SLionel Sambuc 	}
150*433d6423SLionel Sambuc 
151*433d6423SLionel Sambuc 	for( s = sc->partial.next; s!=&sc->partial; s = s->next )
152*433d6423SLionel Sambuc 	{
153*433d6423SLionel Sambuc 		if (s->mem <= obj && obj < s->mem+(SLAB_SIZE))
154*433d6423SLionel Sambuc 		{
155*433d6423SLionel Sambuc 				return s;
156*433d6423SLionel Sambuc 		}
157*433d6423SLionel Sambuc 	}
158*433d6423SLionel Sambuc 
159*433d6423SLionel Sambuc 	return 0;
160*433d6423SLionel Sambuc }
161*433d6423SLionel Sambuc 
162*433d6423SLionel Sambuc /******************************************************************************
163*433d6423SLionel Sambuc  *       ddekit_slab_slab_insert                                              *
164*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_slab_insert(struct ddekit_slab_slab * list,struct ddekit_slab_slab * s)165*433d6423SLionel Sambuc static void  ddekit_slab_slab_insert(struct ddekit_slab_slab *list,
166*433d6423SLionel Sambuc                                       struct ddekit_slab_slab *s)
167*433d6423SLionel Sambuc {
168*433d6423SLionel Sambuc 	s->prev          = list;
169*433d6423SLionel Sambuc 	s->next          = list->next;
170*433d6423SLionel Sambuc 	list->next->prev = s;
171*433d6423SLionel Sambuc 	list->next       = s;
172*433d6423SLionel Sambuc }
173*433d6423SLionel Sambuc 
174*433d6423SLionel Sambuc /******************************************************************************
175*433d6423SLionel Sambuc  *       ddekit_slab_slab_remove                                              *
176*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_slab_remove(struct ddekit_slab_slab * s)177*433d6423SLionel Sambuc static void ddekit_slab_slab_remove(struct ddekit_slab_slab *s)
178*433d6423SLionel Sambuc {
179*433d6423SLionel Sambuc 	s->next->prev     = s->prev;
180*433d6423SLionel Sambuc 	s->prev->next     = s->next;
181*433d6423SLionel Sambuc 	s->next = s->prev = 0;
182*433d6423SLionel Sambuc }
183*433d6423SLionel Sambuc 
184*433d6423SLionel Sambuc 
185*433d6423SLionel Sambuc /******************************************************************************
186*433d6423SLionel Sambuc  *       ddekit_slab_grow                                                     *
187*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_grow(struct ddekit_slab * sc)188*433d6423SLionel Sambuc static void ddekit_slab_grow(struct ddekit_slab *sc)
189*433d6423SLionel Sambuc {
190*433d6423SLionel Sambuc 	/*
191*433d6423SLionel Sambuc 	 * NOTE:
192*433d6423SLionel Sambuc 	 * As it doesn't seem to make problems ddekit_slabs are disregarding
193*433d6423SLionel Sambuc 	 * alignment.  However this should be revisited, maybe this leads to
194*433d6423SLionel Sambuc 	 * performance degregation somewhere.
195*433d6423SLionel Sambuc 	 * Further the ddekit_slab doesn't have to be real slab, as the entries are
196*433d6423SLionel Sambuc 	 * initialized in the personalized DDEs. (slab is simple the wrong name.)
197*433d6423SLionel Sambuc 	 */
198*433d6423SLionel Sambuc 	int i;
199*433d6423SLionel Sambuc 	char *p;
200*433d6423SLionel Sambuc 	void **p1;
201*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s;
202*433d6423SLionel Sambuc 
203*433d6423SLionel Sambuc 	/* allocate slab control structure */
204*433d6423SLionel Sambuc 
205*433d6423SLionel Sambuc 	s = (struct ddekit_slab_slab *)
206*433d6423SLionel Sambuc 	    ddekit_simple_malloc(sizeof(struct ddekit_slab_slab));
207*433d6423SLionel Sambuc 
208*433d6423SLionel Sambuc 	s->cache = sc;
209*433d6423SLionel Sambuc 
210*433d6423SLionel Sambuc 	if(sc->contiguous)
211*433d6423SLionel Sambuc 		s->mem = ddekit_large_malloc(SLAB_SIZE);
212*433d6423SLionel Sambuc 	else
213*433d6423SLionel Sambuc 		s->mem = ddekit_simple_malloc(SLAB_SIZE);
214*433d6423SLionel Sambuc 
215*433d6423SLionel Sambuc 	/* setup the object list */
216*433d6423SLionel Sambuc 
217*433d6423SLionel Sambuc 	s->free = sc->number;
218*433d6423SLionel Sambuc 
219*433d6423SLionel Sambuc 	/* put obj into list */
220*433d6423SLionel Sambuc 	p1 = s->mem;
221*433d6423SLionel Sambuc 	*p1 = s->mem;
222*433d6423SLionel Sambuc 	s->objects =  p1;
223*433d6423SLionel Sambuc 
224*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("obj size: %d, memory at: %p , first obj: %p, %p ",
225*433d6423SLionel Sambuc 	                    sc->size, s->mem, s->objects);
226*433d6423SLionel Sambuc 
227*433d6423SLionel Sambuc 	for (i = 0; i < s->free; i++)
228*433d6423SLionel Sambuc 	{
229*433d6423SLionel Sambuc 		p  = *p1;
230*433d6423SLionel Sambuc 		p1 = (void **) (p + sc->size);
231*433d6423SLionel Sambuc 
232*433d6423SLionel Sambuc 		if ( i != s->free-1 )
233*433d6423SLionel Sambuc 		{
234*433d6423SLionel Sambuc 			*p1 = p1+1;
235*433d6423SLionel Sambuc 			DDEBUG_MSG_VERBOSE("%p, %p -> %p", p, p1, *p1);
236*433d6423SLionel Sambuc 		}
237*433d6423SLionel Sambuc 		else
238*433d6423SLionel Sambuc 		{
239*433d6423SLionel Sambuc 			*p1 = 0;
240*433d6423SLionel Sambuc 			DDEBUG_MSG_VERBOSE("%p, %p -> %p", p, p1, *p1);
241*433d6423SLionel Sambuc 		}
242*433d6423SLionel Sambuc 	}
243*433d6423SLionel Sambuc 
244*433d6423SLionel Sambuc 	/* add new slab to free list */
245*433d6423SLionel Sambuc 	ddekit_slab_slab_insert(&sc->empty, s);
246*433d6423SLionel Sambuc }
247*433d6423SLionel Sambuc 
248*433d6423SLionel Sambuc 
249*433d6423SLionel Sambuc /******************************************************************************
250*433d6423SLionel Sambuc  *       ddekit_slab_getobj                                                   *
251*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_getobj(struct ddekit_slab_slab * s)252*433d6423SLionel Sambuc static void *ddekit_slab_getobj(struct ddekit_slab_slab *s)
253*433d6423SLionel Sambuc {
254*433d6423SLionel Sambuc 	struct ddekit_slab *sc;
255*433d6423SLionel Sambuc 	void *ret = 0;
256*433d6423SLionel Sambuc 
257*433d6423SLionel Sambuc 	sc = s->cache;
258*433d6423SLionel Sambuc 	ret  = s->objects;
259*433d6423SLionel Sambuc 
260*433d6423SLionel Sambuc 	/* get pointer to next object */
261*433d6423SLionel Sambuc 
262*433d6423SLionel Sambuc 	s->objects = *(void **)((char *) ret + sc->size);
263*433d6423SLionel Sambuc 	s->free--;
264*433d6423SLionel Sambuc 
265*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("old: %p new: %p", ret, s->objects);
266*433d6423SLionel Sambuc 
267*433d6423SLionel Sambuc 	/* if no more objects move to full */
268*433d6423SLionel Sambuc 
269*433d6423SLionel Sambuc 	if (!s->free)
270*433d6423SLionel Sambuc 	{
271*433d6423SLionel Sambuc 		ddekit_slab_slab_remove(s);
272*433d6423SLionel Sambuc 		ddekit_slab_slab_insert(&sc->full,s);
273*433d6423SLionel Sambuc 	}
274*433d6423SLionel Sambuc 
275*433d6423SLionel Sambuc 	if (s->free == sc->number-1)
276*433d6423SLionel Sambuc 	{
277*433d6423SLionel Sambuc 		ddekit_slab_slab_remove(s);
278*433d6423SLionel Sambuc 		ddekit_slab_slab_insert(&sc->partial,s);
279*433d6423SLionel Sambuc 	}
280*433d6423SLionel Sambuc 
281*433d6423SLionel Sambuc 	return ret;
282*433d6423SLionel Sambuc }
283*433d6423SLionel Sambuc 
284*433d6423SLionel Sambuc /******************************************************************************
285*433d6423SLionel Sambuc  *       ddekit_slab_alloc                                                    *
286*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_alloc(struct ddekit_slab * sc)287*433d6423SLionel Sambuc void *ddekit_slab_alloc(struct ddekit_slab * sc)
288*433d6423SLionel Sambuc {
289*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s=0;
290*433d6423SLionel Sambuc 
291*433d6423SLionel Sambuc 	ddekit_slab_lock(sc);
292*433d6423SLionel Sambuc 
293*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("from slab %p", sc);
294*433d6423SLionel Sambuc 
295*433d6423SLionel Sambuc 	/* first try from partial */
296*433d6423SLionel Sambuc 	if (sc->partial.next != &sc->partial) {
297*433d6423SLionel Sambuc 		DDEBUG_MSG_VERBOSE("from slab %p partial (next=%p)", sc,sc->partial.next);
298*433d6423SLionel Sambuc 		s = sc->partial.next;
299*433d6423SLionel Sambuc 	}
300*433d6423SLionel Sambuc 
301*433d6423SLionel Sambuc 	/* must grow? */
302*433d6423SLionel Sambuc 	if (!s && (sc->empty.next == &sc->empty )){
303*433d6423SLionel Sambuc 		DDEBUG_MSG_VERBOSE("slab %p has to grow", sc);
304*433d6423SLionel Sambuc 		ddekit_slab_grow(sc);
305*433d6423SLionel Sambuc 	}
306*433d6423SLionel Sambuc 
307*433d6423SLionel Sambuc 	/* take from free? */
308*433d6423SLionel Sambuc 	if (!s) {
309*433d6423SLionel Sambuc 		DDEBUG_MSG_VERBOSE("from slab %p empty", sc);
310*433d6423SLionel Sambuc 		s = sc->empty.next;
311*433d6423SLionel Sambuc 	}
312*433d6423SLionel Sambuc 
313*433d6423SLionel Sambuc 	ddekit_slab_unlock(sc);
314*433d6423SLionel Sambuc 
315*433d6423SLionel Sambuc 	return ddekit_slab_getobj(s);
316*433d6423SLionel Sambuc }
317*433d6423SLionel Sambuc 
318*433d6423SLionel Sambuc /******************************************************************************
319*433d6423SLionel Sambuc  *       ddekit_slab_free                                                     *
320*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_free(struct ddekit_slab * sc,void * obj)321*433d6423SLionel Sambuc void ddekit_slab_free(struct ddekit_slab *sc, void* obj)
322*433d6423SLionel Sambuc {
323*433d6423SLionel Sambuc 	void **p;
324*433d6423SLionel Sambuc 
325*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s = 0;
326*433d6423SLionel Sambuc 
327*433d6423SLionel Sambuc 	ddekit_slab_lock(sc);
328*433d6423SLionel Sambuc 	/* first find slab the obj came from */
329*433d6423SLionel Sambuc 
330*433d6423SLionel Sambuc 	s = ddekit_slab_find_slab(sc, obj);
331*433d6423SLionel Sambuc 
332*433d6423SLionel Sambuc 	p = (void **)((char *) obj + sc->size);
333*433d6423SLionel Sambuc 
334*433d6423SLionel Sambuc 	*p= s->objects;
335*433d6423SLionel Sambuc 	s->objects=obj;
336*433d6423SLionel Sambuc 
337*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("old: %p, new: %p",*p,s->objects );
338*433d6423SLionel Sambuc 
339*433d6423SLionel Sambuc 	s->free++;
340*433d6423SLionel Sambuc 
341*433d6423SLionel Sambuc 	if (s->free == sc->number) {
342*433d6423SLionel Sambuc 		ddekit_slab_slab_remove(s);
343*433d6423SLionel Sambuc 		ddekit_slab_slab_insert(&sc->empty, s);
344*433d6423SLionel Sambuc 	}
345*433d6423SLionel Sambuc 
346*433d6423SLionel Sambuc 	if (s->free == 1) {
347*433d6423SLionel Sambuc 		ddekit_slab_slab_remove(s);
348*433d6423SLionel Sambuc 		ddekit_slab_slab_insert(&sc->partial, s);
349*433d6423SLionel Sambuc 	}
350*433d6423SLionel Sambuc 
351*433d6423SLionel Sambuc 	ddekit_slab_unlock(sc);
352*433d6423SLionel Sambuc }
353*433d6423SLionel Sambuc 
354*433d6423SLionel Sambuc /******************************************************************************
355*433d6423SLionel Sambuc  *       ddekit_slab_set_data                                                 *
356*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_set_data(struct ddekit_slab * sc,void * data)357*433d6423SLionel Sambuc void ddekit_slab_set_data(struct ddekit_slab * sc, void *data)
358*433d6423SLionel Sambuc {
359*433d6423SLionel Sambuc 	ddekit_slab_lock(sc);
360*433d6423SLionel Sambuc 	sc->data = data;
361*433d6423SLionel Sambuc 	ddekit_slab_unlock(sc);
362*433d6423SLionel Sambuc }
363*433d6423SLionel Sambuc 
364*433d6423SLionel Sambuc /******************************************************************************
365*433d6423SLionel Sambuc  *       ddekit_slab_get_data                                                 *
366*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_get_data(struct ddekit_slab * sc)367*433d6423SLionel Sambuc void *ddekit_slab_get_data (struct ddekit_slab *sc)
368*433d6423SLionel Sambuc {
369*433d6423SLionel Sambuc 	void *ret;
370*433d6423SLionel Sambuc 	ddekit_slab_lock(sc);
371*433d6423SLionel Sambuc 	ret=sc->data;
372*433d6423SLionel Sambuc 	ddekit_slab_unlock(sc);
373*433d6423SLionel Sambuc 	return ret;
374*433d6423SLionel Sambuc }
375*433d6423SLionel Sambuc 
376*433d6423SLionel Sambuc 
377*433d6423SLionel Sambuc /******************************************************************************
378*433d6423SLionel Sambuc  *       ddekit_slab_init                                                     *
379*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_init(unsigned size,int contiguous)380*433d6423SLionel Sambuc struct ddekit_slab * ddekit_slab_init(unsigned size, int contiguous)
381*433d6423SLionel Sambuc {
382*433d6423SLionel Sambuc 
383*433d6423SLionel Sambuc 	struct ddekit_slab * sc = 0;
384*433d6423SLionel Sambuc 
385*433d6423SLionel Sambuc 	sc = (struct ddekit_slab *)
386*433d6423SLionel Sambuc 	    ddekit_simple_malloc(sizeof(struct ddekit_slab));
387*433d6423SLionel Sambuc 
388*433d6423SLionel Sambuc 	sc->data       = 0;
389*433d6423SLionel Sambuc 	sc->contiguous = contiguous;
390*433d6423SLionel Sambuc 	sc->size       = size;
391*433d6423SLionel Sambuc 	sc->number     = SLAB_SIZE/(size+sizeof(void*));
392*433d6423SLionel Sambuc 
393*433d6423SLionel Sambuc 	if (sc->number == 0) {
394*433d6423SLionel Sambuc 		ddekit_panic("objects too big!");
395*433d6423SLionel Sambuc 	}
396*433d6423SLionel Sambuc 
397*433d6423SLionel Sambuc 	sc->empty.next   = sc->empty.prev   = &sc->empty;
398*433d6423SLionel Sambuc 	sc->partial.next = sc->partial.prev = &sc->partial;
399*433d6423SLionel Sambuc 	sc->full.next    = sc->full.prev    = &sc->full;
400*433d6423SLionel Sambuc 
401*433d6423SLionel Sambuc 	ddekit_lock_init(&sc->lock);
402*433d6423SLionel Sambuc 
403*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("initialzed slab cache %p: size %x, number %d ",
404*433d6423SLionel Sambuc 	    sc, sc->size, sc->number);
405*433d6423SLionel Sambuc 
406*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("partial %p next %p", &sc->partial, sc->partial.next);
407*433d6423SLionel Sambuc 	return sc ;
408*433d6423SLionel Sambuc 
409*433d6423SLionel Sambuc }
410*433d6423SLionel Sambuc 
411*433d6423SLionel Sambuc 
412*433d6423SLionel Sambuc /******************************************************************************
413*433d6423SLionel Sambuc  *       ddekit_slab_free_slab                                                *
414*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_free_slab(struct ddekit_slab_slab * sl,int cont)415*433d6423SLionel Sambuc static void ddekit_slab_free_slab(struct ddekit_slab_slab * sl, int cont)
416*433d6423SLionel Sambuc {
417*433d6423SLionel Sambuc 
418*433d6423SLionel Sambuc 	struct ddekit_slab_slab *s,*t;
419*433d6423SLionel Sambuc 
420*433d6423SLionel Sambuc 	if (!sl) {
421*433d6423SLionel Sambuc 		ddekit_panic("no slab to free!");
422*433d6423SLionel Sambuc 	}
423*433d6423SLionel Sambuc 
424*433d6423SLionel Sambuc 	for ( s = sl->next; s != sl; )
425*433d6423SLionel Sambuc 	{
426*433d6423SLionel Sambuc 		DDEBUG_MSG_VERBOSE("cont: %d, %p, s->mem", cont, s->mem);
427*433d6423SLionel Sambuc 		if(cont)
428*433d6423SLionel Sambuc 		{
429*433d6423SLionel Sambuc 			ddekit_large_free(s->mem);
430*433d6423SLionel Sambuc 		}
431*433d6423SLionel Sambuc 		else
432*433d6423SLionel Sambuc 		{
433*433d6423SLionel Sambuc 			ddekit_simple_free(s->mem);
434*433d6423SLionel Sambuc 		}
435*433d6423SLionel Sambuc 		t = s;
436*433d6423SLionel Sambuc 		s = s->next;
437*433d6423SLionel Sambuc 		ddekit_simple_free(t);
438*433d6423SLionel Sambuc 	}
439*433d6423SLionel Sambuc 
440*433d6423SLionel Sambuc }
441*433d6423SLionel Sambuc 
442*433d6423SLionel Sambuc /******************************************************************************
443*433d6423SLionel Sambuc  *       ddekit_slab_destroy                                                  *
444*433d6423SLionel Sambuc  *****************************************************************************/
ddekit_slab_destroy(struct ddekit_slab * sc)445*433d6423SLionel Sambuc void ddekit_slab_destroy(struct ddekit_slab *sc)
446*433d6423SLionel Sambuc {
447*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p full", sc);
448*433d6423SLionel Sambuc 	ddekit_slab_free_slab(&sc->full,sc->contiguous);
449*433d6423SLionel Sambuc 
450*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p empty", sc);
451*433d6423SLionel Sambuc 	ddekit_slab_free_slab(&sc->empty,sc->contiguous);
452*433d6423SLionel Sambuc 
453*433d6423SLionel Sambuc 	DDEBUG_MSG_VERBOSE("%p partial", sc);
454*433d6423SLionel Sambuc 	ddekit_slab_free_slab(&sc->partial,sc->contiguous);
455*433d6423SLionel Sambuc 
456*433d6423SLionel Sambuc 	ddekit_lock_deinit(&sc->lock);
457*433d6423SLionel Sambuc 
458*433d6423SLionel Sambuc 	ddekit_simple_free(sc);
459*433d6423SLionel Sambuc }
460