Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/async/client.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -110,5 +110,5 @@
 #include <assert.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <time.h>
 #include <barrier.h>
 #include <stdbool.h>
@@ -342,5 +342,5 @@
  *
  */
-errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, suseconds_t timeout)
+errno_t async_wait_timeout(aid_t amsgid, errno_t *retval, usec_t timeout)
 {
 	if (amsgid == 0) {
@@ -359,7 +359,7 @@
 		timeout = 0;
 
-	struct timeval expires;
+	struct timespec expires;
 	getuptime(&expires);
-	tv_add_diff(&expires, timeout);
+	ts_add_diff(&expires, USEC2NSEC(timeout));
 
 	errno_t rc = fibril_wait_timeout(&msg->received, &expires);
Index: uspace/lib/c/generic/async/ports.c
===================================================================
--- uspace/lib/c/generic/async/ports.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/async/ports.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -41,5 +41,5 @@
 #include <assert.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <time.h>
 #include <barrier.h>
 #include <stdbool.h>
Index: uspace/lib/c/generic/async/server.c
===================================================================
--- uspace/lib/c/generic/async/server.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/async/server.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -110,5 +110,5 @@
 #include <assert.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <time.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -916,15 +916,15 @@
  *
  */
-bool async_get_call_timeout(ipc_call_t *call, suseconds_t usecs)
+bool async_get_call_timeout(ipc_call_t *call, usec_t usecs)
 {
 	assert(call);
 	assert(fibril_connection);
 
-	struct timeval tv;
-	struct timeval *expires = NULL;
+	struct timespec ts;
+	struct timespec *expires = NULL;
 	if (usecs) {
-		getuptime(&tv);
-		tv_add_diff(&tv, usecs);
-		expires = &tv;
+		getuptime(&ts);
+		ts_add_diff(&ts, USEC2NSEC(usecs));
+		expires = &ts;
 	}
 
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/io/console.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -223,8 +223,8 @@
 
 bool console_get_event_timeout(console_ctrl_t *ctrl, cons_event_t *event,
-    suseconds_t *timeout)
-{
-	struct timeval t0;
-	gettimeofday(&t0, NULL);
+    usec_t *timeout)
+{
+	struct timespec t0;
+	getuptime(&t0);
 
 	if (ctrl->input_aid == 0) {
@@ -257,7 +257,7 @@
 
 	/* Update timeout */
-	struct timeval t1;
-	gettimeofday(&t1, NULL);
-	*timeout -= tv_sub_diff(&t1, &t0);
+	struct timespec t1;
+	getuptime(&t1);
+	*timeout -= NSEC2USEC(ts_sub_diff(&t1, &t0));
 
 	return true;
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/private/async.h	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -40,5 +40,5 @@
 #include <fibril.h>
 #include <fibril_synch.h>
-#include <sys/time.h>
+#include <time.h>
 #include <stdbool.h>
 
Index: uspace/lib/c/generic/private/fibril.h
===================================================================
--- uspace/lib/c/generic/private/fibril.h	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/private/fibril.h	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -81,8 +81,8 @@
 
 extern void fibril_wait_for(fibril_event_t *);
-extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timeval *);
+extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timespec *);
 extern void fibril_notify(fibril_event_t *);
 
-extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timeval *);
+extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timespec *);
 extern void fibril_ipc_poke(void);
 
Index: uspace/lib/c/generic/private/futex.h
===================================================================
--- uspace/lib/c/generic/private/futex.h	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/private/futex.h	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -102,5 +102,6 @@
  *
  */
-static inline errno_t futex_down_composable(futex_t *futex, const struct timeval *expires)
+static inline errno_t futex_down_composable(futex_t *futex,
+    const struct timespec *expires)
 {
 	// TODO: Add tests for this.
@@ -109,5 +110,5 @@
 		return EOK;
 
-	suseconds_t timeout;
+	usec_t timeout;
 
 	if (!expires) {
@@ -119,8 +120,8 @@
 			timeout = 1;
 		} else {
-			struct timeval tv;
+			struct timespec tv;
 			getuptime(&tv);
-			timeout = tv_gteq(&tv, expires) ? 1 :
-			    tv_sub_diff(expires, &tv);
+			timeout = ts_gteq(&tv, expires) ? 1 :
+			    NSEC2USEC(ts_sub_diff(expires, &tv));
 		}
 
@@ -148,7 +149,8 @@
 }
 
-static inline errno_t futex_down_timeout(futex_t *futex, const struct timeval *expires)
-{
-	if (expires && expires->tv_sec == 0 && expires->tv_usec == 0) {
+static inline errno_t futex_down_timeout(futex_t *futex,
+    const struct timespec *expires)
+{
+	if (expires && expires->tv_sec == 0 && expires->tv_nsec == 0) {
 		/* Nonblocking down. */
 
@@ -209,5 +211,5 @@
 	 * trydown.
 	 */
-	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+	struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 };
 	return futex_down_timeout(futex, &tv) == EOK;
 }
Index: uspace/lib/c/generic/private/thread.h
===================================================================
--- uspace/lib/c/generic/private/thread.h	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/private/thread.h	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -49,6 +49,6 @@
 extern void thread_detach(thread_id_t);
 extern thread_id_t thread_get_id(void);
-extern int thread_usleep(useconds_t);
-extern unsigned int thread_sleep(unsigned int);
+extern void thread_usleep(usec_t);
+extern void thread_sleep(sec_t);
 
 #endif
Index: uspace/lib/c/generic/rndgen.c
===================================================================
--- uspace/lib/c/generic/rndgen.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/rndgen.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -52,5 +52,5 @@
 {
 	rndgen_t *rndgen;
-	struct timeval tv;
+	struct timespec ts;
 
 	rndgen = calloc(1, sizeof(rndgen_t));
@@ -59,6 +59,6 @@
 
 	/* XXX This is a rather poor way of generating random numbers */
-	gettimeofday(&tv, NULL);
-	rndgen->seed = tv.tv_sec ^ tv.tv_usec;
+	getuptime(&ts);
+	rndgen->seed = ts.tv_sec ^ ts.tv_nsec;
 
 	*rrndgen = rndgen;
Index: uspace/lib/c/generic/stdlib.c
===================================================================
--- uspace/lib/c/generic/stdlib.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/stdlib.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -37,4 +37,5 @@
 #include <fibril_synch.h>
 #include <stdlib.h>
+#include <errno.h>
 #include "private/libc.h"
 #include "private/scanf.h"
Index: uspace/lib/c/generic/thread/fibril.c
===================================================================
--- uspace/lib/c/generic/thread/fibril.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/thread/fibril.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -60,5 +60,5 @@
 typedef struct {
 	link_t link;
-	struct timeval expires;
+	struct timespec expires;
 	fibril_event_t *event;
 } _timeout_t;
@@ -142,5 +142,5 @@
 }
 
-static inline errno_t _ready_down(const struct timeval *expires)
+static inline errno_t _ready_down(const struct timespec *expires)
 {
 	if (multithreaded)
@@ -253,5 +253,5 @@
 }
 
-static errno_t _ipc_wait(ipc_call_t *call, const struct timeval *expires)
+static errno_t _ipc_wait(ipc_call_t *call, const struct timespec *expires)
 {
 	if (!expires)
@@ -261,11 +261,12 @@
 		return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);
 
-	struct timeval now;
+	struct timespec now;
 	getuptime(&now);
 
-	if (tv_gteq(&now, expires))
+	if (ts_gteq(&now, expires))
 		return ipc_wait(call, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);
 
-	return ipc_wait(call, tv_sub_diff(expires, &now), SYNCH_FLAGS_NONE);
+	return ipc_wait(call, NSEC2USEC(ts_sub_diff(expires, &now)),
+	    SYNCH_FLAGS_NONE);
 }
 
@@ -275,5 +276,5 @@
  * wait after new ready fibrils are added.
  */
-static fibril_t *_ready_list_pop(const struct timeval *expires, bool locked)
+static fibril_t *_ready_list_pop(const struct timespec *expires, bool locked)
 {
 	if (locked) {
@@ -370,5 +371,5 @@
 static fibril_t *_ready_list_pop_nonblocking(bool locked)
 {
-	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+	struct timespec tv = { .tv_sec = 0, .tv_nsec = 0 };
 	return _ready_list_pop(&tv, locked);
 }
@@ -393,5 +394,5 @@
 
 /* Blocks the current fibril until an IPC call arrives. */
-static errno_t _wait_ipc(ipc_call_t *call, const struct timeval *expires)
+static errno_t _wait_ipc(ipc_call_t *call, const struct timespec *expires)
 {
 	futex_assert_is_not_locked(&fibril_futex);
@@ -430,8 +431,8 @@
 
 /** Fire all timeouts that expired. */
-static struct timeval *_handle_expired_timeouts(struct timeval *next_timeout)
-{
-	struct timeval tv;
-	getuptime(&tv);
+static struct timespec *_handle_expired_timeouts(struct timespec *next_timeout)
+{
+	struct timespec ts;
+	getuptime(&ts);
 
 	futex_lock(&fibril_futex);
@@ -441,5 +442,5 @@
 		_timeout_t *to = list_get_instance(cur, _timeout_t, link);
 
-		if (tv_gt(&to->expires, &tv)) {
+		if (ts_gt(&to->expires, &ts)) {
 			*next_timeout = to->expires;
 			futex_unlock(&fibril_futex);
@@ -535,7 +536,7 @@
 	(void) arg;
 
-	struct timeval next_timeout;
+	struct timespec next_timeout;
 	while (true) {
-		struct timeval *to = _handle_expired_timeouts(&next_timeout);
+		struct timespec *to = _handle_expired_timeouts(&next_timeout);
 		fibril_t *f = _ready_list_pop(to, false);
 		if (f) {
@@ -615,5 +616,5 @@
 		_timeout_t *cur = list_get_instance(tmp, _timeout_t, link);
 
-		if (tv_gteq(&cur->expires, &timeout->expires))
+		if (ts_gteq(&cur->expires, &timeout->expires))
 			break;
 
@@ -634,5 +635,6 @@
  * @return ETIMEOUT if timed out. EOK otherwise.
  */
-errno_t fibril_wait_timeout(fibril_event_t *event, const struct timeval *expires)
+errno_t fibril_wait_timeout(fibril_event_t *event,
+    const struct timespec *expires)
 {
 	assert(fibril_self()->rmutex_locks == 0);
@@ -889,9 +891,9 @@
 }
 
-void fibril_usleep(suseconds_t timeout)
-{
-	struct timeval expires;
+void fibril_usleep(usec_t timeout)
+{
+	struct timespec expires;
 	getuptime(&expires);
-	tv_add_diff(&expires, timeout);
+	ts_add_diff(&expires, USEC2NSEC(timeout));
 
 	fibril_event_t event = FIBRIL_EVENT_INIT;
@@ -899,7 +901,7 @@
 }
 
-void fibril_sleep(unsigned int sec)
-{
-	struct timeval expires;
+void fibril_sleep(sec_t sec)
+{
+	struct timespec expires;
 	getuptime(&expires);
 	expires.tv_sec += sec;
@@ -916,5 +918,5 @@
 }
 
-errno_t fibril_ipc_wait(ipc_call_t *call, const struct timeval *expires)
+errno_t fibril_ipc_wait(ipc_call_t *call, const struct timespec *expires)
 {
 	return _wait_ipc(call, expires);
Index: uspace/lib/c/generic/thread/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/thread/fibril_synch.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/thread/fibril_synch.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -37,5 +37,5 @@
 #include <async.h>
 #include <adt/list.h>
-#include <sys/time.h>
+#include <time.h>
 #include <errno.h>
 #include <assert.h>
@@ -390,5 +390,5 @@
 errno_t
 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm,
-    suseconds_t timeout)
+    usec_t timeout)
 {
 	assert(fibril_mutex_is_locked(fm));
@@ -400,10 +400,10 @@
 	wdata.mutex = fm;
 
-	struct timeval tv;
-	struct timeval *expires = NULL;
+	struct timespec ts;
+	struct timespec *expires = NULL;
 	if (timeout) {
-		getuptime(&tv);
-		tv_add_diff(&tv, timeout);
-		expires = &tv;
+		getuptime(&ts);
+		ts_add_diff(&ts, USEC2NSEC(timeout));
+		expires = &ts;
 	}
 
@@ -557,5 +557,5 @@
  * @param arg		Argument for @a fun
  */
-void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay,
+void fibril_timer_set(fibril_timer_t *timer, usec_t delay,
     fibril_timer_fun_t fun, void *arg)
 {
@@ -575,5 +575,5 @@
  * @param arg		Argument for @a fun
  */
-void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay,
+void fibril_timer_set_locked(fibril_timer_t *timer, usec_t delay,
     fibril_timer_fun_t fun, void *arg)
 {
@@ -728,5 +728,5 @@
 }
 
-errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, suseconds_t timeout)
+errno_t fibril_semaphore_down_timeout(fibril_semaphore_t *sem, usec_t timeout)
 {
 	if (timeout < 0)
@@ -751,10 +751,10 @@
 	futex_unlock(&fibril_synch_futex);
 
-	struct timeval tv;
-	struct timeval *expires = NULL;
+	struct timespec ts;
+	struct timespec *expires = NULL;
 	if (timeout) {
-		getuptime(&tv);
-		tv_add_diff(&tv, timeout);
-		expires = &tv;
+		getuptime(&ts);
+		ts_add_diff(&ts, USEC2NSEC(timeout));
+		expires = &ts;
 	}
 
Index: uspace/lib/c/generic/thread/mpsc.c
===================================================================
--- uspace/lib/c/generic/thread/mpsc.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/thread/mpsc.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -146,5 +146,5 @@
  * there is no message left in the queue.
  */
-errno_t mpsc_receive(mpsc_t *q, void *b, const struct timeval *expires)
+errno_t mpsc_receive(mpsc_t *q, void *b, const struct timespec *expires)
 {
 	mpsc_node_t *n;
Index: uspace/lib/c/generic/thread/thread.c
===================================================================
--- uspace/lib/c/generic/thread/thread.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/thread/thread.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -176,8 +176,7 @@
  *
  */
-int thread_usleep(useconds_t usec)
+void thread_usleep(usec_t usec)
 {
 	(void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
-	return 0;
 }
 
@@ -185,19 +184,15 @@
  *
  */
-unsigned int thread_sleep(unsigned int sec)
+void thread_sleep(sec_t sec)
 {
 	/*
-	 * Sleep in 1000 second steps to support
-	 * full argument range
+	 * Sleep in 1000 second steps to support full argument range
 	 */
-
 	while (sec > 0) {
 		unsigned int period = (sec > 1000) ? 1000 : sec;
 
-		thread_usleep(period * 1000000);
+		thread_usleep(SEC2USEC(period));
 		sec -= period;
 	}
-
-	return 0;
 }
 
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/time.c	(revision bd41ac52cf7d20e9e568c519bf2cb5ac7104b86a)
@@ -35,5 +35,4 @@
  */
 
-#include <sys/time.h>
 #include <time.h>
 #include <stdbool.h>
@@ -51,4 +50,5 @@
 #include <loc.h>
 #include <device/clock_dev.h>
+#include <stats.h>
 
 #define ASCTIME_BUF_LEN  26
@@ -57,5 +57,5 @@
 #define MINS_PER_HOUR  60
 #define SECS_PER_MIN   60
-#define USECS_PER_SEC  1000000
+#define NSECS_PER_SEC  1000000000ll
 #define MINS_PER_DAY   (MINS_PER_HOUR * HOURS_PER_DAY)
 #define SECS_PER_HOUR  (SECS_PER_MIN * MINS_PER_HOUR)
@@ -71,4 +71,36 @@
 static async_sess_t *clock_conn = NULL;
 
+/**
+ * Get CPU time used since the process invocation.
+ *
+ * @return Consumed microseconds by this process or -1 if not available.
+ */
+clock_t clock(void)
+{
+	static_assert(CLOCKS_PER_SEC == 1000000);
+
+	size_t count;
+	stats_cpu_t *cpu_stats = stats_get_cpus(&count);
+	if (!cpu_stats)
+		return (clock_t) -1;
+	if (!cpu_stats->frequency_mhz) {
+		free(cpu_stats);
+		return (clock_t) -1;
+	}
+
+	clock_t total_usecs = -1;
+	if (cpu_stats) {
+		stats_task_t *task_stats = stats_get_task(task_get_id());
+		if (task_stats) {
+			total_usecs = (clock_t) (task_stats->kcycles +
+			    task_stats->ucycles) / cpu_stats->frequency_mhz;
+			free(task_stats);
+		}
+		free(cpu_stats);
+	}
+
+	return total_usecs;
+}
+
 /** Check whether the year is a leap year.
  *
@@ -252,16 +284,16 @@
  *
  * @param tm Broken-down time to normalize.
- * @param tv Timeval to add.
+ * @param ts Timespec to add.
  *
  * @return 0 on success, -1 on overflow
  *
  */
-static int normalize_tm_tv(struct tm *tm, const struct timeval *tv)
+static int normalize_tm_ts(struct tm *tm, const struct timespec *ts)
 {
 	// TODO: DST correction
 
 	/* Set initial values. */
-	time_t usec = tm->tm_usec + tv->tv_usec;
-	time_t sec = tm->tm_sec + tv->tv_sec;
+	time_t nsec = tm->tm_nsec + ts->tv_nsec;
+	time_t sec = tm->tm_sec + ts->tv_sec;
 	time_t min = tm->tm_min;
 	time_t hour = tm->tm_hour;
@@ -271,6 +303,6 @@
 
 	/* Adjust time. */
-	sec += floor_div(usec, USECS_PER_SEC);
-	usec = floor_mod(usec, USECS_PER_SEC);
+	sec += floor_div(nsec, NSECS_PER_SEC);
+	nsec = floor_mod(nsec, NSECS_PER_SEC);
 	min += floor_div(sec, SECS_PER_MIN);
 	sec = floor_mod(sec, SECS_PER_MIN);
@@ -321,5 +353,5 @@
 
 	/* And put the values back to the struct. */
-	tm->tm_usec = (int) usec;
+	tm->tm_nsec = (int) nsec;
 	tm->tm_sec = (int) sec;
 	tm->tm_min = (int) min;
@@ -340,10 +372,10 @@
 static int normalize_tm_time(struct tm *tm, time_t time)
 {
-	struct timeval tv = {
+	struct timespec ts = {
 		.tv_sec = time,
-		.tv_usec = 0
+		.tv_nsec = 0
 	};
 
-	return normalize_tm_tv(tm, &tv);
+	return normalize_tm_ts(tm, &ts);
 }
 
@@ -456,84 +488,83 @@
 }
 
-static void tv_normalize(struct timeval *tv)
-{
-	while (tv->tv_usec > USECS_PER_SEC) {
-		tv->tv_sec++;
-		tv->tv_usec -= USECS_PER_SEC;
-	}
-	while (tv->tv_usec < 0) {
-		tv->tv_sec--;
-		tv->tv_usec += USECS_PER_SEC;
-	}
-}
-
-/** Add microseconds to given timeval.
- *
- * @param tv    Destination timeval.
- * @param usecs Number of microseconds to add.
- *
- */
-void tv_add_diff(struct timeval *tv, suseconds_t usecs)
-{
-	tv->tv_sec += usecs / USECS_PER_SEC;
-	tv->tv_usec += usecs % USECS_PER_SEC;
-	tv_normalize(tv);
-}
-
-/** Add two timevals.
- *
- * @param tv1 First timeval.
- * @param tv2 Second timeval.
- */
-void tv_add(struct timeval *tv1, const struct timeval *tv2)
-{
-	tv1->tv_sec += tv2->tv_sec;
-	tv1->tv_usec += tv2->tv_usec;
-	tv_normalize(tv1);
-}
-
-/** Subtract two timevals.
- *
- * @param tv1 First timeval.
- * @param tv2 Second timeval.
- *
- * @return Difference between tv1 and tv2 (tv1 - tv2) in
- *         microseconds.
- *
- */
-suseconds_t tv_sub_diff(const struct timeval *tv1, const struct timeval *tv2)
-{
-	return (tv1->tv_usec - tv2->tv_usec) +
-	    ((tv1->tv_sec - tv2->tv_sec) * USECS_PER_SEC);
-}
-
-/** Subtract two timevals.
- *
- * @param tv1 First timeval.
- * @param tv2 Second timeval.
- *
- */
-void tv_sub(struct timeval *tv1, const struct timeval *tv2)
-{
-	tv1->tv_sec -= tv2->tv_sec;
-	tv1->tv_usec -= tv2->tv_usec;
-	tv_normalize(tv1);
-}
-
-/** Decide if one timeval is greater than the other.
- *
- * @param t1 First timeval.
- * @param t2 Second timeval.
- *
- * @return True if tv1 is greater than tv2.
- * @return False otherwise.
- *
- */
-int tv_gt(const struct timeval *tv1, const struct timeval *tv2)
-{
-	if (tv1->tv_sec > tv2->tv_sec)
+static void ts_normalize(struct timespec *ts)
+{
+	while (ts->tv_nsec >= NSECS_PER_SEC) {
+		ts->tv_sec++;
+		ts->tv_nsec -= NSECS_PER_SEC;
+	}
+	while (ts->tv_nsec < 0) {
+		ts->tv_sec--;
+		ts->tv_nsec += NSECS_PER_SEC;
+	}
+}
+
+/** Add nanoseconds to given timespec.
+ *
+ * @param ts     Destination timespec.
+ * @param nsecs  Number of nanoseconds to add.
+ *
+ */
+void ts_add_diff(struct timespec *ts, nsec_t nsecs)
+{
+	ts->tv_sec += nsecs / NSECS_PER_SEC;
+	ts->tv_nsec += nsecs % NSECS_PER_SEC;
+	ts_normalize(ts);
+}
+
+/** Add two timespecs.
+ *
+ * @param ts1  First timespec.
+ * @param ts2  Second timespec.
+ */
+void ts_add(struct timespec *ts1, const struct timespec *ts2)
+{
+	ts1->tv_sec += ts2->tv_sec;
+	ts1->tv_nsec += ts2->tv_nsec;
+	ts_normalize(ts1);
+}
+
+/** Subtract two timespecs.
+ *
+ * @param ts1  First timespec.
+ * @param ts2  Second timespec.
+ *
+ * @return  Difference between ts1 and ts2 (ts1 - ts2) in nanoseconds.
+ *
+ */
+nsec_t ts_sub_diff(const struct timespec *ts1, const struct timespec *ts2)
+{
+	return (nsec_t) (ts1->tv_nsec - ts2->tv_nsec) +
+	    SEC2NSEC((ts1->tv_sec - ts2->tv_sec));
+}
+
+/** Subtract two timespecs.
+ *
+ * @param ts1  First timespec.
+ * @param ts2  Second timespec.
+ *
+ */
+void ts_sub(struct timespec *ts1, const struct timespec *ts2)
+{
+	ts1->tv_sec -= ts2->tv_sec;
+	ts1->tv_nsec -= ts2->tv_nsec;
+	ts_normalize(ts1);
+}
+
+/** Decide if one timespec is greater than the other.
+ *
+ * @param ts1  First timespec.
+ * @param ts2  Second timespec.
+ *
+ * @return  True if ts1 is greater than ts2.
+ * @return  False otherwise.
+ *
+ */
+bool ts_gt(const struct timespec *ts1, const struct timespec *ts2)
+{
+	if (ts1->tv_sec > ts2->tv_sec)
 		return true;
 
-	if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
+	if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec > ts2->tv_nsec))
 		return true;
 
@@ -541,19 +572,19 @@
 }
 
-/** Decide if one timeval is greater than or equal to the other.
- *
- * @param tv1 First timeval.
- * @param tv2 Second timeval.
- *
- * @return True if tv1 is greater than or equal to tv2.
- * @return False otherwise.
- *
- */
-int tv_gteq(const struct timeval *tv1, const struct timeval *tv2)
-{
-	if (tv1->tv_sec > tv2->tv_sec)
+/** Decide if one timespec is greater than or equal to the other.
+ *
+ * @param ts1  First timespec.
+ * @param ts2  Second timespec.
+ *
+ * @return  True if ts1 is greater than or equal to ts2.
+ * @return  False otherwise.
+ *
+ */
+bool ts_gteq(const struct timespec *ts1, const struct timespec *ts2)
+{
+	if (ts1->tv_sec > ts2->tv_sec)
 		return true;
 
-	if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
+	if ((ts1->tv_sec == ts2->tv_sec) && (ts1->tv_nsec >= ts2->tv_nsec))
 		return true;
 
@@ -561,25 +592,12 @@
 }
 
-/** Get time of day.
- *
- * The time variables are memory mapped (read-only) from kernel which
- * updates them periodically.
- *
- * As it is impossible to read 2 values atomically, we use a trick:
- * First we read the seconds, then we read the microseconds, then we
- * read the seconds again. If a second elapsed in the meantime, set
- * the microseconds to zero.
- *
- * This assures that the values returned by two subsequent calls
- * to gettimeofday() are monotonous.
- *
- */
-void gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-	if (tz) {
-		tz->tz_minuteswest = 0;
-		tz->tz_dsttime = DST_NONE;
-	}
-
+/** Get real time from a RTC service.
+ *
+ * @param[out] ts  Timespec to hold time read from the RTC service (if
+ *                 available). If no such service exists, the returned time
+ *                 corresponds to system uptime.
+ */
+void getrealtime(struct timespec *ts)
+{
 	if (clock_conn == NULL) {
 		category_id_t cat_id;
@@ -620,14 +638,30 @@
 		goto fallback;
 
-	tv->tv_usec = time.tm_usec;
-	tv->tv_sec = mktime(&time);
+	ts->tv_nsec = time.tm_nsec;
+	ts->tv_sec = mktime(&time);
 
 	return;
 
 fallback:
-	getuptime(tv);
-}
-
-void getuptime(struct timeval *tv)
+	getuptime(ts);
+}
+
+/** Get system uptime.
+ *
+ * @param[out] ts  Timespec to hold time current uptime.
+ *
+ * The time variables are memory mapped (read-only) from kernel which
+ * updates them periodically.
+ *
+ * As it is impossible to read 2 values atomically, we use a trick:
+ * First we read the seconds, then we read the microseconds, then we
+ * read the seconds again. If a second elapsed in the meantime, set
+ * the microseconds to zero.
+ *
+ * This assures that the values returned by two subsequent calls
+ * to getuptime() are monotonous.
+ *
+ */
+void getuptime(struct timespec *ts)
 {
 	if (ktime == NULL) {
@@ -654,5 +688,5 @@
 
 	read_barrier();
-	tv->tv_usec = ktime->useconds;
+	ts->tv_nsec = USEC2NSEC(ktime->useconds);
 
 	read_barrier();
@@ -660,28 +694,28 @@
 
 	if (s1 != s2) {
-		tv->tv_sec = max(s1, s2);
-		tv->tv_usec = 0;
+		ts->tv_sec = max(s1, s2);
+		ts->tv_nsec = 0;
 	} else
-		tv->tv_sec = s1;
+		ts->tv_sec = s1;
 
 	return;
 
 fallback:
-	tv->tv_sec = 0;
-	tv->tv_usec = 0;
+	ts->tv_sec = 0;
+	ts->tv_nsec = 0;
 }
 
 time_t time(time_t *tloc)
 {
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
+	struct timespec ts;
+	getrealtime(&ts);
 
 	if (tloc)
-		*tloc = tv.tv_sec;
-
-	return tv.tv_sec;
-}
-
-void udelay(useconds_t time)
+		*tloc = ts.tv_sec;
+
+	return ts.tv_sec;
+}
+
+void udelay(sysarg_t time)
 {
 	(void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
@@ -884,5 +918,5 @@
 			break;
 		case 's':
-			APPEND("%ld", secs_since_epoch(tm));
+			APPEND("%lld", secs_since_epoch(tm));
 			break;
 		case 'S':
@@ -961,5 +995,5 @@
 
 	/* Set result to epoch. */
-	result->tm_usec = 0;
+	result->tm_nsec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -1038,5 +1072,5 @@
  *
  */
-errno_t time_tv2tm(const struct timeval *tv, struct tm *restrict result)
+errno_t time_ts2tm(const struct timespec *ts, struct tm *restrict result)
 {
 	// TODO: Deal with timezones.
@@ -1044,5 +1078,5 @@
 
 	/* Set result to epoch. */
-	result->tm_usec = 0;
+	result->tm_nsec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -1052,5 +1086,5 @@
 	result->tm_year = 70; /* 1970 */
 
-	if (normalize_tm_tv(result, tv) == -1)
+	if (normalize_tm_ts(result, ts) == -1)
 		return EOVERFLOW;
 
@@ -1070,10 +1104,10 @@
 errno_t time_local2tm(const time_t time, struct tm *restrict result)
 {
-	struct timeval tv = {
+	struct timespec ts = {
 		.tv_sec = time,
-		.tv_usec = 0
+		.tv_nsec = 0
 	};
 
-	return time_tv2tm(&tv, result);
+	return time_ts2tm(&ts, result);
 }
 
