Subversion Repositories HelenOS-historic

Rev

Rev 769 | Rev 772 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 769 Rev 771
Line 90... Line 90...
90
#include <config.h>
90
#include <config.h>
91
#include <print.h>
91
#include <print.h>
92
#include <arch.h>
92
#include <arch.h>
93
#include <panic.h>
93
#include <panic.h>
94
#include <debug.h>
94
#include <debug.h>
-
 
95
#include <bitops.h>
95
 
96
 
96
SPINLOCK_INITIALIZE(slab_cache_lock);
97
SPINLOCK_INITIALIZE(slab_cache_lock);
97
static LIST_INITIALIZE(slab_cache_list);
98
static LIST_INITIALIZE(slab_cache_list);
98
 
99
 
99
/** Magazine cache */
100
/** Magazine cache */
Line 106... Line 107...
106
 * - using SLAB for internal SLAB structures will not deadlock,
107
 * - using SLAB for internal SLAB structures will not deadlock,
107
 *   as all slab structures are 'small' - control structures of
108
 *   as all slab structures are 'small' - control structures of
108
 *   their caches do not require further allocation
109
 *   their caches do not require further allocation
109
 */
110
 */
110
static slab_cache_t *slab_extern_cache;
111
static slab_cache_t *slab_extern_cache;
-
 
112
/** Caches for malloc */
-
 
113
static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W-SLAB_MIN_MALLOC_W+1];
-
 
114
char *malloc_names[] =  {
-
 
115
    "malloc-8","malloc-16","malloc-32","malloc-64","malloc-128",
-
 
116
    "malloc-256","malloc-512","malloc-1K","malloc-2K",
-
 
117
    "malloc-4K","malloc-8K","malloc-16K","malloc-32K",
-
 
118
    "malloc-64K","malloc-128K"
-
 
119
};
111
 
120
 
112
/** Slab descriptor */
121
/** Slab descriptor */
113
typedef struct {
122
typedef struct {
114
    slab_cache_t *cache; /**< Pointer to parent cache */
123
    slab_cache_t *cache; /**< Pointer to parent cache */
115
    link_t link;       /* List of full/partial slabs */
124
    link_t link;       /* List of full/partial slabs */
Line 476... Line 485...
476
           int (*constructor)(void *obj, int kmflag),
485
           int (*constructor)(void *obj, int kmflag),
477
           void (*destructor)(void *obj),
486
           void (*destructor)(void *obj),
478
           int flags)
487
           int flags)
479
{
488
{
480
    int i;
489
    int i;
-
 
490
    int pages;
481
 
491
 
482
    memsetb((__address)cache, sizeof(*cache), 0);
492
    memsetb((__address)cache, sizeof(*cache), 0);
483
    cache->name = name;
493
    cache->name = name;
484
 
494
 
485
    if (align < sizeof(__native))
495
    if (align < sizeof(__native))
Line 505... Line 515...
505
    /* Compute slab sizes, object counts in slabs etc. */
515
    /* Compute slab sizes, object counts in slabs etc. */
506
    if (cache->size < SLAB_INSIDE_SIZE)
516
    if (cache->size < SLAB_INSIDE_SIZE)
507
        cache->flags |= SLAB_CACHE_SLINSIDE;
517
        cache->flags |= SLAB_CACHE_SLINSIDE;
508
 
518
 
509
    /* Minimum slab order */
519
    /* Minimum slab order */
510
    cache->order = (cache->size-1) >> PAGE_WIDTH;
520
    pages = ((cache->size-1) >> PAGE_WIDTH) + 1;
-
 
521
    cache->order = fnzb(pages);
511
 
522
 
512
    while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
523
    while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
513
        cache->order += 1;
524
        cache->order += 1;
514
    }
525
    }
515
    cache->objects = comp_objects(cache);
526
    cache->objects = comp_objects(cache);
Line 630... Line 641...
630
    ipl_t ipl;
641
    ipl_t ipl;
631
    void *result = NULL;
642
    void *result = NULL;
632
 
643
 
633
    /* Disable interrupts to avoid deadlocks with interrupt handlers */
644
    /* Disable interrupts to avoid deadlocks with interrupt handlers */
634
    ipl = interrupts_disable();
645
    ipl = interrupts_disable();
635
   
646
 
636
    if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
647
    if (!(cache->flags & SLAB_CACHE_NOMAGAZINE) && CPU)
637
        result = magazine_obj_get(cache);
648
        result = magazine_obj_get(cache);
638
 
649
 
639
    if (!result) {
650
    if (!result) {
640
        spinlock_lock(&cache->lock);
651
        spinlock_lock(&cache->lock);
641
        result = slab_obj_create(cache, flags);
652
        result = slab_obj_create(cache, flags);
Line 648... Line 659...
648
        atomic_inc(&cache->allocated_objs);
659
        atomic_inc(&cache->allocated_objs);
649
 
660
 
650
    return result;
661
    return result;
651
}
662
}
652
 
663
 
653
/** Return object to cache  */
664
/** Return object to cache, use slab if known  */
654
void slab_free(slab_cache_t *cache, void *obj)
665
static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
655
{
666
{
656
    ipl_t ipl;
667
    ipl_t ipl;
657
 
668
 
658
    ipl = interrupts_disable();
669
    ipl = interrupts_disable();
659
 
670
 
660
    if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
671
    if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
-
 
672
        || !CPU \
661
        || magazine_obj_put(cache, obj)) {
673
        || magazine_obj_put(cache, obj)) {
662
       
674
       
663
        spinlock_lock(&cache->lock);
675
        spinlock_lock(&cache->lock);
664
        slab_obj_destroy(cache, obj, NULL);
676
        slab_obj_destroy(cache, obj, slab);
665
        spinlock_unlock(&cache->lock);
677
        spinlock_unlock(&cache->lock);
666
    }
678
    }
667
    interrupts_restore(ipl);
679
    interrupts_restore(ipl);
668
    atomic_dec(&cache->allocated_objs);
680
    atomic_dec(&cache->allocated_objs);
669
}
681
}
670
 
682
 
-
 
683
/** Return slab object to cache */
-
 
684
void slab_free(slab_cache_t *cache, void *obj)
-
 
685
{
-
 
686
    _slab_free(cache,obj,NULL);
-
 
687
}
-
 
688
 
671
/* Go through all caches and reclaim what is possible */
689
/* Go through all caches and reclaim what is possible */
672
count_t slab_reclaim(int flags)
690
count_t slab_reclaim(int flags)
673
{
691
{
674
    slab_cache_t *cache;
692
    slab_cache_t *cache;
675
    link_t *cur;
693
    link_t *cur;
Line 708... Line 726...
708
    spinlock_unlock(&slab_cache_lock);
726
    spinlock_unlock(&slab_cache_lock);
709
}
727
}
710
 
728
 
711
void slab_cache_init(void)
729
void slab_cache_init(void)
712
{
730
{
-
 
731
    int i, size;
-
 
732
 
713
    /* Initialize magazine cache */
733
    /* Initialize magazine cache */
714
    _slab_cache_create(&mag_cache,
734
    _slab_cache_create(&mag_cache,
715
               "slab_magazine",
735
               "slab_magazine",
716
               sizeof(slab_magazine_t)+SLAB_MAG_SIZE*sizeof(void*),
736
               sizeof(slab_magazine_t)+SLAB_MAG_SIZE*sizeof(void*),
717
               sizeof(__address),
737
               sizeof(__address),
Line 729... Line 749...
729
                          sizeof(slab_t),
749
                          sizeof(slab_t),
730
                          0, NULL, NULL,
750
                          0, NULL, NULL,
731
                          SLAB_CACHE_SLINSIDE);
751
                          SLAB_CACHE_SLINSIDE);
732
 
752
 
733
    /* Initialize structures for malloc */
753
    /* Initialize structures for malloc */
-
 
754
    for (i=0, size=(1<<SLAB_MIN_MALLOC_W);
-
 
755
         i < (SLAB_MAX_MALLOC_W-SLAB_MIN_MALLOC_W+1);
-
 
756
         i++, size <<= 1) {
-
 
757
        malloc_caches[i] = slab_cache_create(malloc_names[i],
-
 
758
                             size, 0,
-
 
759
                             NULL,NULL,0);
-
 
760
    }
-
 
761
}
-
 
762
 
-
 
763
/**************************************/
-
 
764
/* kalloc/kfree functions             */
-
 
765
void * kalloc(unsigned int size, int flags)
-
 
766
{
-
 
767
    int idx;
-
 
768
 
-
 
769
    ASSERT( size && size <= (1 << SLAB_MAX_MALLOC_W));
-
 
770
   
-
 
771
    if (size < (1 << SLAB_MIN_MALLOC_W))
-
 
772
        size = (1 << SLAB_MIN_MALLOC_W);
-
 
773
 
-
 
774
    idx = fnzb(size-1) - SLAB_MIN_MALLOC_W + 1;
-
 
775
 
-
 
776
    return slab_alloc(malloc_caches[idx], flags);
-
 
777
}
-
 
778
 
-
 
779
 
-
 
780
void kfree(void *obj)
-
 
781
{
-
 
782
    slab_t *slab = obj2slab(obj);
-
 
783
   
-
 
784
    _slab_free(slab->cache, obj, slab);
734
}
785
}