Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 767 → Rev 768

/kernel/trunk/generic/src/mm/slab.c
75,7 → 75,7
if (status != FRAME_OK) {
return NULL;
}
if (! cache->flags & SLAB_CACHE_SLINSIDE) {
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) {
slab = malloc(sizeof(*slab)); // , flags);
if (!slab) {
frame_free((__address)data);
102,7 → 102,6
*((int *) (slab->start + i*cache->size)) = i+1;
 
atomic_inc(&cache->allocated_slabs);
 
return slab;
}
 
114,7 → 113,7
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
{
frame_free((__address)slab->start);
if (! cache->flags & SLAB_CACHE_SLINSIDE)
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
free(slab);
 
atomic_dec(&cache->allocated_slabs);
277,6 → 276,7
}
/* Free current magazine and take one from list */
slab_free(&mag_cache, mag);
 
mag = list_get_instance(cache->magazines.next,
slab_magazine_t,
link);
296,7 → 296,8
}
 
/**
* Put object into CPU-cache magazine
* Assure that the current magazine is empty, return pointer to it, or NULL if
* no empty magazine available and cannot be allocated
*
* We have 2 magazines bound to processor.
* First try the current.
304,6 → 305,46
* If full, put to magazines list.
* allocate new, exchange last & current
*
*/
static slab_magazine_t * make_empty_current_mag(slab_cache_t *cache)
{
slab_magazine_t *cmag,*lastmag,*newmag;
 
cmag = cache->mag_cache[CPU->id].current;
lastmag = cache->mag_cache[CPU->id].last;
 
if (cmag) {
if (cmag->busy < cmag->size)
return cmag;
if (lastmag && lastmag->busy < lastmag->size) {
cache->mag_cache[CPU->id].last = cmag;
cache->mag_cache[CPU->id].current = lastmag;
return lastmag;
}
}
/* current | last are full | nonexistent, allocate new */
/* We do not want to sleep just because of caching */
/* Especially we do not want reclaiming to start, as
* this would deadlock */
newmag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
if (!newmag)
return NULL;
newmag->size = SLAB_MAG_SIZE;
newmag->busy = 0;
 
/* Flush last to magazine list */
if (lastmag)
list_prepend(&lastmag->link, &cache->magazines);
/* Move current as last, save new as current */
cache->mag_cache[CPU->id].last = cmag;
cache->mag_cache[CPU->id].current = newmag;
 
return newmag;
}
 
/**
* Put object into CPU-cache magazine
*
* @return 0 - success, -1 - could not get memory
*/
static int magazine_obj_put(slab_cache_t *cache, void *obj)
311,38 → 352,11
slab_magazine_t *mag;
 
spinlock_lock(&cache->mag_cache[CPU->id].lock);
 
mag = make_empty_current_mag(cache);
if (!mag)
goto errout;
mag = cache->mag_cache[CPU->id].current;
if (!mag) {
/* We do not want to sleep just because of caching */
/* Especially we do not want reclaiming to start, as
* this would deadlock */
mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
if (!mag) /* Allocation failed, give up on caching */
goto errout;
 
cache->mag_cache[CPU->id].current = mag;
mag->size = SLAB_MAG_SIZE;
mag->busy = 0;
} else if (mag->busy == mag->size) {
/* If the last is full | empty, allocate new */
mag = cache->mag_cache[CPU->id].last;
if (!mag || mag->size == mag->busy) {
if (mag)
list_prepend(&mag->link, &cache->magazines);
 
mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
if (!mag)
goto errout;
mag->size = SLAB_MAG_SIZE;
mag->busy = 0;
cache->mag_cache[CPU->id].last = mag;
}
/* Exchange the 2 */
cache->mag_cache[CPU->id].last = cache->mag_cache[CPU->id].current;
cache->mag_cache[CPU->id].current = mag;
}
mag->objs[mag->busy++] = obj;
 
spinlock_unlock(&cache->mag_cache[CPU->id].lock);
408,7 → 422,7
list_initialize(&cache->partial_slabs);
list_initialize(&cache->magazines);
spinlock_initialize(&cache->lock, "cachelock");
if (! cache->flags & SLAB_CACHE_NOMAGAZINE) {
if (! (cache->flags & SLAB_CACHE_NOMAGAZINE)) {
for (i=0; i< config.cpu_count; i++)
spinlock_initialize(&cache->mag_cache[i].lock,
"cpucachelock");
457,8 → 471,6
*
* @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
* @return Number of freed pages
*
* TODO: Add light reclaim
*/
static count_t _slab_reclaim(slab_cache_t *cache, int flags)
{
493,12 → 505,11
/* Destroy full magazines */
cur=cache->magazines.prev;
 
while (cur!=&cache->magazines) {
while (cur != &cache->magazines) {
mag = list_get_instance(cur, slab_magazine_t, link);
cur = cur->prev;
list_remove(cur->next);
// list_remove(&mag->link);
list_remove(&mag->link);
frames += magazine_destroy(cache,mag);
/* If we do not do full reclaim, break
* as soon as something is freed */
544,7 → 555,7
/* Disable interrupts to avoid deadlocks with interrupt handlers */
ipl = interrupts_disable();
if (!cache->flags & SLAB_CACHE_NOMAGAZINE)
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
result = magazine_obj_get(cache);
 
if (!result) {