Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision 05882233d8ca97c6879ac5c42456c344c8569d89)
+++ uspace/lib/c/generic/time.c	(revision f33c989e878fae6eb2786815ecf7769c2b706bc6)
@@ -35,5 +35,4 @@
  */
 
-#include <sys/time.h>
 #include <time.h>
 #include <stdbool.h>
@@ -57,5 +56,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)
@@ -252,16 +251,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 +270,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 +320,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 +339,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 +455,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 +539,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 +559,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 +605,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 +655,5 @@
 
 	read_barrier();
-	tv->tv_usec = ktime->useconds;
+	ts->tv_nsec = USEC2NSEC(ktime->useconds);
 
 	read_barrier();
@@ -660,28 +661,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(usec_t time)
 {
 	(void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time);
@@ -884,5 +885,5 @@
 			break;
 		case 's':
-			APPEND("%ld", secs_since_epoch(tm));
+			APPEND("%lld", secs_since_epoch(tm));
 			break;
 		case 'S':
@@ -961,5 +962,5 @@
 
 	/* Set result to epoch. */
-	result->tm_usec = 0;
+	result->tm_nsec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -1038,5 +1039,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 +1045,5 @@
 
 	/* Set result to epoch. */
-	result->tm_usec = 0;
+	result->tm_nsec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -1052,5 +1053,5 @@
 	result->tm_year = 70; /* 1970 */
 
-	if (normalize_tm_tv(result, tv) == -1)
+	if (normalize_tm_ts(result, ts) == -1)
 		return EOVERFLOW;
 
@@ -1070,10 +1071,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);
 }
 
