diff -rupN stunt/execute.cc tmp/execute.cc
--- stunt/execute.cc	2015-03-03 09:14:36.616197764 +0100
+++ tmp/execute.cc	2015-09-13 21:36:33.295539821 +0200
@@ -1730,21 +1730,24 @@ do {								\
 	    {
 		Var time;
 		unsigned id = 0, f_index;
+		double when;
 
 		time = POP();
 		f_index = READ_BYTES(bv, bc.numbytes_fork);
 		if (op == OP_FORK_WITH_ID)
 		    id = READ_BYTES(bv, bc.numbytes_var_name);
-		if (time.type != TYPE_INT) {
+		if (time.type != TYPE_INT && time.type != TYPE_FLOAT) {
 		    free_var(time);
 		    RAISE_ERROR(E_TYPE);
-		} else if (time.v.num < 0) {
-		    free_var(time);
+		}
+		when = time.type == TYPE_INT ? time.v.num : *time.v.fnum;
+		free_var(time);
+		if (when < 0) {
 		    RAISE_ERROR(E_INVARG);
 		} else {
 		    enum error e;
 
-		    e = enqueue_forked_task2(RUN_ACTIV, f_index, time.v.num,
+		    e = enqueue_forked_task2(RUN_ACTIV, f_index, when,
 					op == OP_FORK_WITH_ID ? id : -1);
 		    if (e != E_NONE)
 			RAISE_ERROR(e);
@@ -3028,19 +3031,24 @@ bf_raise(Var arglist, Byte next, void *v
 static package
 bf_suspend(Var arglist, Byte next, void *vdata, Objid progr)
 {
-    static int seconds;
+    static double seconds, *secondsp = NULL;
     int nargs = arglist.v.list[0].v.num;
 
-    if (nargs >= 1)
-	seconds = arglist.v.list[1].v.num;
-    else
-	seconds = -1;
+    if (nargs >= 1) {
+	seconds = arglist.v.list[1].type == TYPE_INT ?
+				arglist.v.list[1].v.num :
+				*arglist.v.list[1].v.fnum;
+	secondsp = &seconds;
+    } else {
+	secondsp = NULL;
+    }
     free_var(arglist);
 
     if (nargs >= 1 && seconds < 0)
 	return make_error_pack(E_INVARG);
-    else
-	return make_suspend_pack(enqueue_suspended_task, &seconds);
+    else {
+	return make_suspend_pack(enqueue_suspended_task, secondsp);
+    }
 }
 
 static package
@@ -3235,7 +3243,7 @@ register_execute(void)
 				      bf_call_function_write,
 				      TYPE_STR);
     register_function("raise", 1, 3, bf_raise, TYPE_ANY, TYPE_STR, TYPE_ANY);
-    register_function("suspend", 0, 1, bf_suspend, TYPE_INT);
+    register_function("suspend", 0, 1, bf_suspend, TYPE_NUMERIC);
     register_function("read", 0, 2, bf_read, TYPE_OBJ, TYPE_ANY);
     register_function("read_http", 1, 2, bf_read_http, TYPE_STR, TYPE_OBJ);
 
diff -rupN stunt/net_mp_fake.cc tmp/net_mp_fake.cc
--- stunt/net_mp_fake.cc	2015-03-03 09:03:49.879267632 +0100
+++ tmp/net_mp_fake.cc	2015-09-13 21:04:56.649562761 +0200
@@ -137,9 +137,10 @@ mplex_wait(unsigned timeout)
 	    }
 	}
 
+	timeout -= 1000000;
 	if (got_one)
 	    break;
-	else if (timeout-- > 0)
+	else if (timeout > 0)
 	    sleep(1);
     }
 
diff -rupN stunt/net_mp_poll.cc tmp/net_mp_poll.cc
--- stunt/net_mp_poll.cc	2015-03-03 09:03:49.879267632 +0100
+++ tmp/net_mp_poll.cc	2015-09-13 21:05:31.359492986 +0200
@@ -80,7 +80,7 @@ mplex_add_writer(int fd)
 int
 mplex_wait(unsigned timeout)
 {
-    int result = poll(ports, max_fd + 1, timeout * 1000);
+    int result = poll(ports, max_fd + 1, timeout / 1000);
 
     if (result < 0) {
 	if (errno != EINTR)
diff -rupN stunt/net_mp_selct.cc tmp/net_mp_selct.cc
--- stunt/net_mp_selct.cc	2015-03-03 09:03:49.879267632 +0100
+++ tmp/net_mp_selct.cc	2015-09-13 21:06:13.489408275 +0200
@@ -58,8 +58,8 @@ mplex_wait(unsigned timeout)
     struct timeval tv;
     int n;
 
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
+    tv.tv_sec = timeout / 1000000;
+    tv.tv_usec = timeout % 1000000;
 
     n = select(max_descriptor + 1, &input, &output, 0, &tv);
 
diff -rupN stunt/net_single.cc tmp/net_single.cc
--- stunt/net_single.cc	2015-03-03 09:03:49.879267632 +0100
+++ tmp/net_single.cc	2015-09-13 21:07:29.129256125 +0200
@@ -184,8 +184,8 @@ network_process_io(int timeout)
 	    sh = server_new_connection(slistener, nh, 0);
 	    state = STATE_OPEN;
 	    got_some = 1;
-	} else if (timeout != 0)
-	    sleep(timeout);
+	} else if (timeout > 0)
+	    sleep(timeout / 1000000);
 	break;
 
     case STATE_OPEN:
@@ -213,11 +213,11 @@ network_process_io(int timeout)
 		    }
 	    }
 
-	    if (got_some || timeout == 0)
+	    if (got_some || timeout <= 0)
 		goto done;
 
 	    sleep(1);
-	    timeout--;
+	    timeout -= 1000000;
 	}
     }
 
diff -rupN stunt/server.cc tmp/server.cc
--- stunt/server.cc	2015-03-03 09:03:49.909267490 +0100
+++ tmp/server.cc	2015-09-13 21:09:15.159042722 +0200
@@ -604,7 +604,7 @@ read_values_pending_finalization(void)
 static void
 main_loop(void)
 {
-    int i;
+    int i, res;
 
     /* First, queue anonymous objects */
     for (i = 1; i <= pending_list.v.list[0].v.num; i++) {
@@ -641,8 +641,8 @@ main_loop(void)
 	 * We only care about three cases (== 0, == 1, and > 1), so we can
 	 * map a `never' result from the task subsystem into 2.
 	 */
-	int task_seconds = next_task_start();
-	int seconds_left = task_seconds < 0 ? 2 : task_seconds;
+	int task_useconds = next_task_start();
+	int useconds_left = task_useconds < 0 ? 1000000 : task_useconds;
 	shandle *h, *nexth;
 
 #ifdef ENABLE_GC
@@ -675,10 +675,7 @@ main_loop(void)
 
 	recycle_anonymous_objects();
 
-	if (!network_process_io(seconds_left ? 1 : 0) && seconds_left > 1)
-	    db_flush(FLUSH_ONE_SECOND);
-	else
-	    db_flush(FLUSH_IF_FULL);
+	res = network_process_io(useconds_left);
 
 	run_ready_tasks();
 
diff -rupN stunt/tasks.cc tmp/tasks.cc
--- stunt/tasks.cc	2015-03-03 09:03:49.919267442 +0100
+++ tmp/tasks.cc	2015-09-13 21:32:15.756107468 +0200
@@ -46,6 +46,11 @@
 #include "verbs.h"
 #include "version.h"
 
+#include <sys/time.h>
+#include <math.h>
+
+#define ROUND(tvp)	((tvp)->tv_sec + ((tvp)->tv_usec > 500000))
+
 typedef enum {
     /* Input Tasks */
     TASK_INBAND,	/* vanilla in-band */
@@ -63,19 +68,19 @@ typedef struct forked_task {
     activation a;
     Var *rt_env;
     int f_index;
-    time_t start_time;
+    struct timeval start_tv;
 } forked_task;
 
 typedef struct suspended_task {
     vm the_vm;
-    time_t start_time;
+    struct timeval start_tv;
     Var value;
 } suspended_task;
 
 typedef struct {
     char *string;
     int length;
-    struct task *next_itail;	/* see tqueue.first_itail */ 
+    struct task *next_itail;	/* see tqueue.first_itail */
 } input_task;
 
 typedef struct task {
@@ -88,10 +93,21 @@ typedef struct task {
     } t;
 } task;
 
-inline time_t
-get_start_time(task *t)
-{
-    return t->kind == TASK_FORKED ? t->t.forked.start_time : t->t.suspended.start_time;
+#define GET_START_TIME(ttt) \
+     (ttt->kind == TASK_FORKED \
+     ? &ttt->t.forked.start_tv \
+     : &ttt->t.suspended.start_tv)
+
+static inline struct timeval
+double_to_start_tv(double after_seconds)
+{
+	struct timeval now, delta, when;
+
+	gettimeofday(&now, NULL);
+	delta.tv_sec = floor(after_seconds);
+	delta.tv_usec = 1000000. * (after_seconds - delta.tv_sec);
+	timeradd(&now, &delta, &when);
+	return when;
 }
 
 enum icmd_flag {
@@ -1128,21 +1144,21 @@ static void
 enqueue_waiting(task * t)
 {				/* either FORKED or SUSPENDED */
 
-    time_t start_time = get_start_time(t);
+    struct timeval *start_tvp = GET_START_TIME(t);
     Objid progr = (t->kind == TASK_FORKED
 		   ? t->t.forked.a.progr
 		   : progr_of_cur_verb(t->t.suspended.the_vm));
     tqueue *tq = find_tqueue(progr, 1);
 
     tq->num_bg_tasks++;
-    if (!waiting_tasks || start_time < get_start_time(waiting_tasks)) {
+    if (!waiting_tasks || timercmp(start_tvp, GET_START_TIME(waiting_tasks), <)) {
 	t->next = waiting_tasks;
 	waiting_tasks = t;
     } else {
 	task *tt;
 
 	for (tt = waiting_tasks; tt->next; tt = tt->next)
-	    if (start_time < get_start_time(tt->next))
+	    if (timercmp(start_tvp, GET_START_TIME(tt->next), <))
 		break;
 	t->next = tt->next;
 	tt->next = t;
@@ -1151,7 +1167,7 @@ enqueue_waiting(task * t)
 
 static void
 enqueue_forked(Program * program, activation a, Var * rt_env,
-	   int f_index, time_t start_time, int id)
+	   int f_index, struct timeval start_tv, int id)
 {
     task *t = (task *)mymalloc(sizeof(task), M_TASK);
 
@@ -1170,7 +1186,7 @@ enqueue_forked(Program * program, activa
     t->t.forked.a = a;
     t->t.forked.rt_env = rt_env;
     t->t.forked.f_index = f_index;
-    t->t.forked.start_time = start_time;
+    t->t.forked.start_tv = start_tv;
     t->t.forked.id = id;
 
     enqueue_waiting(t);
@@ -1200,8 +1216,9 @@ check_user_task_limit(Objid user)
 }
 
 enum error
-enqueue_forked_task2(activation a, int f_index, unsigned after_seconds, int vid)
+enqueue_forked_task2(activation a, int f_index, double after_seconds, int vid)
 {
+    struct timeval when;
     int id;
     Var *rt_env;
 
@@ -1230,29 +1247,31 @@ enqueue_forked_task2(activation a, int f
 	a.rt_env[vid].v.num = id;
     }
     rt_env = copy_rt_env(a.rt_env, a.prog->num_var_names);
-    enqueue_forked(a.prog, a, rt_env, f_index, time(0) + after_seconds, id);
-
+    when = double_to_start_tv(after_seconds);
+    enqueue_forked(a.prog, a, rt_env, f_index, when, id);
     return E_NONE;
 }
 
 enum error
 enqueue_suspended_task(vm the_vm, void *data)
 {
-    int after_seconds = *((int *) data);
-    int now = time(0);
-    int when;
+    struct timeval when;
     task *t;
 
+    if (data) {
+	double after_seconds = *((double *) data);
+
+	when = double_to_start_tv(after_seconds);
+    } else {
+	when.tv_sec = INT32_MAX;
+	when.tv_usec = 0;
+    }
+
     if (check_user_task_limit(progr_of_cur_verb(the_vm))) {
 	t = (task *)mymalloc(sizeof(task), M_TASK);
 	t->kind = TASK_SUSPENDED;
 	t->t.suspended.the_vm = the_vm;
-	if (now + after_seconds < now)
-	    /* overflow or suspend `forever' code */
-	    when = INT32_MAX;
-	else
-	    when = now + after_seconds;
-	t->t.suspended.start_time = when;
+	t->t.suspended.start_tv = when;
 	t->t.suspended.value = zero;
 
 	enqueue_waiting(t);
@@ -1270,7 +1289,8 @@ resume_task(vm the_vm, Var value)
 
     t->kind = TASK_SUSPENDED;
     t->t.suspended.the_vm = the_vm;
-    t->t.suspended.start_time = 0;	/* ready now */
+    t->t.suspended.start_tv.tv_sec = 0;	/* ready now */
+    t->t.suspended.start_tv.tv_usec = 0;
     t->t.suspended.value = value;
 
     enqueue_bg_task(tq, t);
@@ -1379,12 +1399,18 @@ next_task_start(void)
 	    return 0;
 
     if (waiting_tasks != 0) {
-	int wait = (waiting_tasks->kind == TASK_FORKED
-		    ? waiting_tasks->t.forked.start_time
-		    : waiting_tasks->t.suspended.start_time) - time(0);
-	return (wait >= 0) ? wait : 0;
+	struct timeval *tvp, now, delta;
+
+	gettimeofday(&now, NULL);
+	tvp = GET_START_TIME(waiting_tasks);
+	timersub(tvp, &now, &delta);
+	if (delta.tv_sec < 0 || delta.tv_usec < 0)
+		return 0;
+	if (delta.tv_sec > 9)
+		delta.tv_sec = 9;
+	return delta.tv_usec + delta.tv_sec * 1000000;
     }
-    return -1;
+    return -1;		/* never */
 }
 
 static Var
@@ -1563,10 +1589,11 @@ void
 run_ready_tasks(void)
 {
     task *t, *next_t;
-    time_t now = time(0);
+    struct timeval now;
     tqueue *tq, *next_tq;
 
-    for (t = waiting_tasks; t && get_start_time(t) <= now; t = next_t) {
+    gettimeofday(&now, NULL);
+    for (t = waiting_tasks; t && timercmp(GET_START_TIME(t), &now, <=); t = next_t) {
 	Objid progr = (t->kind == TASK_FORKED
 		       ? t->t.forked.a.progr
 		       : progr_of_cur_verb(t->t.suspended.the_vm));
@@ -1837,7 +1864,8 @@ write_forked_task(forked_task ft)
 {
     unsigned lineno = find_line_number(ft.program, ft.f_index, 0);
 
-    dbio_printf("0 %d %d %d\n", lineno, ft.start_time, ft.id);
+    /* saving rounds to the nearest second.  restart is slow anyway */
+    dbio_printf("0 %d %d %d\n", lineno, ROUND(&ft.start_tv), ft.id);
     write_activ_as_pi(ft.a);
     write_rt_env(ft.program->var_names, ft.rt_env, ft.program->num_var_names);
     dbio_write_forked_program(ft.program, ft.f_index);
@@ -1846,7 +1874,8 @@ write_forked_task(forked_task ft)
 static void
 write_suspended_task(suspended_task st)
 {
-    dbio_printf("%d %d ", st.start_time, st.the_vm->task_id);
+    /* saving rounds down to the nearest second.  restart is slow anyway */
+    dbio_printf("%d %d ", ROUND(&st.start_tv), st.the_vm->task_id);
     dbio_write_var(st.value);
     write_vm(st.the_vm);
 }
@@ -1964,7 +1993,7 @@ read_task_queue(void)
     for (; count > 0; count--) {
 	int first_lineno, id, old_size, st;
 	char c;
-	time_t start_time;
+	struct timeval start_tv;
 	Program *program;
 	Var *rt_env, *old_rt_env;
 	const char **old_names;
@@ -1976,7 +2005,8 @@ read_task_queue(void)
 	    errlog("READ_TASK_QUEUE: Bad numbers, count = %d.\n", count);
 	    return 0;
 	}
-	start_time = st;
+	start_tv.tv_sec = st;
+	start_tv.tv_usec = 0;
 	if (!read_activ_as_pi(&a)) {
 	    errlog("READ_TASK_QUEUE: Bad activation, count = %d.\n", count);
 	    return 0;
@@ -1994,7 +2024,7 @@ read_task_queue(void)
 	rt_env = reorder_rt_env(old_rt_env, old_names, old_size, program);
 	program->first_lineno = first_lineno;
 
-	enqueue_forked(program, a, rt_env, MAIN_VECTOR, start_time, id);
+	enqueue_forked(program, a, rt_env, MAIN_VECTOR, start_tv, id);
     }
 
     suspended_task_header = dbio_scanf("%d suspended tasks\n",
@@ -2007,16 +2037,17 @@ read_task_queue(void)
     }
     for (; suspended_count > 0; suspended_count--) {
 	task *t = (task *)mymalloc(sizeof(task), M_TASK);
-	int task_id, start_time;
+	int task_id, st;
 	char c;
 
 	t->kind = TASK_SUSPENDED;
-	if (dbio_scanf("%d %d%c", &start_time, &task_id, &c) != 3) {
+	if (dbio_scanf("%d %d%c", &st, &task_id, &c) != 3) {
 	    errlog("READ_TASK_QUEUE: Bad suspended task header, count = %d\n",
 		   suspended_count);
 	    return 0;
 	}
-	t->t.suspended.start_time = start_time;
+	t->t.suspended.start_tv.tv_sec = st;
+	t->t.suspended.start_tv.tv_usec = 0;
 	if (c == ' ')
 	    t->t.suspended.value = dbio_read_var();
 	else if (c == '\n')
@@ -2070,7 +2101,8 @@ read_task_queue(void)
 
 	task *t = (task *)mymalloc(sizeof(task), M_TASK);
 	t->kind = TASK_SUSPENDED;
-	t->t.suspended.start_time = 0;
+	t->t.suspended.start_tv.tv_sec = 0;
+	t->t.suspended.start_tv.tv_usec = 0;
 	t->t.suspended.value.type = TYPE_ERR;
 	t->t.suspended.value.v.err = E_INTRPT;
 	t->t.suspended.the_vm = the_vm;
@@ -2246,7 +2278,7 @@ list_for_forked_task(forked_task ft, Obj
     list.v.list[1].type = TYPE_INT;
     list.v.list[1].v.num = ft.id;
     list.v.list[2].type = TYPE_INT;
-    list.v.list[2].v.num = ft.start_time;
+    list.v.list[2].v.num = ROUND(&ft.start_tv);
     list.v.list[3].type = TYPE_INT;
     list.v.list[3].v.num = 0;			/* OBSOLETE: was clock ID */
     list.v.list[4].type = TYPE_INT;
@@ -2312,7 +2344,7 @@ list_for_suspended_task(suspended_task s
 
     list = list_for_vm(st.the_vm, progr);
     list.v.list[2].type = TYPE_INT;
-    list.v.list[2].v.num = st.start_time;
+    list.v.list[2].v.num = ROUND(&st.start_tv);
 
     return list;
 }
@@ -2669,7 +2701,7 @@ do_resume(int id, Var value, Objid progr
 
 	if (!is_wizard(progr) && progr != owner)
 	    return E_PERM;
-	t->t.suspended.start_time = time(0);	/* runnable now */
+	gettimeofday(&t->t.suspended.start_tv, NULL);	/* runnable now */
 	free_var(t->t.suspended.value);
 	t->t.suspended.value = value;
 	tq = find_tqueue(owner, 1);
diff -rupN stunt/tasks.h tmp/tasks.h
--- stunt/tasks.h	2015-03-03 09:03:49.919267442 +0100
+++ tmp/tasks.h	2015-09-13 21:40:10.675061726 +0200
@@ -38,7 +38,7 @@ extern int tasks_set_connection_option(t
 extern void new_input_task(task_queue, const char *, int);
 extern void task_suspend_input(task_queue);
 extern enum error enqueue_forked_task2(activation a, int f_index,
-			       unsigned after_seconds, int vid);
+			       double after_seconds, int vid);
 extern enum error enqueue_suspended_task(vm the_vm, void *data);
 				/* data == &(int after_seconds) */
 extern enum error make_reading_task(vm the_vm, void *data);
