Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/include/cpu.h	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -72,7 +72,11 @@
 	size_t missed_clock_ticks;
 	
+	/**
+	 * Processor cycle accounting.
+	 */
 	bool idle;
-	uint64_t idle_ticks;
-	uint64_t busy_ticks;
+	uint64_t last_cycle;
+	uint64_t idle_cycles;
+	uint64_t busy_cycles;
 	
 	/**
Index: kernel/generic/include/sysinfo/abi.h
===================================================================
--- kernel/generic/include/sysinfo/abi.h	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/include/sysinfo/abi.h	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -69,6 +69,6 @@
 	bool active;             /**< CPU is activate */
 	uint16_t frequency_mhz;  /**< Frequency in MHz */
-	uint64_t idle_ticks;     /**< Number of idle kernel quanta */
-	uint64_t busy_ticks;     /**< Number of busy kernel quanta */
+	uint64_t idle_cycles;    /**< Number of idle cycles */
+	uint64_t busy_cycles;    /**< Number of busy cycles */
 } stats_cpu_t;
 
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/src/cpu/cpu.c	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -49,4 +49,5 @@
 #include <print.h>
 #include <sysinfo/sysinfo.h>
+#include <arch/cycle.h>
 
 cpu_t *cpus;
@@ -94,4 +95,9 @@
 	CPU->tlb_active = true;
 	
+	CPU->idle = false;
+	CPU->last_cycle = get_cycle();
+	CPU->idle_cycles = 0;
+	CPU->busy_cycles = 0;
+	
 	cpu_identify();
 	cpu_arch_init();
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/src/interrupt/interrupt.c	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -99,4 +99,6 @@
 void exc_dispatch(unsigned int n, istate_t *istate)
 {
+	ASSERT(CPU);
+	
 #if (IVT_ITEMS > 0)
 	ASSERT(n < IVT_ITEMS);
@@ -109,4 +111,14 @@
 		irq_spinlock_unlock(&THREAD->lock, false);
 	}
+	
+	/* Account CPU usage if it has waked up from sleep */
+	irq_spinlock_lock(&CPU->lock, false);
+	if (CPU->idle) {
+		uint64_t now = get_cycle();
+		CPU->idle_cycles += now - CPU->last_cycle;
+		CPU->last_cycle = now;
+		CPU->idle = false;
+	}
+	irq_spinlock_unlock(&CPU->lock, false);
 	
 	uint64_t begin_cycle = get_cycle();
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/src/proc/scheduler.c	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -193,11 +193,9 @@
 		 * This improves energy saving and hyperthreading.
 		 */
-		
-		 /* Mark CPU as it was idle this clock tick */
 		irq_spinlock_lock(&CPU->lock, false);
 		CPU->idle = true;
 		irq_spinlock_unlock(&CPU->lock, false);
-		
 		interrupts_enable();
+		
 		/*
 		 * An interrupt might occur right now and wake up a thread.
@@ -386,5 +384,5 @@
 	as_t *old_as = AS;
 	
-	ASSERT(!THREAD || irq_spinlock_locked(&THREAD->lock));
+	ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
 	ASSERT(CPU != NULL);
 	
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/src/sysinfo/stats.c	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -124,6 +124,6 @@
 		stats_cpus[i].active = cpus[i].active;
 		stats_cpus[i].frequency_mhz = cpus[i].frequency_mhz;
-		stats_cpus[i].busy_ticks = cpus[i].busy_ticks;
-		stats_cpus[i].idle_ticks = cpus[i].idle_ticks;
+		stats_cpus[i].busy_cycles = cpus[i].busy_cycles;
+		stats_cpus[i].idle_cycles = cpus[i].idle_cycles;
 		
 		irq_spinlock_unlock(&cpus[i].lock, true);
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 2319df3fb307138936718465566682581aa7fbf3)
+++ kernel/generic/src/time/clock.c	(revision 538780736253a52c38332ffe3f75d60f64190f4e)
@@ -57,4 +57,5 @@
 #include <mm/frame.h>
 #include <ddi/ddi.h>
+#include <arch/cycle.h>
 
 /* Pointer to variable with uptime */
@@ -125,4 +126,13 @@
 }
 
+static void cpu_update_accounting(void)
+{
+	irq_spinlock_lock(&CPU->lock, false);
+	uint64_t now = get_cycle();
+	CPU->busy_cycles += now - CPU->last_cycle;
+	CPU->last_cycle = now;
+	irq_spinlock_unlock(&CPU->lock, false);
+}
+
 /** Clock routine
  *
@@ -136,11 +146,6 @@
 	size_t missed_clock_ticks = CPU->missed_clock_ticks;
 	
-	/* Account lost ticks to CPU usage */
-	if (CPU->idle)
-		CPU->idle_ticks += missed_clock_ticks + 1;
-	else
-		CPU->busy_ticks += missed_clock_ticks + 1;
-	
-	CPU->idle = false;
+	/* Account CPU usage */
+	cpu_update_accounting();
 	
 	/*
@@ -151,5 +156,8 @@
 	size_t i;
 	for (i = 0; i <= missed_clock_ticks; i++) {
+		/* Update counters and accounting */
 		clock_update_counters();
+		cpu_update_accounting();
+		
 		irq_spinlock_lock(&CPU->timeoutlock, false);
 		
