Index: generic/include/mm/slab.h
===================================================================
--- generic/include/mm/slab.h	(revision 086d4fdc2702688cbbe860eb8b6fa914170b9d24)
+++ generic/include/mm/slab.h	(revision 14e5d88783acf4d0ab6f0dd21cad187ff52b1278)
@@ -38,8 +38,8 @@
 
 /** If object size is less, store control structure inside SLAB */
-#define SLAB_INSIDE_SIZE   (PAGE_SIZE / 6)
+#define SLAB_INSIDE_SIZE   (PAGE_SIZE >> 3)
 
 /** Maximum wasted space we allow for cache */
-#define SLAB_MAX_BADNESS(cache)   ((PAGE_SIZE << (cache)->order) / 4)
+#define SLAB_MAX_BADNESS(cache)   ((PAGE_SIZE << (cache)->order >> 2))
 
 /* slab_reclaim constants */
Index: generic/src/mm/slab.c
===================================================================
--- generic/src/mm/slab.c	(revision 086d4fdc2702688cbbe860eb8b6fa914170b9d24)
+++ generic/src/mm/slab.c	(revision 14e5d88783acf4d0ab6f0dd21cad187ff52b1278)
@@ -89,5 +89,5 @@
 	/* Fill in slab structures */
 	/* TODO: some better way of accessing the frame */
-	for (i=0; i< (1<<cache->order); i++) {
+	for (i=0; i < (1 << cache->order); i++) {
 		frame = ADDR2FRAME(zone, KA2PA((__address)(data+i*PAGE_SIZE)));
 		frame->parent = slab;
@@ -107,5 +107,5 @@
 
 /**
- * Free space associated with SLAB
+ * Deallocate space associated with SLAB
  *
  * @return number of freed frames
@@ -151,6 +151,4 @@
 	if (!slab)
 		slab = obj2slab(obj);
-
-	spinlock_lock(&cache->lock);
 
 	*((int *)obj) = slab->nextavail;
@@ -172,6 +170,4 @@
 		spinlock_lock(&cache->lock);
 	}
-
-	spinlock_unlock(&cache->lock);
 
 	return frames;
@@ -389,6 +385,8 @@
 	cache->name = name;
 
-	if (align)
-		size = ALIGN_UP(size, align);
+	if (align < sizeof(__native))
+		align = sizeof(__native);
+	size = ALIGN_UP(size, align);
+		
 	cache->size = size;
 
@@ -412,11 +410,13 @@
 
 	/* Minimum slab order */
-	cache->order = (cache->size >> PAGE_WIDTH) + 1;
-		
+	cache->order = (cache->size-1) >> PAGE_WIDTH;
+
 	while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
 		cache->order += 1;
 	}
-
 	cache->objects = comp_objects(cache);
+	/* If info fits in, put it inside */
+	if (badness(cache) > sizeof(slab_t))
+		cache->flags |= SLAB_CACHE_SLINSIDE;
 
 	spinlock_lock(&slab_cache_lock);
@@ -597,11 +597,12 @@
 
 	spinlock_lock(&slab_cache_lock);
-	printf("SLAB name\tOsize\tOrder\tOcnt\tSlabs\tAllocobjs\n");
+	printf("SLAB name\tOsize\tPages\tOcnt\tSlabs\tAllocobjs\tCtl\n");
 	for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) {
 		cache = list_get_instance(cur, slab_cache_t, link);
-		printf("%s\t%d\t%d\t%d\t%d\t%d\n", cache->name, cache->size, 
-		       cache->order, cache->objects,
+		printf("%s\t%d\t%d\t%d\t%d\t%d\t\t%s\n", cache->name, cache->size, 
+		       (1 << cache->order), cache->objects,
 		       atomic_get(&cache->allocated_slabs), 
-		       atomic_get(&cache->allocated_objs));
+		       atomic_get(&cache->allocated_objs),
+		       cache->flags & SLAB_CACHE_SLINSIDE ? "In" : "Out");
 	}
 	spinlock_unlock(&slab_cache_lock);
Index: test/mm/slab1/test.c
===================================================================
--- test/mm/slab1/test.c	(revision 086d4fdc2702688cbbe860eb8b6fa914170b9d24)
+++ test/mm/slab1/test.c	(revision 14e5d88783acf4d0ab6f0dd21cad187ff52b1278)
@@ -30,38 +30,35 @@
 #include <mm/slab.h>
 #include <print.h>
+#include <proc/thread.h>
+#include <arch.h>
+#include <panic.h>
 
-#define VAL_SIZE    128
 #define VAL_COUNT   1024
 
-void * data[16384];
+void * data[VAL_COUNT];
 
-void test(void) 
+static void testit(int size, int count) 
 {
 	slab_cache_t *cache;
 	int i;
 	
-
-	printf("Creating cache.\n");
-	cache = slab_cache_create("test_cache", VAL_SIZE, 0, NULL, NULL, SLAB_CACHE_NOMAGAZINE);
-	printf("Destroying cache.\n");
-	slab_cache_destroy(cache);
-
-	printf("Creating cache.\n");
-	cache = slab_cache_create("test_cache", VAL_SIZE, 0, NULL, NULL, 
+	printf("Creating cache, object size: %d.\n", size);
+	cache = slab_cache_create("test_cache", size, 0, NULL, NULL, 
 				  SLAB_CACHE_NOMAGAZINE);
+	slab_print_list();
 	
-	printf("Allocating %d items...", VAL_COUNT);
-	for (i=0; i < VAL_COUNT; i++) {
+	printf("Allocating %d items...", count);
+	for (i=0; i < count; i++) {
 		data[i] = slab_alloc(cache, 0);
 	}
 	printf("done.\n");
-	printf("Freeing %d items...", VAL_COUNT);
-	for (i=0; i < VAL_COUNT; i++) {
+	printf("Freeing %d items...", count);
+	for (i=0; i < count; i++) {
 		slab_free(cache, data[i]);
 	}
 	printf("done.\n");
 
-	printf("Allocating %d items...", VAL_COUNT);
-	for (i=0; i < VAL_COUNT; i++) {
+	printf("Allocating %d items...", count);
+	for (i=0; i < count; i++) {
 		data[i] = slab_alloc(cache, 0);
 	}
@@ -69,23 +66,93 @@
 
 	slab_print_list();
-	printf("Freeing %d items...", VAL_COUNT/2);
-	for (i=VAL_COUNT-1; i >= VAL_COUNT/2; i--) {
+	printf("Freeing %d items...", count/2);
+	for (i=count-1; i >= count/2; i--) {
 		slab_free(cache, data[i]);
 	}
 	printf("done.\n");	
 
-	printf("Allocating %d items...", VAL_COUNT/2);
-	for (i=VAL_COUNT/2; i < VAL_COUNT; i++) {
+	printf("Allocating %d items...", count/2);
+	for (i=count/2; i < count; i++) {
 		data[i] = slab_alloc(cache, 0);
 	}
 	printf("done.\n");
-	printf("Freeing %d items...", VAL_COUNT);
-	for (i=0; i < VAL_COUNT; i++) {
+	printf("Freeing %d items...", count);
+	for (i=0; i < count; i++) {
 		slab_free(cache, data[i]);
 	}
 	printf("done.\n");	
-	slab_print_list();
 	slab_cache_destroy(cache);
 
 	printf("Test complete.\n");
 }
+
+static void testsimple(void)
+{
+	testit(100, VAL_COUNT);
+	testit(200, VAL_COUNT);
+	testit(1024, VAL_COUNT);
+	testit(2048, 512);
+	testit(4000, 128);
+	testit(8192, 128);
+	testit(16384, 128);
+	testit(16385, 128);
+}
+
+
+#define THREADS     6
+#define THR_MEM_COUNT   1024
+#define THR_MEM_SIZE    128
+
+void * thr_data[THREADS][THR_MEM_COUNT];
+slab_cache_t *thr_cache;
+semaphore_t thr_sem;
+
+static void thread(void *data)
+{
+	int offs = (int)(__native) data;
+	int i,j;
+
+	printf("Starting thread #%d...\n",THREAD->tid);
+	for (j=0; j<10; j++) {
+		for (i=0; i<THR_MEM_COUNT; i++)
+			thr_data[offs][i] = slab_alloc(thr_cache,0);
+		for (i=0; i<THR_MEM_COUNT/2; i++)
+			slab_free(thr_cache, thr_data[offs][i]);
+		for (i=0; i< THR_MEM_COUNT/2; i++)
+			thr_data[offs][i] = slab_alloc(thr_cache, 0);
+		for (i=0; i<THR_MEM_COUNT;i++)
+			slab_free(thr_cache, thr_data[offs][i]);
+	}
+	printf("Thread #%d finished\n", THREAD->tid);
+	slab_print_list();
+	semaphore_up(&thr_sem);
+}
+
+static void testthreads(void)
+{
+	thread_t *t;
+	int i;
+
+	thr_cache = slab_cache_create("thread_cache", THR_MEM_SIZE, 0, 
+				      NULL, NULL, 
+				      SLAB_CACHE_NOMAGAZINE);
+	semaphore_initialize(&thr_sem,0);
+	for (i=0; i<THREADS; i++) {  
+		if (!(t = thread_create(thread, (void *)(__native)i, TASK, 0)))
+			panic("could not create thread\n");
+		thread_ready(t);
+	}
+
+	for (i=0; i<THREADS; i++)
+		semaphore_down(&thr_sem);
+	
+	slab_cache_destroy(thr_cache);
+	printf("Test complete.\n");
+	
+}
+
+void test(void)
+{
+	testsimple();
+	testthreads();
+}
