Index: uspace/app/tasks/tasks.c
===================================================================
--- uspace/app/tasks/tasks.c	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/tasks/tasks.c	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -59,8 +59,7 @@
 {
 	size_t count;
-	task_id_t *ids =
-	    (task_id_t *) stats_get_tasks(&count);
-	
-	if (ids == NULL) {
+	stats_task_t *stats_tasks = stats_get_tasks(&count);
+	
+	if (stats_tasks == NULL) {
 		fprintf(stderr, "%s: Unable to get tasks\n", NAME);
 		return;
@@ -71,24 +70,18 @@
 	size_t i;
 	for (i = 0; i < count; i++) {
-		stats_task_t *stats_task = stats_get_task(ids[i]);
-		if (stats_task != NULL) {
-			uint64_t virtmem, ucycles, kcycles;
-			char vmsuffix, usuffix, ksuffix;
-			
-			order_suffix(stats_task->virtmem, &virtmem, &vmsuffix);
-			order_suffix(stats_task->ucycles, &ucycles, &usuffix);
-			order_suffix(stats_task->kcycles, &kcycles, &ksuffix);
-			
-			printf("%8" PRIu64 "%8u %8" PRIu64"%c %12"
-			    PRIu64 "%c %12" PRIu64 "%c %s\n", ids[i], stats_task->threads,
-			    virtmem, vmsuffix, ucycles, usuffix, kcycles, ksuffix,
-			    stats_task->name);
-			
-			free(stats_task);
-		} else
-			printf("%8" PRIu64 "\n", ids[i]);
-	}
-	
-	free(ids);
+		uint64_t virtmem, ucycles, kcycles;
+		char vmsuffix, usuffix, ksuffix;
+		
+		order_suffix(stats_tasks[i].virtmem, &virtmem, &vmsuffix);
+		order_suffix(stats_tasks[i].ucycles, &ucycles, &usuffix);
+		order_suffix(stats_tasks[i].kcycles, &kcycles, &ksuffix);
+		
+		printf("%8" PRIu64 "%8u %8" PRIu64"%c %12"
+		    PRIu64 "%c %12" PRIu64 "%c %s\n", stats_tasks[i].task_id,
+		    stats_tasks[i].threads, virtmem, vmsuffix, ucycles, usuffix,
+		    kcycles, ksuffix, stats_tasks[i].name);
+	}
+	
+	free(stats_tasks);
 }
 
@@ -96,8 +89,7 @@
 {
 	size_t count;
-	thread_id_t *ids =
-	    (thread_id_t *) stats_get_threads(&count);
-	
-	if (ids == NULL) {
+	stats_thread_t *stats_threads = stats_get_threads(&count);
+	
+	if (stats_threads == NULL) {
 		fprintf(stderr, "%s: Unable to get threads\n", NAME);
 		return;
@@ -107,34 +99,28 @@
 	size_t i;
 	for (i = 0; i < count; i++) {
-		stats_thread_t *stats_thread = stats_get_thread(ids[i]);
-		if (stats_thread != NULL) {
-			if ((all) || (stats_thread->task_id == task_id)) {
-				uint64_t ucycles, kcycles;
-				char usuffix, ksuffix;
-				
-				order_suffix(stats_thread->ucycles, &ucycles, &usuffix);
-				order_suffix(stats_thread->kcycles, &kcycles, &ksuffix);
-				
-				if (stats_thread->on_cpu) {
-					printf("%8" PRIu64 " %-8s %4u %6d %12"
-					    PRIu64"%c %12" PRIu64"%c\n", ids[i],
-					    thread_get_state(stats_thread->state),
-					    stats_thread->cpu, stats_thread->priority,
-					    ucycles, usuffix, kcycles, ksuffix);
-				} else {
-					printf("%8" PRIu64 " %-8s ---- %6d %12"
-					    PRIu64"%c %12" PRIu64"%c\n", ids[i],
-					    thread_get_state(stats_thread->state),
-					    stats_thread->priority,
-					    ucycles, usuffix, kcycles, ksuffix);
-				}
+		if ((all) || (stats_threads[i].task_id == task_id)) {
+			uint64_t ucycles, kcycles;
+			char usuffix, ksuffix;
+			
+			order_suffix(stats_threads[i].ucycles, &ucycles, &usuffix);
+			order_suffix(stats_threads[i].kcycles, &kcycles, &ksuffix);
+			
+			if (stats_threads[i].on_cpu) {
+				printf("%8" PRIu64 " %-8s %4u %6d %12"
+				    PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id,
+				    thread_get_state(stats_threads[i].state),
+				    stats_threads[i].cpu, stats_threads[i].priority,
+				    ucycles, usuffix, kcycles, ksuffix);
+			} else {
+				printf("%8" PRIu64 " %-8s ---- %6d %12"
+				    PRIu64"%c %12" PRIu64"%c\n", stats_threads[i].thread_id,
+				    thread_get_state(stats_threads[i].state),
+				    stats_threads[i].priority,
+				    ucycles, usuffix, kcycles, ksuffix);
 			}
-			
-			free(stats_thread);
-		} else if (all)
-			printf("%8" PRIu64 "\n", ids[i]);
-	}
-	
-	free(ids);
+		}
+	}
+	
+	free(stats_threads);
 }
 
Index: uspace/app/top/Makefile
===================================================================
--- uspace/app/top/Makefile	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/top/Makefile	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -29,11 +29,10 @@
 
 USPACE_PREFIX = ../..
-# BINARY = top
+BINARY = top
 
 SOURCES = \
 	top.c \
 	screen.c \
-	input.c \
-	ps.c
+	input.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/top/ps.c
===================================================================
--- uspace/app/top/ps.c	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ 	(revision )
@@ -1,111 +1,0 @@
-/*
- * Copyright (c) 2010 Stanislav Kozina
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup top
- * @brief Task lister.
- * @{
- */
-/**
- * @file
- */
-
-#include <stdio.h>
-#include <task.h>
-#include <thread.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <ps.h>
-#include <sysinfo.h>
-#include "ps.h"
-
-#define TASK_COUNT 10
-#define THREAD_COUNT 50
-
-/** Thread states */
-const char *thread_states[] = {
-	"Invalid",
-	"Running",
-	"Sleeping",
-	"Ready",
-	"Entering",
-	"Exiting",
-	"Lingering"
-}; 
-
-size_t get_tasks(task_info_t **out_infos)
-{
-	size_t task_count = TASK_COUNT;
-	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
-	size_t result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
-
-	while (result > task_count) {
-		task_count *= 2;
-		tasks = realloc(tasks, task_count * sizeof(task_id_t));
-		result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
-	}
-
-	size_t i;
-	task_info_t *taskinfos = malloc(result * sizeof(task_info_t));
-	for (i = 0; i < result; ++i) {
-		get_task_info(tasks[i], &taskinfos[i]);
-	}
-
-	free(tasks);
-
-	*out_infos = taskinfos;
-	return result;
-}
-
-size_t get_threads(thread_info_t **thread_infos)
-{
-	size_t thread_count = THREAD_COUNT;
-	thread_info_t *threads = malloc(thread_count * sizeof(thread_info_t));
-	size_t result = get_task_threads(threads, sizeof(thread_info_t) * thread_count);
-
-	while (result > thread_count) {
-		thread_count *= 2;
-		threads = realloc(threads, thread_count * sizeof(thread_info_t));
-		result = get_task_threads(threads, sizeof(thread_info_t) * thread_count);
-	}
-	
-	*thread_infos = threads;
-	return result;
-}
-
-unsigned int get_cpu_infos(uspace_cpu_info_t **out_infos)
-{
-	unsigned int cpu_count = sysinfo_value("cpu.count");
-	uspace_cpu_info_t *cpus = malloc(cpu_count * sizeof(uspace_cpu_info_t));
-	get_cpu_info(cpus);
-
-	*out_infos = cpus;
-	return cpu_count;
-}
-
-/** @}
- */
Index: uspace/app/top/ps.h
===================================================================
--- uspace/app/top/ps.h	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2008 Stanislav Kozina
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup top
- * @{
- */
-
-#ifndef TOP_PS_H_
-#define TOP_PS_H_
-
-#include <task.h>
-#include <kernel/ps/taskinfo.h>
-#include <kernel/ps/cpuinfo.h>
-
-extern const char *thread_states[];
-extern size_t get_tasks(task_info_t **out_infos);
-extern size_t get_threads(thread_info_t **thread_infos);
-extern unsigned int get_cpu_infos(uspace_cpu_info_t **out_infos);
-
-#endif
-
-/**
- * @}
- */
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/top/screen.c	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 Martin Decky
  * All rights reserved.
  *
@@ -38,30 +39,30 @@
 #include <io/console.h>
 #include <vfs/vfs.h>
-#include <load.h>
-#include <kernel/ps/taskinfo.h>
-#include <ps.h>
+#include <stdarg.h>
+#include <stats.h>
+#include <inttypes.h>
 #include "screen.h"
 #include "top.h"
-#include "func.h"
-
-int rows;
-int colls;
-int up_rows;
-
-#define WHITE 0xf0f0f0
-#define BLACK 0x000000
-
-static void print_float(ps_float f, int precision)
-{
-	printf("%2u.", f.upper / f.lower);
-	int i;
-	unsigned int rest = (f.upper % f.lower) * 10;
-	for (i = 0; i < precision; ++i) {
-		printf("%d", rest / f.lower);
-		rest = (rest % f.lower) * 10;
-	}
-}
-
-static void resume_normal(void)
+
+#define WHITE  0xf0f0f0
+#define BLACK  0x000000
+
+static int rows;
+static int colls;
+static int up_rows;
+
+static void print_float(fixed_float ffloat, unsigned int precision)
+{
+	printf("%2" PRIu64 ".", ffloat.upper / ffloat.lower);
+	
+	unsigned int i;
+	uint64_t rest = (ffloat.upper % ffloat.lower) * 10;
+	for (i = 0; i < precision; i++) {
+		printf("%" PRIu64, rest / ffloat.lower);
+		rest = (rest % ffloat.lower) * 10;
+	}
+}
+
+static void screen_resume_normal(void)
 {
 	fflush(stdout);
@@ -69,136 +70,162 @@
 }
 
+static void screen_moveto(int r, int c)
+{
+	fflush(stdout);
+	console_goto(fphone(stdout), c, r);
+}
+
+static void screen_clear(void)
+{
+	console_clear(fphone(stdout));
+	screen_moveto(0, 0);
+	up_rows = 0;
+	fflush(stdout);
+}
+
 void screen_init(void)
 {
+	console_cursor_visibility(fphone(stdout), 0);
+	screen_resume_normal();
+	screen_clear();
+	
 	console_get_size(fphone(stdout), &colls, &rows);
-	up_rows = 0;
-	console_cursor_visibility(fphone(stdout), 0);
-	resume_normal();
-	clear_screen();
-}
-
-void clear_screen(void)
-{
-	console_clear(fphone(stdout));
-	moveto(0, 0);
-	up_rows = 0;
-	fflush(stdout);
-}
-
-void moveto(int r, int c)
-{
-	fflush(stdout);
-	console_goto(fphone(stdout), c, r);
+}
+
+void screen_done(void)
+{
+	screen_resume_normal();
+	screen_clear();
+	console_cursor_visibility(fphone(stdout), 1);
 }
 
 static inline void print_time(data_t *data)
 {
-	printf("%02d:%02d:%02d ", data->hours, data->minutes, data->seconds);
+	printf("%02lu:%02lu:%02lu ", data->hours, data->minutes, data->seconds);
 }
 
 static inline void print_uptime(data_t *data)
 {
-	printf("up %4d days, %02d:%02d:%02d, ", data->uptime_d, data->uptime_h,
-		data->uptime_m, data->uptime_s);
+	printf("up %u days, %02u:%02u:%02u, ", data->udays, data->uhours,
+	    data->uminutes, data->useconds);
 }
 
 static inline void print_load(data_t *data)
 {
-	puts("load avarage: ");
-	print_load_fragment(data->load[0], 2);
-	puts(" ");
-	print_load_fragment(data->load[1], 2);
-	puts(" ");
-	print_load_fragment(data->load[2], 2);
-}
-
-static inline void print_taskstat(data_t *data)
-{
-	puts("Tasks: ");
-	printf("%4u total", data->task_count);
-}
-
-static inline void print_threadstat(data_t *data)
-{
+	printf("load avarage: ");
+	
+	size_t i;
+	for (i = 0; i < data->load_count; i++) {
+		stats_print_load_fragment(data->load[i], 2);
+		printf(" ");
+	}
+}
+
+static inline void print_task_summary(data_t *data)
+{
+	printf("tasks: %u total", data->tasks_count);
+}
+
+static inline void print_thread_summary(data_t *data)
+{
+	size_t total = 0;
+	size_t running = 0;
+	size_t ready = 0;
 	size_t sleeping = 0;
-	size_t running = 0;
+	size_t lingering = 0;
+	size_t other = 0;
 	size_t invalid = 0;
-	size_t other = 0;
-	size_t total = 0;
-	size_t i;
-	for (i = 0; i < data->thread_count; ++i) {
-		++total;
-		switch (data->thread_infos[i].state) {
-			case Invalid:
-			case Lingering:
-				++invalid;
-				break;
-			case Running:
-			case Ready:
-				++running;
-				break;
-			case Sleeping:
-				++sleeping;
-				break;
-			case Entering:
-			case Exiting:
-				++other;
-				break;
+	
+	
+	size_t i;
+	for (i = 0; i < data->threads_count; i++) {
+		total++;
+		
+		switch (data->threads[i].state) {
+		case Running:
+			running++;
+			break;
+		case Ready:
+			ready++;
+			break;
+		case Sleeping:
+			sleeping++;
+			break;
+		case Lingering:
+			lingering++;
+			break;
+		case Entering:
+		case Exiting:
+			other++;
+			break;
+		default:
+			invalid++;
 		}
 	}
-	printf("Threads: %5u total, %5u running, %5u sleeping, %5u invalid, %5u other",
-		total, running, sleeping, invalid, other);
-}
-
-static inline void print_cpuinfo(data_t *data)
-{
-	unsigned int i;
-	uspace_cpu_info_t *cpus = data->cpus;
-	for (i = 0; i < data->cpu_count; ++i) {
-		printf("Cpu%u (%4u Mhz): Busy ticks: %6llu, Idle Ticks: %6llu",
-			i, (unsigned int)cpus[i].frequency_mhz, cpus[i].busy_ticks,
-			cpus[i].idle_ticks);
+	
+	printf("threads: %u total, %u running, %u ready, %u sleeping, %u lingering, "
+	    "%u other, %u invalid",
+	    total, running, ready, sleeping, lingering, other, invalid);
+}
+
+static inline void print_cpu_info(data_t *data)
+{
+	size_t i;
+	for (i = 0; i < data->cpus_count; i++) {
+		printf("cpu%u (%4" PRIu16 " MHz): busy ticks: "
+		    "%" PRIu64 ", idle ticks: %" PRIu64,
+		    data->cpus[i].id, data->cpus[i].frequency_mhz,
+		    data->cpus[i].busy_ticks, data->cpus[i].idle_ticks);
 		printf(", idle: ");
-		print_float(data->cpu_perc[i].idle, 2);
-		puts("%, busy: ");
-		print_float(data->cpu_perc[i].busy, 2);
-		puts("%\n");
-		++up_rows;
-	}
-}
-
-static inline void print_meminfo(data_t *data)
-{
-	uint64_t newsize;
-	char suffix;
-	order(data->mem_info.total, &newsize, &suffix);
-	printf("Mem: %8llu %c total", newsize, suffix);
-	order(data->mem_info.used, &newsize, &suffix);
-	printf(", %8llu %c used", newsize, suffix);
-	order(data->mem_info.free, &newsize, &suffix);
-	printf(", %8llu %c free", newsize, suffix);
+		print_float(data->cpus_perc[i].idle, 2);
+		printf("%%, busy: ");
+		print_float(data->cpus_perc[i].busy, 2);
+		
+		printf("%%\n");
+		up_rows++;
+	}
+}
+
+static inline void print_physmem_info(data_t *data)
+{
+	uint64_t total;
+	uint64_t unavail;
+	uint64_t used;
+	uint64_t free;
+	char total_suffix;
+	char unavail_suffix;
+	char used_suffix;
+	char free_suffix;
+	
+	order_suffix(data->physmem->total, &total, &total_suffix);
+	order_suffix(data->physmem->unavail, &unavail, &unavail_suffix);
+	order_suffix(data->physmem->used, &used, &used_suffix);
+	order_suffix(data->physmem->free, &free, &free_suffix);
+	
+	printf("memory: %" PRIu64 "%c total, %" PRIu64 "%c unavail, %"
+	    PRIu64 "%c used, %" PRIu64 "%c free", total, total_suffix,
+	    unavail, unavail_suffix, used, used_suffix, free, free_suffix);
 }
 
 static inline void print_tasks(data_t *data, int row)
 {
-	int i;
-	for (i = 0; i < (int)data->task_count; ++i) {
-		if (row + i > rows)
-			return;
-		task_info_t *taskinfo = &data->taskinfos[i];
-		uint64_t mem;
-		char suffix;
-		order(taskinfo->virt_mem, &mem, &suffix);
-		printf("%8llu %8u %8llu%c ", taskinfo->taskid,
-			taskinfo->thread_count, mem, suffix);
-		task_perc_t *taskperc = &data->task_perc[i];
-		puts("   ");
-		print_float(taskperc->mem, 2);
-		puts("%   ");
-		print_float(taskperc->ucycles, 2);
-		puts("%   ");
-		print_float(taskperc->kcycles, 2);
-		puts("% ");
-		printf("%s\n", taskinfo->name);
+	size_t i;
+	for (i = 0; i < data->tasks_count; i++, row++) {
+		if (row > rows)
+			break;
+		
+		uint64_t virtmem;
+		char virtmem_suffix;
+		order_suffix(data->tasks[i].virtmem, &virtmem, &virtmem_suffix);
+		
+		printf("%8" PRIu64 " %8u %8" PRIu64 "%c ", data->tasks[i].task_id,
+		    data->tasks[i].threads, virtmem, virtmem_suffix);
+		printf("   ");
+		print_float(data->tasks_perc[i].virtmem, 2);
+		printf("%%   ");
+		print_float(data->tasks_perc[i].ucycles, 2);
+		printf("%%   ");
+		print_float(data->tasks_perc[i].kcycles, 2);
+		printf("%% %s\n", data->tasks[i].name);
 	}
 }
@@ -208,8 +235,11 @@
 	fflush(stdout);
 	console_set_rgb_color(fphone(stdout), WHITE, BLACK);
+	
 	printf("      ID  Threads      Mem      %%Mem %%uCycles %%kCycles  Name");
+	
 	int i;
 	for (i = 61; i < colls; ++i)
-		puts(" ");
+		printf(" ");
+	
 	fflush(stdout);
 	console_set_rgb_color(fphone(stdout), BLACK, WHITE);
@@ -220,8 +250,11 @@
 	fflush(stdout);
 	console_set_rgb_color(fphone(stdout), WHITE, BLACK);
+	
 	printf("      ID Calls sent Calls recv Answs sent Answs recv  IRQn recv       Forw Name");
+	
 	int i;
 	for (i = 80; i < colls; ++i)
-		puts(" ");
+		printf(" ");
+	
 	fflush(stdout);
 	console_set_rgb_color(fphone(stdout), BLACK, WHITE);
@@ -230,16 +263,17 @@
 static inline void print_ipc(data_t *data, int row)
 {
-	int i;
-	for (i = 0; i < (int)data->task_count; ++i) {
-		if (row + i > rows)
-			return;
-		task_info_t *taskinfo = &data->taskinfos[i];
-		task_ipc_info_t *ipcinfo = &taskinfo->ipc_info;
-		printf("%8llu ", taskinfo->taskid);
-		printf("%10llu %10llu %10llu %10llu %10llu %10llu ",
-				ipcinfo->call_sent, ipcinfo->call_recieved,
-				ipcinfo->answer_sent, ipcinfo->answer_recieved,
-				ipcinfo->irq_notif_recieved, ipcinfo->forwarded);
-		printf("%s\n", taskinfo->name);
+	size_t i;
+	for (i = 0; i < data->tasks_count; i++, row++) {
+		if (row > rows)
+			break;
+		
+		printf("%8" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64
+		     " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %s\n",
+		     data->tasks[i].task_id, data->tasks[i].ipc_info.call_sent,
+		     data->tasks[i].ipc_info.call_recieved,
+		     data->tasks[i].ipc_info.answer_sent,
+		     data->tasks[i].ipc_info.answer_recieved,
+		     data->tasks[i].ipc_info.irq_notif_recieved,
+		     data->tasks[i].ipc_info.forwarded, data->tasks[i].name);
 	}
 }
@@ -247,33 +281,56 @@
 void print_data(data_t *data)
 {
-	clear_screen();
-	fflush(stdout);
+	screen_clear();
+	fflush(stdout);
+	
 	printf("top - ");
 	print_time(data);
 	print_uptime(data);
 	print_load(data);
-	puts("\n");
-	++up_rows;
-	print_taskstat(data);
-	puts("\n");
-	++up_rows;
-	print_threadstat(data);
-	puts("\n");
-	++up_rows;
-	print_cpuinfo(data);
-	print_meminfo(data);
-	puts("\n");
-	++up_rows;
-	puts("\n");
-	++up_rows;
+	
+	printf("\n");
+	up_rows++;
+	
+	print_task_summary(data);
+	
+	printf("\n");
+	up_rows++;
+	
+	print_thread_summary(data);
+	
+	printf("\n");
+	up_rows++;
+	
+	print_cpu_info(data);
+	print_physmem_info(data);
+	
+	printf("\n");
+	up_rows++;
+	
+	/* Empty row for warnings */
+	printf("\n");
+	
 	if (operation_type == OP_IPC) {
 		print_ipc_head();
-		puts("\n");
+		printf("\n");
 		print_ipc(data, up_rows);
 	} else {
 		print_task_head();
-		puts("\n");
+		printf("\n");
 		print_tasks(data, up_rows);
 	}
+	
+	fflush(stdout);
+}
+
+void print_warning(const char *fmt, ...)
+{
+	screen_moveto(up_rows, 0);
+	
+	va_list args;
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+	
 	fflush(stdout);
 }
Index: uspace/app/top/screen.h
===================================================================
--- uspace/app/top/screen.h	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/top/screen.h	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -1,4 +1,5 @@
 /*
- * Copyright (c) 2008 Stanislav Kozina
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 Martin Decky
  * All rights reserved.
  *
@@ -36,19 +37,8 @@
 #include "top.h"
 
-extern int rows;
-extern int colls;
-
 extern void screen_init(void);
-extern void clear_screen(void);
-extern void moveto(int r, int c);
-extern void print_data(data_t *data);
-
-extern int up_rows;
-#define PRINT_WARNING(message, ...) \
-do { \
-	moveto(up_rows - 1, 0); \
-	printf(message, ##__VA_ARGS__); \
-	fflush(stdout); \
-} while (0)
+extern void screen_done(void);
+extern void print_data(data_t *);
+extern void print_warning(const char *, ...);
 
 #endif
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/top/top.c	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 Martin Decky
  * All rights reserved.
  *
@@ -38,92 +39,142 @@
 #include <stdlib.h>
 #include <unistd.h>
-#include <uptime.h>
 #include <task.h>
 #include <thread.h>
 #include <sys/time.h>
-#include <load.h>
-#include <ps.h>
 #include <arch/barrier.h>
+#include <errno.h>
 #include "screen.h"
 #include "input.h"
 #include "top.h"
-#include "ps.h"
-
-#define UPDATE_INTERVAL 1
-
-#define DAY 86400
-#define HOUR 3600
-#define MINUTE 60
+
+#define NAME  "top"
+
+#define UPDATE_INTERVAL  1
+
+#define DAY     86400
+#define HOUR    3600
+#define MINUTE  60
 
 int operation_type;
 
-static void read_data(data_t *target)
+static const char *read_data(data_t *target)
 {
-	/* Read current time */
+	/* Initialize data */
+	target->load = NULL;
+	target->cpus = NULL;
+	target->cpus_perc = NULL;
+	target->tasks = NULL;
+	target->tasks_perc = NULL;
+	target->threads = NULL;
+	target->physmem = NULL;
+	
+	/* Get current time */
 	struct timeval time;
-	if (gettimeofday(&time, NULL) != 0) {
-		printf("Cannot get time of day!\n");
-		exit(1);
-	}
+	if (gettimeofday(&time, NULL) != EOK)
+		return "Cannot get time of day";
+	
 	target->hours = (time.tv_sec % DAY) / HOUR;
 	target->minutes = (time.tv_sec % HOUR) / MINUTE;
 	target->seconds = time.tv_sec % MINUTE;
-
-	/* Read uptime */
-	uint64_t uptime;
-	get_uptime(&uptime);
-	target->uptime_d = uptime / DAY;
-	target->uptime_h = (uptime % DAY) / HOUR;
-	target->uptime_m = (uptime % HOUR) / MINUTE;
-	target->uptime_s = uptime % MINUTE;
-
-	/* Read load */
-	get_load(target->load);
-
-	/* Read task ids */
-	target->task_count = get_tasks(&target->taskinfos);
-
-	/* Read all threads */
-	target->thread_count = get_threads(&target->thread_infos);
-
-	/* Read cpu infos */
-	target->cpu_count = get_cpu_infos(&target->cpus);
-
-	/* Read mem info */
-	get_mem_info(&target->mem_info);
+	
+	/* Get uptime */
+	sysarg_t uptime = stats_get_uptime();
+	target->udays = uptime / DAY;
+	target->uhours = (uptime % DAY) / HOUR;
+	target->uminutes = (uptime % HOUR) / MINUTE;
+	target->useconds = uptime % MINUTE;
+	
+	/* Get load */
+	target->load = stats_get_load(&(target->load_count));
+	if (target->load == NULL)
+		return "Cannot get system load";
+	
+	/* Get CPUs */
+	target->cpus = stats_get_cpus(&(target->cpus_count));
+	if (target->cpus == NULL)
+		return "Cannot get CPUs";
+	
+	target->cpus_perc =
+	    (perc_cpu_t *) calloc(target->cpus_count, sizeof(perc_cpu_t));
+	if (target->cpus_perc == NULL)
+		return "Not enough memory for CPU utilization";
+	
+	/* Get tasks */
+	target->tasks = stats_get_tasks(&(target->tasks_count));
+	if (target->tasks == NULL)
+		return "Cannot get tasks";
+	
+	target->tasks_perc =
+	    (perc_task_t *) calloc(target->tasks_count, sizeof(perc_task_t));
+	if (target->tasks_perc == NULL)
+		return "Not enough memory for task utilization";
+	
+	/* Get threads */
+	target->threads = stats_get_threads(&(target->threads_count));
+	if (target->threads == NULL)
+		return "Cannot get threads";
+	
+	/* Get physical memory */
+	target->physmem = stats_get_physmem();
+	if (target->physmem == NULL)
+		return "Cannot get physical memory";
+	
+	return NULL;
 }
 
 /** Computes percentage differencies from old_data to new_data
  *
- * @param old_data	Pointer to old data strucutre.
- * @param new_data	Pointer to actual data where percetages are stored.
- *
- */
-static void compute_percentages(data_t *old_data, data_t *new_data)
+ * @param old_data Pointer to old data strucutre.
+ * @param new_data Pointer to actual data where percetages are stored.
+ *
+ */
+static const char *compute_percentages(data_t *old_data, data_t *new_data)
 {
-	/* Foreach cpu, compute total ticks and divide it between user and
-	 * system */
-	unsigned int i;
-	new_data->cpu_perc = malloc(new_data->cpu_count * sizeof(cpu_perc_t));
-	for (i = 0; i < new_data->cpu_count; ++i) {
-		uint64_t idle = new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
-		uint64_t busy = new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
+	/* Allocate memory */
+	
+	uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
+	if (ucycles_diff == NULL)
+		return "Not enough memory for user utilization";
+	
+	uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
+	if (kcycles_diff == NULL) {
+		free(ucycles_diff);
+		return "Not enough memory for kernel utilization";
+	}
+	
+	/* For each CPU: Compute total ticks and divide it between
+	   user and kernel */
+	
+	size_t i;
+	for (i = 0; i < new_data->cpus_count; i++) {
+		uint64_t idle =
+		    new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
+		uint64_t busy =
+		    new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
 		uint64_t sum = idle + busy;
-		FRACTION_TO_FLOAT(new_data->cpu_perc[i].idle, idle * 100, sum);
-		FRACTION_TO_FLOAT(new_data->cpu_perc[i].busy, busy * 100, sum);
-	}
-
+		
+		FRACTION_TO_FLOAT(new_data->cpus_perc[i].idle, idle * 100, sum);
+		FRACTION_TO_FLOAT(new_data->cpus_perc[i].busy, busy * 100, sum);
+	}
+	
 	/* For all tasks compute sum and differencies of all cycles */
-	uint64_t mem_total = 1; /*< Must NOT be null! */
-	uint64_t ucycles_total = 1; /*< Must NOT be null! */
-	uint64_t kcycles_total = 1; /*< Must NOT be null! */
-	uint64_t *ucycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
-	uint64_t *kcycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
-	unsigned int j = 0;
-	for (i = 0; i < new_data->task_count; ++i) {
-		/* Jump over all death tasks */
-		while (old_data->taskinfos[j].taskid < new_data->taskinfos[i].taskid)
-			++j;
-		if (old_data->taskinfos[j].taskid > new_data->taskinfos[i].taskid) {
+	
+	uint64_t virtmem_total = 1;  /* Must NOT be zero */
+	uint64_t ucycles_total = 1;  /* Must NOT be zero */
+	uint64_t kcycles_total = 1;  /* Must NOT be zero */
+	
+	for (i = 0; i < new_data->tasks_count; i++) {
+		/* Match task with the previous instance */
+		
+		bool found = false;
+		size_t j;
+		for (j = 0; j < old_data->tasks_count; j++) {
+			if (new_data->tasks[i].task_id == old_data->tasks[j].task_id) {
+				found = true;
+				break;
+			}
+		}
+		
+		if (!found) {
 			/* This is newly borned task, ignore it */
 			ucycles_diff[i] = 0;
@@ -131,93 +182,122 @@
 			continue;
 		}
-		/* Now we now we have task with same id */
-		ucycles_diff[i] = new_data->taskinfos[i].ucycles - old_data->taskinfos[j].ucycles;
-		kcycles_diff[i] = new_data->taskinfos[i].kcycles - old_data->taskinfos[j].kcycles;
-
-		mem_total += new_data->taskinfos[i].virt_mem;
+		
+		ucycles_diff[i] =
+		    new_data->tasks[i].ucycles - old_data->tasks[j].ucycles;
+		kcycles_diff[i] =
+		    new_data->tasks[i].kcycles - old_data->tasks[j].kcycles;
+		
+		virtmem_total += new_data->tasks[i].virtmem;
 		ucycles_total += ucycles_diff[i];
 		kcycles_total += kcycles_diff[i];
 	}
-
-	/* And now compute percental change */
-	new_data->task_perc = malloc(new_data->task_count * sizeof(task_perc_t));
-	for (i = 0; i < new_data->task_count; ++i) {
-		FRACTION_TO_FLOAT(new_data->task_perc[i].mem, new_data->taskinfos[i].virt_mem * 100, mem_total);
-		FRACTION_TO_FLOAT(new_data->task_perc[i].ucycles, ucycles_diff[i] * 100, ucycles_total);
-		FRACTION_TO_FLOAT(new_data->task_perc[i].kcycles, kcycles_diff[i] * 100, kcycles_total);
-	}
-
-	/* Wait until coprocessor finishes its work */
-	write_barrier();
-
-	/* And free temporary structures */
+	
+	/* For each task: Compute percential change */
+	
+	for (i = 0; i < new_data->tasks_count; i++) {
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].virtmem,
+		    new_data->tasks[i].virtmem * 100, virtmem_total);
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
+		    ucycles_diff[i] * 100, ucycles_total);
+		FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles,
+		    kcycles_diff[i] * 100, kcycles_total);
+	}
+	
+	/* Cleanup */
+	
 	free(ucycles_diff);
 	free(kcycles_diff);
+	
+	return NULL;
 }
 
 static void free_data(data_t *target)
 {
-	free(target->taskinfos);
-	free(target->thread_infos);
-	free(target->cpus);
-	free(target->cpu_perc);
-	free(target->task_perc);
+	if (target->load != NULL)
+		free(target->load);
+	
+	if (target->cpus != NULL)
+		free(target->cpus);
+	
+	if (target->cpus_perc != NULL)
+		free(target->cpus_perc);
+	
+	if (target->tasks != NULL)
+		free(target->tasks);
+	
+	if (target->tasks_perc != NULL)
+		free(target->tasks_perc);
+	
+	if (target->threads != NULL)
+		free(target->threads);
+	
+	if (target->physmem != NULL)
+		free(target->physmem);
 }
-
-static inline void swap(data_t **first, data_t **second)
-{
-	data_t *temp;
-	temp = *first;
-	*first = *second;
-	*second = temp;
-}
-
-static data_t data[2];
 
 int main(int argc, char *argv[])
 {
-	data_t *data1 = &data[0];
-	data_t *data2 = &data[1];
+	data_t data;
+	data_t data_prev;
+	const char *ret = NULL;
+	
 	screen_init();
-
-	/* Read initial stats */
 	printf("Reading initial data...\n");
-	read_data(data1);
+	
+	if ((ret = read_data(&data_prev)) != NULL)
+		goto out;
+	
 	/* Compute some rubbish to have initialised values */
-	compute_percentages(data1, data1);
-
-	/* And paint screen until death... */
+	if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL)
+		goto out;
+	
+	/* And paint screen until death */
 	operation_type = OP_TASKS;
 	while (true) {
 		char c = tgetchar(UPDATE_INTERVAL);
 		if (c < 0) {
-			read_data(data2);
-			compute_percentages(data1, data2);
-			free_data(data1);
-			print_data(data2);
-			swap(&data1, &data2);
+			if ((ret = read_data(&data)) != NULL) {
+				free_data(&data);
+				goto out;
+			}
+			
+			if ((ret = compute_percentages(&data_prev, &data)) != NULL) {
+				free_data(&data);
+				goto out;
+			}
+			
+			print_data(&data);
+			free_data(&data_prev);
+			data_prev = data;
+			
 			continue;
 		}
+		
 		switch (c) {
 			case 'q':
-				clear_screen();
-				return 0;
+				goto out;
 			case 'i':
-				PRINT_WARNING("Showing IPC statistics", c);
+				print_warning("Showing IPC statistics");
 				operation_type = OP_IPC;
 				break;
 			case 't':
-				PRINT_WARNING("Showing task stats", c);
+				print_warning("Showing task statistics");
 				operation_type = OP_TASKS;
 				break;
 			default:
-				PRINT_WARNING("Unknown command: %c", c);
+				print_warning("Unknown command: %c", c);
 				break;
 		}
-
-	}
-
-	free_data(data1);
-	free_data(data2);
+	}
+	
+out:
+	screen_done();
+	free_data(&data_prev);
+	
+	if (ret != NULL) {
+		fprintf(stderr, "%s: %s\n", NAME, ret);
+		return 1;
+	}
+	
 	return 0;
 }
Index: uspace/app/top/top.h
===================================================================
--- uspace/app/top/top.h	(revision e535eeb8ca65f325690f9d79d60ea2f3c9e9da35)
+++ uspace/app/top/top.h	(revision 7d42cc98a6c2040a964dff9d22829f2f1f5a859a)
@@ -1,4 +1,5 @@
 /*
- * Copyright (c) 2008 Stanislav Kozina
+ * Copyright (c) 2010 Stanislav Kozina
+ * Copyright (c) 2010 Martin Decky
  * All rights reserved.
  *
@@ -35,6 +36,6 @@
 
 #include <task.h>
-#include <kernel/ps/cpuinfo.h>
-#include <kernel/ps/taskinfo.h>
+#include <stats.h>
+#include <time.h>
 
 #define FRACTION_TO_FLOAT(float, a, b) { \
@@ -43,6 +44,7 @@
 }
 
-#define OP_TASKS 1
-#define OP_IPC 2
+#define OP_TASKS  1
+#define OP_IPC    2
+
 extern int operation_type;
 
@@ -50,41 +52,42 @@
 	uint64_t upper;
 	uint64_t lower;
-} ps_float;
+} fixed_float;
 
 typedef struct {
-	ps_float idle;
-	ps_float busy;
-} cpu_perc_t;
+	fixed_float idle;
+	fixed_float busy;
+} perc_cpu_t;
 
 typedef struct {
-	ps_float ucycles;
-	ps_float kcycles;
-	ps_float mem;
-} task_perc_t;
+	fixed_float ucycles;
+	fixed_float kcycles;
+	fixed_float virtmem;
+} perc_task_t;
 
 typedef struct {
-	unsigned int hours;
-	unsigned int minutes;
-	unsigned int seconds;
-
-	unsigned int uptime_d;
-	unsigned int uptime_h;
-	unsigned int uptime_m;
-	unsigned int uptime_s;
-
-	unsigned long load[3];
-
-	size_t task_count;
-	task_info_t *taskinfos;
-	task_perc_t *task_perc;
-
-	size_t thread_count;
-	thread_info_t *thread_infos;
-
-	unsigned int cpu_count;
-	uspace_cpu_info_t *cpus;
-	cpu_perc_t *cpu_perc;
-
-	uspace_mem_info_t mem_info;
+	time_t hours;
+	time_t minutes;
+	time_t seconds;
+	
+	sysarg_t udays;
+	sysarg_t uhours;
+	sysarg_t uminutes;
+	sysarg_t useconds;
+	
+	size_t load_count;
+	load_t *load;
+	
+	size_t cpus_count;
+	stats_cpu_t *cpus;
+	perc_cpu_t *cpus_perc;
+	
+	size_t tasks_count;
+	stats_task_t *tasks;
+	perc_task_t *tasks_perc;
+	
+	size_t threads_count;
+	stats_thread_t *threads;
+	
+	stats_physmem_t *physmem;
 } data_t;
 
