Index: kernel/generic/include/arch.h
===================================================================
--- kernel/generic/include/arch.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/arch.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -36,8 +36,7 @@
 #define KERN_ARCH_H_
 
-#include <arch/arch.h>
-#include <proc/thread.h>
-#include <proc/task.h>
-#include <mm/as.h>
+#include <arch/arch.h>  /* arch_pre_main() */
+#include <arch/asm.h>   /* get_stack_base() */
+
 
 /*
@@ -49,10 +48,4 @@
 #define THE  ((the_t * )(get_stack_base()))
 
-#define CPU                  THE->cpu
-#define THREAD               THE->thread
-#define TASK                 THE->task
-#define AS                   THE->as
-#define PREEMPTION_DISABLED  (0 != THE->preemption_disabled)
-#define PREEMPTION_ENABLED   (0 == THE->preemption_disabled)
 #define MAGIC                UINT32_C(0xfacefeed)
 
@@ -63,4 +56,10 @@
 	((THE->task) ? (THE->task->container) : (DEFAULT_CONTAINER))
 
+/* Fwd decl. to avoid include hell. */
+struct thread;
+struct task;
+struct cpu;
+struct as;
+
 /**
  * For each possible kernel stack, structure
@@ -69,10 +68,10 @@
  */
 typedef struct {
-	size_t preemption_disabled;  /**< Preemption disabled counter. */
-	thread_t *thread;            /**< Current thread. */
-	task_t *task;                /**< Current task. */
-	cpu_t *cpu;                  /**< Executing cpu. */
-	as_t *as;                    /**< Current address space. */
-	uint32_t magic;              /**< Magic value */
+	size_t preemption;     /**< Preemption disabled counter and flag. */
+	struct thread *thread; /**< Current thread. */
+	struct task *task;     /**< Current task. */
+	struct cpu *cpu;       /**< Executing cpu. */
+	struct as *as;         /**< Current address space. */
+	uint32_t magic;        /**< Magic value */
 } the_t;
 
@@ -92,4 +91,5 @@
 extern void *arch_construct_function(fncptr_t *, void *, void *);
 
+
 #endif
 
Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/cpu.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -43,4 +43,8 @@
 #include <arch/context.h>
 #include <adt/list.h>
+#include <arch.h>
+
+#define CPU                  THE->cpu
+
 
 /** CPU structure.
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/mm/as.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -48,4 +48,8 @@
 #include <adt/btree.h>
 #include <lib/elf.h>
+#include <arch.h>
+
+#define AS                   THE->as
+
 
 /**
Index: kernel/generic/include/preemption.h
===================================================================
--- kernel/generic/include/preemption.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/preemption.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -36,10 +36,43 @@
 #define KERN_PREEMPTION_H_
 
-extern void preemption_disable(void);
-extern void preemption_enable(void);
-extern void preemption_enable_noresched(void);
-extern void preemption_enabled_scheduler(void);
+#include <arch.h>
+#include <compiler/barrier.h>
+#include <debug.h>
+
+#define PREEMPTION_INC         (1 << 1)
+#define PREEMPTION_NEEDED_FLAG (1 << 0)
+#define PREEMPTION_NEEDED      (THE->preemption & PREEMPTION_NEEDED_FLAG)
+#define PREEMPTION_DISABLED    (PREEMPTION_INC <= THE->preemption)
+#define PREEMPTION_ENABLED     (!PREEMPTION_DISABLED)
+
+/** Increment preemption disabled counter. */
+#define preemption_disable() \
+	do { \
+		THE->preemption += PREEMPTION_INC; \
+		compiler_barrier(); \
+	} while (0)
+
+/** Restores preemption and reschedules if out time slice already elapsed.*/
+#define preemption_enable() \
+	do { \
+		preemption_enable_noresched(); \
+		\
+		if (PREEMPTION_ENABLED && PREEMPTION_NEEDED) { \
+			preemption_enabled_scheduler(); \
+		} \
+	} while (0)
+
+/** Restores preemption but never reschedules. */
+#define preemption_enable_noresched() \
+	do { \
+		ASSERT(PREEMPTION_DISABLED); \
+		compiler_barrier(); \
+		THE->preemption -= PREEMPTION_INC; \
+	} while (0)
 
 
+extern void preemption_enabled_scheduler(void);
+extern void preemption_set_needed(void);
+extern void preemption_clear_needed(void);
 
 #endif
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/proc/task.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -57,4 +57,8 @@
 #include <mm/as.h>
 #include <abi/sysinfo.h>
+#include <arch.h>
+
+#define TASK                 THE->task
+
 
 struct thread;
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision b23c88e8d625f4041bc622f650332526f02cba8e)
+++ kernel/generic/include/proc/thread.h	(revision 935e28c8aa3b9baab3bd1019dc4ef58654e3ff93)
@@ -49,4 +49,8 @@
 #include <udebug/udebug.h>
 #include <abi/sysinfo.h>
+#include <arch.h>
+
+
+#define THREAD              THE->thread
 
 #define THREAD_NAME_BUFLEN  20
@@ -155,7 +159,4 @@
 	state_t state;
 	
-	/** The thread would have been rescheduled had it not disabled preemption.*/
-	bool need_resched;
-	
 	/** Thread CPU. */
 	cpu_t *cpu;
