Index: uspace/app/dummy_load/Makefile
===================================================================
--- uspace/app/dummy_load/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/dummy_load/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = dummy_load
+
+SOURCES = \
+	dummy_load.c \
+	input.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/dummy_load/dummy_load.c
===================================================================
--- uspace/app/dummy_load/dummy_load.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/dummy_load/dummy_load.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,166 @@
+/*
+ * 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 dummy_load
+ * @brief Dummy application to make some system load.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <task.h>
+#include <malloc.h>
+#include <ps.h>
+#include <str.h>
+#include <stdlib.h>
+#include "input.h"
+
+#define TASK_COUNT 50
+#define USPACE_CYCLES (1 << 26)
+#define SYSTEM_CYCLES (1 << 16)
+
+static void uspace_load()
+{
+	puts("u");
+	uint64_t volatile i;
+	for (i = 0; i < USPACE_CYCLES; ++i)
+		;
+}
+
+static int task_count;
+
+static void system_init()
+{
+	task_count = TASK_COUNT;
+	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
+	int 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);
+	}
+
+	free(tasks);
+}
+
+static void system_load()
+{
+	puts("s");
+	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
+	int result;
+
+	uint64_t i;
+	for (i = 0; i < SYSTEM_CYCLES; ++i) {
+		result = get_task_ids(tasks, sizeof(task_id_t) * task_count);
+	}
+
+	free(tasks);
+}
+
+static void usage()
+{
+	printf("Usage: dummy_load [-u|-s|-r]\n");
+}
+
+int main(int argc, char *argv[])
+{
+	--argc; ++argv;
+	system_init();
+
+	char mode = 'r';
+	if (argc > 1) {
+		printf("Bad argument count!\n");
+		usage();
+		exit(1);
+	}
+
+	if (argc > 0) {
+		if (str_cmp(*argv, "-r") == 0) {
+			printf("Doing random load\n");
+			mode = 'r';
+		} else if (str_cmp(*argv, "-u") == 0) {
+			printf("Doing uspace load\n");
+			mode = 'u';
+		} else if (str_cmp(*argv, "-s") == 0) {
+			printf("Doing system load\n");
+			mode = 's';
+		} else {
+			usage();
+			exit(1);
+		}
+	} else {
+		mode = 'r';
+		printf("Doing random load\n");
+	}
+
+	bool system = false;
+	while (true) {
+		char c = tgetchar(0);
+		switch (c) {
+			case 'r':
+				mode = 'r';
+				break;
+			case 'u':
+				mode = 'u';
+				break;
+			case 's':
+				mode = 's';
+				break;
+			case 'q':
+				exit(0);
+				break;
+		}
+		switch (mode) {
+			case 'r':
+				if (system) {
+					system_load();
+				} else {
+					uspace_load();
+				}
+				system = !system;
+				break;
+			case 'u':
+				uspace_load();
+				break;
+			case 's':
+				system_load();
+				break;
+		}
+		fflush(stdout);
+	}
+
+	puts("\n");
+	fflush(stdout);
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/dummy_load/input.c
===================================================================
--- uspace/app/dummy_load/input.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/dummy_load/input.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,200 @@
+/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
+/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup dummy_load
+ * @{
+ */
+/** @file
+ */
+
+/*
+ * Top input.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <str.h>
+
+#include "input.h"
+
+#include <async.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+#define USEC_COUNT 1000000
+
+/* return true iff the given timeval is positive */
+#define	TV_POS(tv) \
+	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
+
+/* subtract timeval `sub' from `res' */
+#define	TV_SUB(res, sub) \
+	(res)->tv_sec -= (sub)->tv_sec; \
+	(res)->tv_usec -= (sub)->tv_usec; \
+	if ((res)->tv_usec < 0) { \
+		(res)->tv_usec += 1000000; \
+		(res)->tv_sec--; \
+	}
+
+/* We will use a hack here - if lastchar is non-zero, it is
+ * the last character read. We will somehow simulate the select
+ * semantics.
+ */
+static aid_t getchar_inprog = 0;
+static char lastchar = '\0';
+
+/*
+ * Do a `read wait': select for reading from stdin, with timeout *tvp.
+ * On return, modify *tvp to reflect the amount of time spent waiting.
+ * It will be positive only if input appeared before the time ran out;
+ * otherwise it will be zero or perhaps negative.
+ *
+ * If tvp is nil, wait forever, but return if select is interrupted.
+ *
+ * Return 0 => no input, 1 => can read() from stdin
+ *
+ */
+int rwait(struct timeval *tvp)
+{
+	struct timeval starttv, endtv, *s;
+	static ipc_call_t charcall;
+	ipcarg_t rc;
+	
+	/*
+	 * Someday, select() will do this for us.
+	 * Just in case that day is now, and no one has
+	 * changed this, we use a temporary.
+	 */
+	if (tvp) {
+		(void) gettimeofday(&starttv, NULL);
+		endtv = *tvp;
+		s = &endtv;
+	} else
+		s = NULL;
+	
+	if (!lastchar) {
+again:
+		if (!getchar_inprog) {
+			getchar_inprog = async_send_0(fphone(stdin),
+			    CONSOLE_GET_EVENT, &charcall);
+		}
+		
+		if (!s)
+			async_wait_for(getchar_inprog, &rc);
+		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
+			tvp->tv_sec = 0;
+			tvp->tv_usec = 0;
+			return (0);
+		}
+		
+		getchar_inprog = 0;
+		if (rc) {
+			printf("End of file, bug?\n");
+			exit(1);
+		}
+		
+		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
+			goto again;
+		
+		lastchar = IPC_GET_ARG4(charcall);
+	}
+	
+	if (tvp) {
+		/* since there is input, we may not have timed out */
+		(void) gettimeofday(&endtv, NULL);
+		TV_SUB(&endtv, &starttv);
+		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
+	}
+	
+	return 1;
+}
+
+/*
+ * `sleep' for the current turn time (using select).
+ * Eat any input that might be available.
+ */
+void tsleep(unsigned int sec)
+{
+	struct timeval tv;
+	
+	tv.tv_sec = 0;
+	tv.tv_usec = sec * USEC_COUNT;
+	while (TV_POS(&tv))
+		if (rwait(&tv)) {
+			lastchar = '\0';
+		} else
+			break;
+}
+
+/*
+ * getchar with timeout.
+ */
+int tgetchar(unsigned int sec)
+{
+	static struct timeval timeleft;
+	char c;
+	
+	/*
+	 * Reset timeleft to USEC_COUNT whenever it is not positive.
+	 * In any case, wait to see if there is any input.  If so,
+	 * take it, and update timeleft so that the next call to
+	 * tgetchar() will not wait as long.  If there is no input,
+	 * make timeleft zero or negative, and return -1.
+	 *
+	 * Most of the hard work is done by rwait().
+	 */
+	if (!TV_POS(&timeleft)) {
+		timeleft.tv_sec = 0;
+		timeleft.tv_usec = sec * USEC_COUNT;
+	}
+	
+	if (!rwait(&timeleft))
+		return -1;
+	
+	c = lastchar;
+	lastchar = '\0';
+	return ((int) (unsigned char) c);
+}
+
+/** @}
+ */
Index: uspace/app/dummy_load/input.h
===================================================================
--- uspace/app/dummy_load/input.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/dummy_load/input.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,56 @@
+/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup dummy_load
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TOP_INPUT_
+#define TOP_INPUT_
+
+#include <sys/time.h>
+
+extern int rwait(struct timeval *);
+extern int tgetchar(unsigned int sec);
+extern void tsleep(unsigned int sec);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/ps/Makefile
===================================================================
--- uspace/app/ps/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/ps/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = ps
+
+SOURCES = \
+	ps.c \
+	func.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/ps/func.c
===================================================================
--- uspace/app/ps/func.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/ps/func.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * 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 ps
+ * @{
+ */
+
+/**
+ * @file
+ * @brief	Miscellaneous functions.
+ */
+
+#include <stdio.h>
+
+#include "func.h"
+
+void order(const uint64_t val, uint64_t *rv, char *suffix)
+{
+	if (val > 10000000000000000000ULL) {
+		*rv = val / 1000000000000000000ULL;
+		*suffix = 'Z';
+	} else if (val > 1000000000000000000ULL) {
+		*rv = val / 1000000000000000ULL;
+		*suffix = 'E';
+	} else if (val > 1000000000000000ULL) {
+		*rv = val / 1000000000000ULL;
+		*suffix = 'T';
+	} else if (val > 1000000000000ULL) {
+		*rv = val / 1000000000ULL;
+		*suffix = 'G';
+	} else if (val > 1000000000ULL) {
+		*rv = val / 1000000ULL;
+		*suffix = 'M';
+	} else if (val > 1000000ULL) {
+		*rv = val / 1000ULL;
+		*suffix = 'k';
+	} else {
+		*rv = val;
+		*suffix = ' ';
+	}
+}
+
+/** @}
+ */
Index: uspace/app/ps/func.h
===================================================================
--- uspace/app/ps/func.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/ps/func.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * 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 ps
+ * @{
+ */
+/** @file
+ */
+
+#ifndef FUNC_H_
+#define FUNC_H_
+
+extern void order(const uint64_t val, uint64_t *rv, char *suffix);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/ps/ps.c
===================================================================
--- uspace/app/ps/ps.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/ps/ps.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,208 @@
+/*
+ * 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 ps
+ * @brief Task lister.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <task.h>
+#include <thread.h>
+#include <ps.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <load.h>
+#include <sysinfo.h>
+
+#include "func.h"
+
+#define TASK_COUNT 10
+#define THREAD_COUNT 50
+
+#define ECHOLOAD1(x) ((x) >> 11)
+#define ECHOLOAD2(x) (((x) & 0x7ff) / 2)
+
+/** Thread states */
+static const char *thread_states[] = {
+	"Invalid",
+	"Running",
+	"Sleeping",
+	"Ready",
+	"Entering",
+	"Exiting",
+	"Lingering"
+}; 
+
+static void list_tasks(void)
+{
+	int task_count = TASK_COUNT;
+	task_id_t *tasks = malloc(task_count * sizeof(task_id_t));
+	int 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);
+	}
+
+	printf("      ID  Threads      Mem       uCycles       kCycles   Cycle fault Name\n");
+
+	int i;
+	for (i = 0; i < result; ++i) {
+		task_info_t taskinfo;
+		get_task_info(tasks[i], &taskinfo);
+		uint64_t mem, ucycles, kcycles;
+		char memsuffix, usuffix, ksuffix;
+		order(taskinfo.virt_mem, &mem, &memsuffix);
+		order(taskinfo.ucycles, &ucycles, &usuffix);
+		order(taskinfo.kcycles, &kcycles, &ksuffix);
+		printf("%8llu %8u %8llu%c %12llu%c %12llu%c %s\n", tasks[i],
+			taskinfo.thread_count, mem, memsuffix, ucycles, usuffix,
+			kcycles, ksuffix, taskinfo.name);
+	}
+
+	free(tasks);
+}
+
+static void list_threads(task_id_t taskid)
+{
+	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);
+	}
+
+	if (result == 0) {
+		printf("No task with given pid!\n");
+		exit(1);
+	}
+
+	size_t i;
+	printf("    ID    State  CPU   Prio    [k]uCycles    [k]kcycles   Cycle fault\n");
+	for (i = 0; i < result; ++i) {
+		if (threads[i].taskid != taskid) {
+			continue;
+		}
+		uint64_t ucycles, kcycles;
+		char usuffix, ksuffix;
+		order(threads[i].ucycles, &ucycles, &usuffix);
+		order(threads[i].kcycles, &kcycles, &ksuffix);
+		printf("%6llu %-8s %4u %6d %12llu%c %12llu%c\n", threads[i].tid,
+			thread_states[threads[i].state], threads[i].cpu,
+			threads[i].priority, ucycles, usuffix,
+			kcycles, ksuffix);
+	}
+
+	free(threads);
+}
+
+static void echo_load(void)
+{
+	unsigned long load[3];
+	get_load(load);
+	printf("load avarage: ");
+	print_load_fragment(load[0], 2);
+	puts(" ");
+	print_load_fragment(load[1], 2);
+	puts(" ");
+	print_load_fragment(load[2], 2);
+	puts("\n");
+}
+
+static void echo_cpus(void)
+{
+	size_t cpu_count = sysinfo_value("cpu.count");
+	printf("Found %u cpu's:\n", cpu_count);
+	uspace_cpu_info_t *cpus = malloc(cpu_count * sizeof(uspace_cpu_info_t));
+	get_cpu_info(cpus);
+	size_t i;
+	for (i = 0; i < cpu_count; ++i) {
+		printf("%2u (%4u Mhz): Busy ticks: %6llu, Idle ticks: %6llu\n", cpus[i].id,
+				(size_t)cpus[i].frequency_mhz, cpus[i].busy_ticks, cpus[i].idle_ticks);
+	}
+}
+
+static void usage()
+{
+	printf("Usage: ps [-t pid|-l|-c]\n");
+}
+
+int main(int argc, char *argv[])
+{
+	--argc; ++argv;
+
+	if (argc > 0)
+	{
+		if (str_cmp(*argv, "-t") == 0) {
+			--argc; ++argv;
+			if (argc != 1) {
+				printf("Bad argument count!\n");
+				usage();
+				exit(1);
+			}
+			task_id_t taskid = strtol(*argv, NULL, 10);
+			list_threads(taskid);
+		} else if (str_cmp(*argv, "-l") == 0) {
+			--argc; ++argv;
+			if (argc != 0) {
+				printf("Bad argument count!\n");
+				usage();
+				exit(1);
+			}
+			echo_load();
+		} else if (str_cmp(*argv, "-c") == 0) {
+			--argc; ++argv;
+			if (argc != 0) {
+				printf("Bad argument count!\n");
+				usage();
+				exit(1);
+			}
+			echo_cpus();
+		} else {
+			printf("Unknown argument %s!\n", *argv);
+			usage();
+			exit(1);
+		}
+	} else {
+		list_tasks();
+	}
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/top/Makefile
===================================================================
--- uspace/app/top/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = top
+
+SOURCES = \
+	top.c \
+	screen.c \
+	input.c \
+	func.c \
+	ps.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/top/func.c
===================================================================
--- uspace/app/top/func.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/func.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * 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
+ * @{
+ */
+
+/**
+ * @file
+ * @brief	Miscellaneous functions.
+ */
+
+#include <stdio.h>
+
+#include "func.h"
+
+void order(const uint64_t val, uint64_t *rv, char *suffix)
+{
+	if (val > 10000000000000000000ULL) {
+		*rv = val >> 60;
+		*suffix = 'Z';
+	} else if (val > 1000000000000000000ULL) {
+		*rv = val >> 50;
+		*suffix = 'E';
+	} else if (val > 1000000000000000ULL) {
+		*rv = val >> 40;
+		*suffix = 'T';
+	} else if (val > 1000000000000ULL) {
+		*rv = val >> 30;
+		*suffix = 'G';
+	} else if (val > 1000000000ULL) {
+		*rv = val >> 20;
+		*suffix = 'M';
+	} else if (val > 1000000ULL) {
+		*rv = val >> 10;
+		*suffix = 'k';
+	} else {
+		*rv = val;
+		*suffix = ' ';
+	}
+}
+
+/** @}
+ */
Index: uspace/app/top/func.h
===================================================================
--- uspace/app/top/func.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/func.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * 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 ps
+ * @{
+ */
+/** @file
+ */
+
+#ifndef FUNC_H_
+#define FUNC_H_
+
+extern void order(const uint64_t val, uint64_t *rv, char *suffix);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/top/input.c
===================================================================
--- uspace/app/top/input.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/input.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,200 @@
+/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
+/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup top
+ * @{
+ */
+/** @file
+ */
+
+/*
+ * Top input.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <str.h>
+
+#include "input.h"
+
+#include <async.h>
+#include <vfs/vfs.h>
+#include <io/console.h>
+#include <ipc/console.h>
+
+#define USEC_COUNT 1000000
+
+/* return true iff the given timeval is positive */
+#define	TV_POS(tv) \
+	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
+
+/* subtract timeval `sub' from `res' */
+#define	TV_SUB(res, sub) \
+	(res)->tv_sec -= (sub)->tv_sec; \
+	(res)->tv_usec -= (sub)->tv_usec; \
+	if ((res)->tv_usec < 0) { \
+		(res)->tv_usec += 1000000; \
+		(res)->tv_sec--; \
+	}
+
+/* We will use a hack here - if lastchar is non-zero, it is
+ * the last character read. We will somehow simulate the select
+ * semantics.
+ */
+static aid_t getchar_inprog = 0;
+static char lastchar = '\0';
+
+/*
+ * Do a `read wait': select for reading from stdin, with timeout *tvp.
+ * On return, modify *tvp to reflect the amount of time spent waiting.
+ * It will be positive only if input appeared before the time ran out;
+ * otherwise it will be zero or perhaps negative.
+ *
+ * If tvp is nil, wait forever, but return if select is interrupted.
+ *
+ * Return 0 => no input, 1 => can read() from stdin
+ *
+ */
+int rwait(struct timeval *tvp)
+{
+	struct timeval starttv, endtv, *s;
+	static ipc_call_t charcall;
+	ipcarg_t rc;
+	
+	/*
+	 * Someday, select() will do this for us.
+	 * Just in case that day is now, and no one has
+	 * changed this, we use a temporary.
+	 */
+	if (tvp) {
+		(void) gettimeofday(&starttv, NULL);
+		endtv = *tvp;
+		s = &endtv;
+	} else
+		s = NULL;
+	
+	if (!lastchar) {
+again:
+		if (!getchar_inprog) {
+			getchar_inprog = async_send_0(fphone(stdin),
+			    CONSOLE_GET_EVENT, &charcall);
+		}
+		
+		if (!s)
+			async_wait_for(getchar_inprog, &rc);
+		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
+			tvp->tv_sec = 0;
+			tvp->tv_usec = 0;
+			return (0);
+		}
+		
+		getchar_inprog = 0;
+		if (rc) {
+			printf("End of file, bug?\n");
+			exit(1);
+		}
+		
+		if (IPC_GET_ARG1(charcall) == KEY_RELEASE)
+			goto again;
+		
+		lastchar = IPC_GET_ARG4(charcall);
+	}
+	
+	if (tvp) {
+		/* since there is input, we may not have timed out */
+		(void) gettimeofday(&endtv, NULL);
+		TV_SUB(&endtv, &starttv);
+		TV_SUB(tvp, &endtv);  /* adjust *tvp by elapsed time */
+	}
+	
+	return 1;
+}
+
+/*
+ * `sleep' for the current turn time (using select).
+ * Eat any input that might be available.
+ */
+void tsleep(unsigned int sec)
+{
+	struct timeval tv;
+	
+	tv.tv_sec = 0;
+	tv.tv_usec = sec * USEC_COUNT;
+	while (TV_POS(&tv))
+		if (rwait(&tv)) {
+			lastchar = '\0';
+		} else
+			break;
+}
+
+/*
+ * getchar with timeout.
+ */
+int tgetchar(unsigned int sec)
+{
+	static struct timeval timeleft;
+	char c;
+	
+	/*
+	 * Reset timeleft to USEC_COUNT whenever it is not positive.
+	 * In any case, wait to see if there is any input.  If so,
+	 * take it, and update timeleft so that the next call to
+	 * tgetchar() will not wait as long.  If there is no input,
+	 * make timeleft zero or negative, and return -1.
+	 *
+	 * Most of the hard work is done by rwait().
+	 */
+	if (!TV_POS(&timeleft)) {
+		timeleft.tv_sec = 0;
+		timeleft.tv_usec = sec * USEC_COUNT;
+	}
+	
+	if (!rwait(&timeleft))
+		return -1;
+	
+	c = lastchar;
+	lastchar = '\0';
+	return ((int) (unsigned char) c);
+}
+
+/** @}
+ */
Index: uspace/app/top/input.h
===================================================================
--- uspace/app/top/input.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/input.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,56 @@
+/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup top
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TOP_INPUT_
+#define TOP_INPUT_
+
+#include <sys/time.h>
+
+extern int rwait(struct timeval *);
+extern int tgetchar(unsigned int sec);
+extern void tsleep(unsigned int sec);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/top/ps.c
===================================================================
--- uspace/app/top/ps.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/ps.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,111 @@
+/*
+ * 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 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/ps.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,49 @@
+/*
+ * 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 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/screen.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,282 @@
+/*
+ * 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 Top utility.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <io/console.h>
+#include <vfs/vfs.h>
+#include <load.h>
+#include <kernel/ps/taskinfo.h>
+#include <ps.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)
+{
+	fflush(stdout);
+	console_set_rgb_color(fphone(stdout), 0, WHITE);
+}
+
+void screen_init(void)
+{
+	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);
+}
+
+static inline void print_time(data_t *data)
+{
+	printf("%02d:%02d:%02d ", 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);
+}
+
+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)
+{
+	size_t sleeping = 0;
+	size_t running = 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;
+		}
+	}
+	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(", 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);
+}
+
+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);
+	}
+}
+
+static inline void print_task_head(void)
+{
+	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(" ");
+	fflush(stdout);
+	console_set_rgb_color(fphone(stdout), BLACK, WHITE);
+}
+
+static inline void print_ipc_head(void)
+{
+	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(" ");
+	fflush(stdout);
+	console_set_rgb_color(fphone(stdout), BLACK, WHITE);
+}
+
+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);
+	}
+}
+
+void print_data(data_t *data)
+{
+	clear_screen();
+	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;
+	if (operation_type == OP_IPC) {
+		print_ipc_head();
+		puts("\n");
+		print_ipc(data, up_rows);
+	} else {
+		print_task_head();
+		puts("\n");
+		print_tasks(data, up_rows);
+	}
+	fflush(stdout);
+}
+
+/** @}
+ */
Index: uspace/app/top/screen.h
===================================================================
--- uspace/app/top/screen.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/screen.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,58 @@
+/*
+ * 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_SCREEN_H_
+#define TOP_SCREEN_H_
+
+#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)
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/top.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,226 @@
+/*
+ * 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 Top utility.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#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 "screen.h"
+#include "input.h"
+#include "top.h"
+#include "ps.h"
+
+#define UPDATE_INTERVAL 1
+
+#define DAY 86400
+#define HOUR 3600
+#define MINUTE 60
+
+int operation_type;
+
+static void read_data(data_t *target)
+{
+	/* Read current time */
+	struct timeval time;
+	if (gettimeofday(&time, NULL) != 0) {
+		printf("Cannot get time of day!\n");
+		exit(1);
+	}
+	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);
+}
+
+/** 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)
+{
+	/* 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;
+		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);
+	}
+
+	/* 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) {
+			/* This is newly borned task, ignore it */
+			ucycles_diff[i] = 0;
+			kcycles_diff[i] = 0;
+			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_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 */
+	free(ucycles_diff);
+	free(kcycles_diff);
+}
+
+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);
+}
+
+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];
+	screen_init();
+
+	/* Read initial stats */
+	printf("Reading initial data...\n");
+	read_data(data1);
+	/* Compute some rubbish to have initialised values */
+	compute_percentages(data1, data1);
+
+	/* 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);
+			continue;
+		}
+		switch (c) {
+			case 'q':
+				clear_screen();
+				return 0;
+			case 'i':
+				PRINT_WARNING("Showing IPC statistics", c);
+				operation_type = OP_IPC;
+				break;
+			case 't':
+				PRINT_WARNING("Showing task stats", c);
+				operation_type = OP_TASKS;
+				break;
+			default:
+				PRINT_WARNING("Unknown command: %c", c);
+				break;
+		}
+
+	}
+
+	free_data(data1);
+	free_data(data2);
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/top/top.h
===================================================================
--- uspace/app/top/top.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/top/top.h	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,95 @@
+/*
+ * 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_TOP_H_
+#define TOP_TOP_H_
+
+#include <task.h>
+#include <kernel/ps/cpuinfo.h>
+#include <kernel/ps/taskinfo.h>
+
+#define FRACTION_TO_FLOAT(float, a, b) { \
+	(float).upper = (a); \
+	(float).lower = (b); \
+}
+
+#define OP_TASKS 1
+#define OP_IPC 2
+extern int operation_type;
+
+typedef struct {
+	uint64_t upper;
+	uint64_t lower;
+} ps_float;
+
+typedef struct {
+	ps_float idle;
+	ps_float busy;
+} cpu_perc_t;
+
+typedef struct {
+	ps_float ucycles;
+	ps_float kcycles;
+	ps_float mem;
+} task_perc_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;
+} data_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/uptime/Makefile
===================================================================
--- uspace/app/uptime/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/uptime/Makefile	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = uptime
+
+SOURCES = \
+	uptime.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/uptime/uptime.c
===================================================================
--- uspace/app/uptime/uptime.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
+++ uspace/app/uptime/uptime.c	(revision 88dea9d01a9bc5e8482c1ceafa6e6531ac50cb4f)
@@ -0,0 +1,77 @@
+/*
+ * 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 uptime
+ * @brief Echo system uptime.
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <uptime.h>
+#include <sys/time.h>
+#include <load.h>
+
+#define DAY 86400
+#define HOUR 3600
+#define MINUTE 60
+
+int main(int argc, char *argv[])
+{
+	struct timeval time;
+	uint64_t sec;
+	if (gettimeofday(&time, NULL) != 0) {
+		printf("Cannot get time of day!\n");
+		return 1;
+	}
+	sec = time.tv_sec;
+	printf("%02llu:%02llu:%02llu", (sec % DAY) / HOUR,
+			(sec % HOUR) / MINUTE, sec % MINUTE);
+
+	uint64_t uptime;
+	get_uptime(&uptime);
+	printf(", up %4llu days, %02llu:%02llu:%02llu",
+		uptime / DAY, (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE);
+
+	unsigned long load[3];
+	get_load(load);
+	puts(", load avarage: ");
+	print_load_fragment(load[0], 2);
+	puts(" ");
+	print_load_fragment(load[1], 2);
+	puts(" ");
+	print_load_fragment(load[2], 2);
+
+	puts("\n");
+	return 0;
+}
+
+/** @}
+ */
