Index: generic/include/proc/scheduler.h
===================================================================
--- generic/include/proc/scheduler.h	(revision c5613b7239c9e986e13faac9e99cacf66da13608)
+++ generic/include/proc/scheduler.h	(revision 10e16a7258e74c3db1abf7fb13b527544a85950b)
@@ -55,4 +55,5 @@
 extern void before_thread_runs(void);
 
+extern void sched_print_list(void);
 /*
  * To be defined by architectures:
Index: generic/src/console/cmd.c
===================================================================
--- generic/src/console/cmd.c	(revision c5613b7239c9e986e13faac9e99cacf66da13608)
+++ generic/src/console/cmd.c	(revision 10e16a7258e74c3db1abf7fb13b527544a85950b)
@@ -52,4 +52,5 @@
 #include <main/version.h>
 #include <mm/slab.h>
+#include <proc/scheduler.h>
 
 /** Data and methods for 'help' command. */
@@ -245,4 +246,12 @@
 
 
+static int cmd_sched(cmd_arg_t *argv);
+static cmd_info_t sched_info = {
+	.name = "scheduler",
+	.description = "List all scheduler information",
+	.func = cmd_sched,
+	.argc = 0
+};
+
 static int cmd_slabs(cmd_arg_t *argv);
 static cmd_info_t slabs_info = {
@@ -298,5 +307,24 @@
 };
 
-
+static cmd_info_t *basic_commands[] = {
+	&call0_info,
+	&call1_info,
+	&call2_info,
+	&call3_info,
+	&cpus_info,
+	&desc_info,
+	&exit_info,
+	&halt_info,
+	&help_info,
+	&set4_info,
+	&slabs_info,
+	&symaddr_info,
+	&sched_info,
+	&tlb_info,
+	&version_info,
+	&zones_info,
+	&zone_info,
+	NULL
+};
 
 
@@ -315,70 +343,12 @@
 void cmd_init(void)
 {
-	cmd_initialize(&help_info);
-	if (!cmd_register(&help_info))
-		panic("could not register command %s\n", help_info.name);
-
-	cmd_initialize(&desc_info);
-	if (!cmd_register(&desc_info))
-		panic("could not register command %s\n", desc_info.name);
-
-	cmd_initialize(&exit_info);
-	if (!cmd_register(&exit_info))
-		panic("could not register command %s\n", exit_info.name);
-	
-	cmd_initialize(&symaddr_info);
-	if (!cmd_register(&symaddr_info))
-		panic("could not register command %s\n", symaddr_info.name);
-
-	cmd_initialize(&call0_info);
-	if (!cmd_register(&call0_info))
-		panic("could not register command %s\n", call0_info.name);
-
-	cmd_initialize(&call1_info);
-	if (!cmd_register(&call1_info))
-		panic("could not register command %s\n", call1_info.name);
-
-	cmd_initialize(&call2_info);
-	if (!cmd_register(&call2_info))
-		panic("could not register command %s\n", call2_info.name);
-
-	cmd_initialize(&call3_info);
-	if (!cmd_register(&call3_info))
-		panic("could not register command %s\n", call3_info.name);
-
-	cmd_initialize(&set4_info);
-	if (!cmd_register(&set4_info))
-		panic("could not register command %s\n", set4_info.name);
-	
-	cmd_initialize(&halt_info);
-	if (!cmd_register(&halt_info))
-		panic("could not register command %s\n", halt_info.name);
-
-	cmd_initialize(&tlb_info);
-	if (!cmd_register(&tlb_info))
-		panic("could not register command %s\n", tlb_info.name);
-
-	cmd_initialize(&zones_info);
-	if (!cmd_register(&zones_info))
-		panic("could not register command %s\n", zones_info.name);
-
-	cmd_initialize(&slabs_info);
-	if (!cmd_register(&slabs_info))
-		panic("could not register command %s\n", slabs_info.name);
-
-	cmd_initialize(&zone_info);
-	if (!cmd_register(&zone_info))
-		panic("could not register command %s\n", zone_info.name);
-
-	cmd_initialize(&cpus_info);
-	if (!cmd_register(&cpus_info))
-		panic("could not register command %s\n", cpus_info.name);
-		
-	cmd_initialize(&version_info);
-	if (!cmd_register(&version_info))
-		panic("could not register command %s\n", version_info.name);
-		
-		
-
+	int i;
+
+	for (i=0;basic_commands[i]; i++) {
+		cmd_initialize(basic_commands[i]);
+		if (!cmd_register(basic_commands[i]))
+			panic("could not register command %s\n", 
+			      basic_commands[i]->name);
+	}
 }
 
@@ -482,5 +452,5 @@
 	__address symaddr;
 	char *symbol;
-	__native (*f)(__native);
+	__native (*f)(__native,...);
 	__native arg1 = argv[1].intval;
 
@@ -494,5 +464,5 @@
 		symbol = get_symtab_entry(symaddr);
 		printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
-		f =  (__native (*)(__native)) symaddr;
+		f =  (__native (*)(__native,...)) symaddr;
 		printf("Result: 0x%p\n", f(arg1));
 	}
@@ -506,5 +476,5 @@
 	__address symaddr;
 	char *symbol;
-	__native (*f)(__native,__native);
+	__native (*f)(__native,__native,...);
 	__native arg1 = argv[1].intval;
 	__native arg2 = argv[2].intval;
@@ -520,5 +490,5 @@
 		printf("Calling f(0x%x,0x%x): 0x%p: %s\n", 
 		       arg1, arg2, symaddr, symbol);
-		f =  (__native (*)(__native,__native)) symaddr;
+		f =  (__native (*)(__native,__native,...)) symaddr;
 		printf("Result: 0x%p\n", f(arg1, arg2));
 	}
@@ -532,5 +502,5 @@
 	__address symaddr;
 	char *symbol;
-	__native (*f)(__native,__native,__native);
+	__native (*f)(__native,__native,__native,...);
 	__native arg1 = argv[1].intval;
 	__native arg2 = argv[2].intval;
@@ -547,5 +517,5 @@
 		printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n", 
 		       arg1, arg2, arg3, symaddr, symbol);
-		f =  (__native (*)(__native,__native,__native)) symaddr;
+		f =  (__native (*)(__native,__native,__native,...)) symaddr;
 		printf("Result: 0x%p\n", f(arg1, arg2, arg3));
 	}
@@ -628,4 +598,15 @@
 }
 
+/** Command for listings Thread information
+ *
+ * @param argv Ignores
+ *
+ * @return Always 1
+ */
+int cmd_sched(cmd_arg_t * argv) {
+	sched_print_list();
+	return 1;
+}
+
 /** Command for listing memory zones
  *
Index: generic/src/mm/slab.c
===================================================================
--- generic/src/mm/slab.c	(revision c5613b7239c9e986e13faac9e99cacf66da13608)
+++ generic/src/mm/slab.c	(revision 10e16a7258e74c3db1abf7fb13b527544a85950b)
@@ -77,5 +77,13 @@
  * magazines.
  *
- * 
+ * TODO: For better CPU-scaling the magazine allocation strategy should
+ * be extended. Currently, if the cache does not have magazine, it asks
+ * for non-cpu cached magazine cache to provide one. It might be feasible
+ * to add cpu-cached magazine cache (which would allocate it's magazines
+ * from non-cpu-cached mag. cache). This would provide a nice per-cpu
+ * buffer. The other possibility is to use the per-cache 
+ * 'empty-magazine-list', which decreases competing for 1 per-system
+ * magazine cache.
+ *
  */
 
@@ -296,5 +304,5 @@
  * Free all objects in magazine and free memory associated with magazine
  *
- * Assume mag_cache[cpu].lock is locked 
+ * Assume cache->lock is held
  *
  * @return Number of freed pages
@@ -620,4 +628,5 @@
 	
 	spinlock_unlock(&cache->lock);
+	/* We can release the cache locks now */
 	if (flags & SLAB_RECLAIM_ALL) {
 		for (i=0; i < config.cpu_count; i++)
@@ -778,5 +787,5 @@
 {
 	int idx;
-
+	
 	ASSERT( size && size <= (1 << SLAB_MAX_MALLOC_W));
 	
Index: generic/src/proc/scheduler.c
===================================================================
--- generic/src/proc/scheduler.c	(revision c5613b7239c9e986e13faac9e99cacf66da13608)
+++ generic/src/proc/scheduler.c	(revision 10e16a7258e74c3db1abf7fb13b527544a85950b)
@@ -627,2 +627,45 @@
 
 #endif /* CONFIG_SMP */
+
+
+/** Print information about threads & scheduler queues */
+void sched_print_list(void)
+{
+	ipl_t ipl;
+	int cpu,i;
+	runq_t *r;
+	thread_t *t;
+	link_t *cur;
+
+	/* We are going to mess with scheduler structures,
+	 * let's not be interrupted */
+	ipl = interrupts_disable();
+	printf("*********** Scheduler dump ***********\n");
+	for (cpu=0;cpu < config.cpu_count; cpu++) {
+		if (!cpus[cpu].active)
+			continue;
+		spinlock_lock(&cpus[cpu].lock);
+		printf("cpu%d: nrdy: %d needs_relink: %d\n",
+		       cpus[cpu].id, cpus[cpu].nrdy, cpus[cpu].needs_relink);
+		
+		for (i=0; i<RQ_COUNT; i++) {
+			r = &cpus[cpu].rq[i];
+			spinlock_lock(&r->lock);
+			if (!r->n) {
+				spinlock_unlock(&r->lock);
+				continue;
+			}
+			printf("Rq %d: ", i);
+			for (cur=r->rq_head.next; cur!=&r->rq_head; cur=cur->next) {
+				t = list_get_instance(cur, thread_t, rq_link);
+				printf("%d(%s) ", t->tid,
+				       thread_states[t->state]);
+			}
+			printf("\n");
+			spinlock_unlock(&r->lock);
+		}
+		spinlock_unlock(&cpus[cpu].lock);
+	}
+	
+	interrupts_restore(ipl);
+}
