Rev 786 | Rev 788 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 786 | Rev 787 | ||
|---|---|---|---|
| Line 226... | Line 226... | ||
| 226 | * @return Number of freed pages |
226 | * @return Number of freed pages |
| 227 | */ |
227 | */ |
| 228 | static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, |
228 | static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, |
| 229 | slab_t *slab) |
229 | slab_t *slab) |
| 230 | { |
230 | { |
| - | 231 | int freed = 0; |
|
| - | 232 | ||
| 231 | if (!slab) |
233 | if (!slab) |
| 232 | slab = obj2slab(obj); |
234 | slab = obj2slab(obj); |
| 233 | 235 | ||
| 234 | ASSERT(slab->cache == cache); |
236 | ASSERT(slab->cache == cache); |
| 235 | ASSERT(slab->available < cache->objects); |
237 | ASSERT(slab->available < cache->objects); |
| 236 | 238 | ||
| - | 239 | if (cache->destructor) |
|
| - | 240 | freed = cache->destructor(obj); |
|
| - | 241 | ||
| 237 | spinlock_lock(&cache->slablock); |
242 | spinlock_lock(&cache->slablock); |
| 238 | 243 | ||
| 239 | *((int *)obj) = slab->nextavail; |
244 | *((int *)obj) = slab->nextavail; |
| 240 | slab->nextavail = (obj - slab->start)/cache->size; |
245 | slab->nextavail = (obj - slab->start)/cache->size; |
| 241 | slab->available++; |
246 | slab->available++; |
| Line 244... | Line 249... | ||
| 244 | if (slab->available == cache->objects) { |
249 | if (slab->available == cache->objects) { |
| 245 | /* Free associated memory */ |
250 | /* Free associated memory */ |
| 246 | list_remove(&slab->link); |
251 | list_remove(&slab->link); |
| 247 | spinlock_unlock(&cache->slablock); |
252 | spinlock_unlock(&cache->slablock); |
| 248 | 253 | ||
| 249 | return slab_space_free(cache, slab); |
254 | return freed + slab_space_free(cache, slab); |
| 250 | 255 | ||
| 251 | } else if (slab->available == 1) { |
256 | } else if (slab->available == 1) { |
| 252 | /* It was in full, move to partial */ |
257 | /* It was in full, move to partial */ |
| 253 | list_remove(&slab->link); |
258 | list_remove(&slab->link); |
| 254 | list_prepend(&slab->link, &cache->partial_slabs); |
259 | list_prepend(&slab->link, &cache->partial_slabs); |
| 255 | } |
260 | } |
| 256 | spinlock_unlock(&cache->slablock); |
261 | spinlock_unlock(&cache->slablock); |
| 257 | return 0; |
262 | return freed; |
| 258 | } |
263 | } |
| 259 | 264 | ||
| 260 | /** |
265 | /** |
| 261 | * Take new object from slab or create new if needed |
266 | * Take new object from slab or create new if needed |
| 262 | * |
267 | * |
| Line 288... | Line 293... | ||
| 288 | list_remove(&slab->link); |
293 | list_remove(&slab->link); |
| 289 | } |
294 | } |
| 290 | obj = slab->start + slab->nextavail * cache->size; |
295 | obj = slab->start + slab->nextavail * cache->size; |
| 291 | slab->nextavail = *((int *)obj); |
296 | slab->nextavail = *((int *)obj); |
| 292 | slab->available--; |
297 | slab->available--; |
| - | 298 | ||
| 293 | if (! slab->available) |
299 | if (! slab->available) |
| 294 | list_prepend(&slab->link, &cache->full_slabs); |
300 | list_prepend(&slab->link, &cache->full_slabs); |
| 295 | else |
301 | else |
| 296 | list_prepend(&slab->link, &cache->partial_slabs); |
302 | list_prepend(&slab->link, &cache->partial_slabs); |
| 297 | 303 | ||
| 298 | spinlock_unlock(&cache->slablock); |
304 | spinlock_unlock(&cache->slablock); |
| - | 305 | ||
| - | 306 | if (cache->constructor && cache->constructor(obj, flags)) { |
|
| - | 307 | /* Bad, bad, construction failed */ |
|
| - | 308 | slab_obj_destroy(cache, obj, slab); |
|
| - | 309 | return NULL; |
|
| - | 310 | } |
|
| 299 | return obj; |
311 | return obj; |
| 300 | } |
312 | } |
| 301 | 313 | ||
| 302 | /**************************************/ |
314 | /**************************************/ |
| 303 | /* CPU-Cache slab functions */ |
315 | /* CPU-Cache slab functions */ |
| Line 529... | Line 541... | ||
| 529 | _slab_cache_create(slab_cache_t *cache, |
541 | _slab_cache_create(slab_cache_t *cache, |
| 530 | char *name, |
542 | char *name, |
| 531 | size_t size, |
543 | size_t size, |
| 532 | size_t align, |
544 | size_t align, |
| 533 | int (*constructor)(void *obj, int kmflag), |
545 | int (*constructor)(void *obj, int kmflag), |
| 534 | void (*destructor)(void *obj), |
546 | int (*destructor)(void *obj), |
| 535 | int flags) |
547 | int flags) |
| 536 | { |
548 | { |
| 537 | int i; |
549 | int i; |
| 538 | int pages; |
550 | int pages; |
| 539 | ipl_t ipl; |
551 | ipl_t ipl; |
| Line 594... | Line 606... | ||
| 594 | /** Create slab cache */ |
606 | /** Create slab cache */ |
| 595 | slab_cache_t * slab_cache_create(char *name, |
607 | slab_cache_t * slab_cache_create(char *name, |
| 596 | size_t size, |
608 | size_t size, |
| 597 | size_t align, |
609 | size_t align, |
| 598 | int (*constructor)(void *obj, int kmflag), |
610 | int (*constructor)(void *obj, int kmflag), |
| 599 | void (*destructor)(void *obj), |
611 | int (*destructor)(void *obj), |
| 600 | int flags) |
612 | int flags) |
| 601 | { |
613 | { |
| 602 | slab_cache_t *cache; |
614 | slab_cache_t *cache; |
| 603 | 615 | ||
| 604 | cache = slab_alloc(&slab_cache_cache, 0); |
616 | cache = slab_alloc(&slab_cache_cache, 0); |