diff --git a/src/backend.cmod b/src/backend.cmod
index b798f5e13853c4671535efd3c1a01ae3d18be6b5..af46683a0d9e7de4b54219d017fe63cf7ff384b1 100644
--- a/src/backend.cmod
+++ b/src/backend.cmod
@@ -11,6 +11,7 @@
 #include "global.h"
 #include "fdlib.h"
 #include "backend.h"
+#include "time_stuff.h"
 #include <errno.h>
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -191,6 +192,7 @@ DECLARATIONS
 
 struct callback_list do_debug_callbacks;
 struct timeval current_time;
+int current_time_invalid = 1;
 
 /*
  * Stuff to map fds to the proper Backend
@@ -725,7 +727,7 @@ PIKECLASS Backend
      if(num_threads>1)
      {
        struct timeval tmp;
-       GETTIMEOFDAY(&tmp);
+       ACCURATE_GETTIMEOFDAY(&tmp);
        my_add_timeval(& new->tv, &tmp);
        IF_CO (fprintf (stderr, "BACKEND[%d]: Adding call out at %ld.%ld "
 		       "(current time is %ld.%ld)\n", me->id,
@@ -734,11 +736,13 @@ PIKECLASS Backend
      }else
 #endif
      {
-       my_add_timeval(& new->tv, &current_time);
+       struct timeval tmp;
+       INACCURATE_GETTIMEOFDAY(&tmp);
+       my_add_timeval(& new->tv, &tmp);
        IF_CO (fprintf (stderr, "BACKEND[%d]: Adding call out at %ld.%ld "
 		       "(current_time is %ld.%ld)\n", me->id,
 		       new->tv.tv_sec, new->tv.tv_usec,
-		       current_time.tv_sec, current_time.tv_usec));
+		       tmp.tv_sec, tmp.tv_usec));
      }
 
      if(Pike_fp && Pike_fp->current_object)
@@ -863,15 +867,17 @@ PIKECLASS Backend
      {
        int call_count = 0;
        int args;
-       struct timeval tmp;
+       struct timeval tmp, now;
        backend_verify_call_outs(me);
 
-       tmp.tv_sec = current_time.tv_sec;
-       tmp.tv_usec = current_time.tv_usec;
+       INACCURATE_GETTIMEOFDAY(&now);
+       tmp.tv_sec = now.tv_sec;
+       tmp.tv_usec = now.tv_usec;
        tmp.tv_sec++;
        while(me->num_pending_calls &&
-	     my_timercmp(&CALL(0)->tv, <= ,&current_time))
+	     my_timercmp(&CALL(0)->tv, <= ,&now))
        {
+	 struct timeval now;
 	 /* unlink call out */
 	 call_out c,*cc;
 	 
@@ -917,8 +923,8 @@ PIKECLASS Backend
 	 }
 	 backend_verify_call_outs(me);
 	 
-	 GETTIMEOFDAY(&current_time);
-	 if(my_timercmp(&current_time, > , &tmp)) break;
+	 ACCURATE_GETTIMEOFDAY(&now);
+	 if(my_timercmp(&now, > , &tmp)) break;
        }
 
        IF_CO (
@@ -928,7 +934,7 @@ PIKECLASS Backend
 		    "(current_time %ld.%ld, limit at %ld.%ld)\n",
 		    me->id, me->num_pending_calls,
 		    CALL(0)->tv.tv_sec, CALL(0)->tv.tv_usec,
-		    current_time.tv_sec, current_time.tv_usec,
+		    now.tv_sec, now.tv_usec,
 		    tmp.tv_sec, tmp.tv_usec);
 	 else
 	   fprintf (stderr, "BACKEND[%d]: backend_do_call_outs: "
@@ -1021,7 +1027,7 @@ PIKECLASS Backend
  */
    PIKEFUN int _do_call_outs()
      {
-       GETTIMEOFDAY(&current_time);
+       INVALIDATE_CURRENT_TIME();
        RETURN backend_do_call_outs(THIS);
      }
 
@@ -1060,7 +1066,9 @@ PIKECLASS Backend
 	 SET_SVAL(*Pike_sp, T_INT, NUMBER_UNDEFINED, integer, -1);
 	 Pike_sp++;
        }else{
-	 push_int(CALL(e)->tv.tv_sec - current_time.tv_sec);
+	 struct timeval now;
+	 INACCURATE_GETTIMEOFDAY(&now);
+	 push_int(CALL(e)->tv.tv_sec - now.tv_sec);
        }
        UNPROTECT_CALL_OUTS();
        backend_verify_call_outs(me);
@@ -1093,12 +1101,14 @@ PIKECLASS Backend
        backend_verify_call_outs(me);
        if(e!=-1)
        {
+	 struct timeval now;
+	 INACCURATE_GETTIMEOFDAY(&now);
 	 IF_CO (fprintf (stderr, "BACKEND[%d]: Removing call out at %ld.%ld "
 			 "(current_time is %ld.%ld)\n", me->id,
 			 CALL(e)->tv.tv_sec, CALL(e)->tv.tv_usec,
-			 current_time.tv_sec, current_time.tv_usec));
+			 now.tv_sec, now.tv_usec));
 	 pop_n_elems(args);
-	 push_int(CALL(e)->tv.tv_sec - current_time.tv_sec);
+	 push_int(CALL(e)->tv.tv_sec - now.tv_sec);
 	 free_array(CALL(e)->args);
 	 if(CALL(e)->caller)
 	   free_object(CALL(e)->caller);
@@ -1127,6 +1137,7 @@ PIKECLASS Backend
      {
        int e;
        struct array *ret;
+       struct timeval now;
        ONERROR err;
 
        backend_verify_call_outs(me);
@@ -1134,11 +1145,12 @@ PIKECLASS Backend
        ret=allocate_array_no_init(0, me->num_pending_calls);
        SET_ONERROR(err, do_free_array, ret);
        ret->type_field = BIT_ARRAY;
+       if(me->num_pending_calls) INACCURATE_GETTIMEOFDAY(&now);
        for(e=0;e<me->num_pending_calls;e++)
        {
 	 struct array *v;
 	 v=allocate_array_no_init(CALL(e)->args->size+2, 0);
-	 ITEM(v)[0].u.integer=CALL(e)->tv.tv_sec - current_time.tv_sec;
+	 ITEM(v)[0].u.integer=CALL(e)->tv.tv_sec - now.tv_sec;
 	 
 	 if(CALL(e)->caller)
 	 {
@@ -1799,7 +1811,7 @@ PIKECLASS Backend
 #ifdef PIKE_DEBUG
     struct timeval max_timeout;
 #endif
-    struct timeval *next_timeout = &me->next_timeout;
+    struct timeval *next_timeout = &me->next_timeout, now;
 
     alloca(0);			/* Do garbage collect */
 #ifdef PIKE_DEBUG
@@ -1826,12 +1838,14 @@ PIKECLASS Backend
     me->exec_thread = 1;
 #endif
       
+
 #ifndef OWN_GETHRTIME
-    GETTIMEOFDAY(&current_time);
+    ACCURATE_GETTIMEOFDAY(&now);
 #else
     /* good place to run the gethrtime-conversion update
        since we have to run gettimeofday anyway /Mirar */
-    own_gethrtime_update(&current_time);
+    INACCURATE_GETTIMEOFDAY(&now);
+    own_gethrtime_update(&now);
 #endif
     if (start_time->tv_sec < 0) {
       next_timeout->tv_sec = -1;
@@ -1839,10 +1853,10 @@ PIKECLASS Backend
     }
     else {
       *next_timeout = *start_time;
-      my_add_timeval(next_timeout, &current_time);
+      my_add_timeval(next_timeout, &now);
     }
 
-    *start_time = current_time;
+    *start_time = now;
 
     /* Call outs */
     if(me->num_pending_calls)
@@ -1870,9 +1884,9 @@ PIKECLASS Backend
       next_timeout->tv_sec = 100000000;
       next_timeout->tv_usec = 0;
     }
-    else if(my_timercmp(next_timeout, > , &current_time))
+    else if(my_timercmp(next_timeout, > , &now))
     {
-      my_subtract_timeval(next_timeout, &current_time);
+      my_subtract_timeval(next_timeout, &now);
     }else{
       next_timeout->tv_usec = 0;
       next_timeout->tv_sec = 0;
@@ -2063,7 +2077,7 @@ PIKECLASS Backend
     me->backend_callbacks.callbacks=0;
     me->backend_callbacks.num_calls=0;
 
-    GETTIMEOFDAY(&current_time); /* Why? /mast */
+    INVALIDATE_CURRENT_TIME(); /* Why? /mast */
 
     me->num_pending_calls=0;
     me->call_buffer=0;
@@ -3224,7 +3238,7 @@ PIKECLASS PollDeviceBackend
       THREADS_DISALLOW();
       check_threads_etc();
       me->may_need_wakeup = 0;
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }
 
     if (TYPEOF(me->after_callback) != T_INT)
@@ -3419,7 +3433,7 @@ PIKECLASS PollDeviceBackend
       CALL_AND_UNSET_ONERROR(free_fd_list);
 
       /* Must be up-to-date for backend_do_call_outs. */
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }else{
       switch(errno)
       {
@@ -3470,8 +3484,10 @@ PIKECLASS PollDeviceBackend
     if (!done_something)
       timeout->tv_sec = -1;
     else {
-      timeout->tv_sec = current_time.tv_sec;
-      timeout->tv_usec = current_time.tv_usec;
+      struct timeval now;
+      INACCURATE_GETTIMEOFDAY(&now);
+      timeout->tv_sec = now.tv_sec;
+      timeout->tv_usec = now.tv_usec;
       my_subtract_timeval (timeout, &start_time);
     }
 
@@ -3822,7 +3838,7 @@ PIKECLASS PollBackend
       THREADS_DISALLOW();
       check_threads_etc();
       me->may_need_wakeup = 0;
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }
 
     if (TYPEOF(me->after_callback) != T_INT)
@@ -3981,7 +3997,7 @@ PIKECLASS PollBackend
       CALL_AND_UNSET_ONERROR(free_fd_list);
 
       /* Must be up-to-date for backend_do_call_outs. */
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }else{
       switch(errno)
       {
@@ -4032,8 +4048,10 @@ PIKECLASS PollBackend
     if (!done_something)
       timeout->tv_sec = -1;
     else {
-      timeout->tv_sec = current_time.tv_sec;
-      timeout->tv_usec = current_time.tv_usec;
+      struct timeval now;
+      INACCURATE_GETTIMEOFDAY(&now);
+      timeout->tv_sec = now.tv_sec;
+      timeout->tv_usec = now.tv_usec;
       my_subtract_timeval (timeout, &start_time);
     }
 
@@ -4377,7 +4395,7 @@ PIKECLASS SelectBackend
       THREADS_DISALLOW();
       check_threads_etc();
       me->may_need_wakeup = 0;
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }
 
     if (TYPEOF(me->after_callback) != T_INT)
@@ -4462,7 +4480,7 @@ PIKECLASS SelectBackend
       CALL_AND_UNSET_ONERROR(free_fd_list);
 
       /* Must be up-to-date for backend_do_call_outs. */
-      GETTIMEOFDAY(&current_time);
+      INVALIDATE_CURRENT_TIME();
     }else{
       switch(errno)
       {
@@ -4586,8 +4604,10 @@ PIKECLASS SelectBackend
     if (!done_something)
       timeout->tv_sec = -1;
     else {
-      timeout->tv_sec = current_time.tv_sec;
-      timeout->tv_usec = current_time.tv_usec;
+      struct timeval now;
+      INACCURATE_GETTIMEOFDAY(&now);
+      timeout->tv_sec = now.tv_sec;
+      timeout->tv_usec = now.tv_usec;
       my_subtract_timeval (timeout, &start_time);
     }
 
@@ -4943,7 +4963,7 @@ void wake_up_backend(void)
 void do_call_outs(void)
 {
   if(default_backend) {
-    GETTIMEOFDAY (&current_time);
+    INVALIDATE_CURRENT_TIME();
     backend_do_call_outs(default_backend);
   }
 }
diff --git a/src/backend.h b/src/backend.h
index 836db0f8324c42cbf10758649d041d430c91a839..0cfe9de5d2d8aa70df08d564d331624facbfb769 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -72,7 +72,6 @@
 
 struct Backend_struct;
 
-PMOD_EXPORT extern struct timeval current_time;
 PMOD_EXPORT extern struct Backend_struct *default_backend;
 extern struct callback_list do_debug_callbacks;
 PMOD_EXPORT extern struct program *Backend_program;
diff --git a/src/builtin.cmod b/src/builtin.cmod
index c31aefa03018baf56c80c9a3b5a5dff3e94dec88..505680ac53268e69284fae0dca74db5620928011 100644
--- a/src/builtin.cmod
+++ b/src/builtin.cmod
@@ -3223,22 +3223,26 @@ PIKECLASS Time
 
   PIKEFUN int `sec()
   {
-    extern struct timeval current_time;
+    struct timeval now;
 
     if( THIS->hard_update )
-      GETTIMEOFDAY( &current_time );
+      ACCURATE_GETTIMEOFDAY( &now );
+    else
+      INACCURATE_GETTIMEOFDAY( &now );
 
-    RETURN current_time.tv_sec;
+    RETURN now.tv_sec;
   }
 
   PIKEFUN int `usec()
   {
-    extern struct timeval current_time;
+    struct timeval now;
 
     if( THIS->hard_update )
-      GETTIMEOFDAY( &current_time );
+      ACCURATE_GETTIMEOFDAY( &now );
+    else
+      INACCURATE_GETTIMEOFDAY( &now );
 
-    RETURN current_time.tv_usec;
+    RETURN now.tv_usec;
   }
 
   /*! @decl int usec_full
@@ -3250,20 +3254,22 @@ PIKECLASS Time
 
   PIKEFUN int `usec_full()
   {
-    extern struct timeval current_time;
+    struct timeval now;
 
     if( THIS->hard_update )
-      GETTIMEOFDAY( &current_time );
+      ACCURATE_GETTIMEOFDAY( &now );
+    else
+      INACCURATE_GETTIMEOFDAY( &now );
 
 #ifdef AUTO_BIGNUM
-    push_int( current_time.tv_sec );
+    push_int( now.tv_sec );
     push_int( 1000000 );
     f_multiply( 2 );
-    push_int( current_time.tv_usec );
+    push_int( now.tv_usec );
     f_add( 2 );
     return;
 #else
-    RETURN (current_time.tv_sec * 1000000 + current_time.tv_usec);
+    RETURN (now.tv_sec * 1000000 + now.tv_usec);
 #endif
   }
 
@@ -3297,12 +3303,14 @@ PIKECLASS Timer
    */
   PIKEFUN float peek( )
   {
-    extern struct timeval current_time;
+    struct timeval now;
     FLOAT_TYPE res;
     if( THIS->hard_update )
-      GETTIMEOFDAY( &current_time );
-    res = current_time.tv_sec-THIS->last_time.tv_sec +
-      (current_time.tv_usec-THIS->last_time.tv_usec)/(FLOAT_TYPE) 1000000.0;
+      ACCURATE_GETTIMEOFDAY( &now );
+    else
+      INACCURATE_GETTIMEOFDAY( &now );
+    res = now.tv_sec-THIS->last_time.tv_sec +
+      (now.tv_usec-THIS->last_time.tv_usec)/(FLOAT_TYPE) 1000000.0;
     RETURN res;
   }
 
@@ -3313,9 +3321,8 @@ PIKECLASS Timer
    */
   PIKEFUN float get( )
   {
-    extern struct timeval current_time;
     f_Timer_peek( 0 );
-    THIS->last_time = current_time;
+    INACCURATE_GETTIMEOFDAY(&THIS->last_time);
     return;
   }
 
@@ -3332,11 +3339,11 @@ PIKECLASS Timer
   PIKEFUN void create( int|zero|void fast )
     flags ID_PROTECTED;
   {
-    extern struct timeval current_time;
     THIS->hard_update = !fast;
     if( THIS->hard_update )
-      GETTIMEOFDAY( &current_time );
-    THIS->last_time = current_time; 
+      ACCURATE_GETTIMEOFDAY( &THIS->last_time );
+    else
+      INACCURATE_GETTIMEOFDAY( &THIS->last_time );
   }
 }
 
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index b21748c1eda1f74ef57cf9d6ba4ca4362ea45dc9..0f71e6c1074a1dbf7c685ce836f6ebaac23736e3 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -2930,25 +2930,31 @@ void f__exit(INT32 args)
  */
 PMOD_EXPORT void f_time(INT32 args)
 {
+  struct timeval ret;
   if(!args ||
      (TYPEOF(Pike_sp[-args]) == T_INT && Pike_sp[-args].u.integer == 0))
   {
-    GETTIMEOFDAY(&current_time);
+    ACCURATE_GETTIMEOFDAY(&ret);
+    pop_n_elems(args);
+    push_int(ret.tv_sec);
+
+    return;
   }else{
     if(TYPEOF(Pike_sp[-args]) == T_INT && Pike_sp[-args].u.integer > 1)
     {
       struct timeval tmp;
-      GETTIMEOFDAY(&current_time);
+      ACCURATE_GETTIMEOFDAY(&ret);
       tmp.tv_sec=Pike_sp[-args].u.integer;
       tmp.tv_usec=0;
-      my_subtract_timeval(&tmp,&current_time);
+      my_subtract_timeval(&tmp,&ret);
       pop_n_elems(args);
       push_float( - (FLOAT_TYPE)tmp.tv_sec-((FLOAT_TYPE)tmp.tv_usec)/1000000 );
       return;
     }
   }
   pop_n_elems(args);
-  push_int(current_time.tv_sec);
+  INACCURATE_GETTIMEOFDAY(&ret);
+  push_int(ret.tv_sec);
 }
 
 /*! @decl string crypt(string password)
@@ -4662,13 +4668,13 @@ static void delaysleep(double delay, unsigned do_abort_on_signal,
    if (t0 == -1) {
      /* Paranoia in case get_real_time fails. */
      /* fprintf (stderr, "get_real_time failed in sleep()\n"); */
-     GETTIMEOFDAY (&gtod_t0);
+     ACCURATE_GETTIMEOFDAY (&gtod_t0);
      gtod_tv = gtod_t0;
    }
 
 #define FIX_LEFT()							\
    if (t0 == -1) {							\
-     GETTIMEOFDAY (&gtod_tv);						\
+     ACCURATE_GETTIMEOFDAY (&gtod_tv);					\
      left = delay - ((gtod_tv.tv_sec-gtod_t0.tv_sec) +			\
 		     (gtod_tv.tv_usec-gtod_t0.tv_usec)*1e-6);		\
    }									\
@@ -4690,7 +4696,7 @@ static void delaysleep(double delay, unsigned do_abort_on_signal,
 	 sysleep(left);
        THREADS_DISALLOW();
        if(do_abort_on_signal) {
-	 GETTIMEOFDAY (&current_time);
+	 INVALIDATE_CURRENT_TIME();
 	 return;
        }
        FIX_LEFT();
@@ -4698,14 +4704,14 @@ static void delaysleep(double delay, unsigned do_abort_on_signal,
 	 break;
        check_threads_etc();
      }
-     GETTIMEOFDAY (&current_time);
+     INVALIDATE_CURRENT_TIME();
    }
 
    if (do_microsleep) {
      if (t0 == -1) {
        while (delay> ((gtod_tv.tv_sec-gtod_t0.tv_sec) +
 		      (gtod_tv.tv_usec-gtod_t0.tv_usec)*1e-6))
-	 GETTIMEOFDAY (&gtod_tv);
+	 ACCURATE_GETTIMEOFDAY (&gtod_tv);
      }
      else {
        while (delay> (tv - t0) * (1.0 / CPU_TIME_TICKS))
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 4045e88ee25376e2a2652a412442a00a60d18356..c369bfdd43309193204dd0eeab2d6f540600858b 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -23,6 +23,7 @@
 #include "bignum.h"
 #include "builtin_functions.h"
 #include "gc.h"
+#include "time_stuff.h"
 
 #include "file_machine.h"
 #include "file.h"
@@ -1343,6 +1344,9 @@ static void file_read(INT32 args)
       push_int(0);
     }
 
+  if (!(THIS->open_mode & FILE_NONBLOCKING))
+    INVALIDATE_CURRENT_TIME();
+
   /* Race: A backend in another thread might have managed to set these
    * again for something that arrived after the read above. Not that
    * bad - it will get through in a later backend round. */
@@ -1604,6 +1608,9 @@ static void file_read_oob(INT32 args)
     push_int(0);
   }
 
+  if (!(THIS->open_mode & FILE_NONBLOCKING))
+    INVALIDATE_CURRENT_TIME();
+
   /* Race: A backend in another thread might have managed to set these
    * again for something that arrived after the read above. Not that
    * bad - it will get through in a later backend round. */
@@ -1791,6 +1798,9 @@ static void file_write(INT32 args)
       struct iovec *iov = iovbase;
       int iovcnt = a->size;
 
+      if (!(THIS->open_mode & FILE_NONBLOCKING))
+	INVALIDATE_CURRENT_TIME();
+
       i = a->size;
       while(i--) {
 	if (a->item[i].u.string->len) {
@@ -1953,6 +1963,9 @@ static void file_write(INT32 args)
 
     check_threads_etc();
 
+    if (!(THIS->open_mode & FILE_NONBLOCKING))
+      INVALIDATE_CURRENT_TIME();
+
     if(i<0)
     {
 #ifdef HAVE_PIKE_SEND_FD
@@ -2123,6 +2136,9 @@ static void file_write_oob(INT32 args)
     ADD_FD_EVENTS (THIS, PIKE_BIT_FD_WRITE_OOB);
   ERRNO=0;
 
+  if (!(THIS->open_mode & FILE_NONBLOCKING))
+    INVALIDATE_CURRENT_TIME();
+
   pop_n_elems(args);
   push_int64(written);
 }
@@ -4376,6 +4392,7 @@ static void file_open_socket(INT32 args)
     addr_len = get_inet_addr(&addr, (char *) STR0(Pike_sp[2-args].u.string),
 			     NULL, -1, 0);
     family = SOCKADDR_FAMILY(addr);
+    INVALIDATE_CURRENT_TIME();
   }
 
   if (args && TYPEOF(Pike_sp[-args]) == PIKE_T_INT &&
@@ -4411,6 +4428,7 @@ static void file_open_socket(INT32 args)
 			      Pike_sp[-args].u.string->str : NULL),
 			     (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
 			      Pike_sp[-args].u.integer : -1), 0);
+    INVALIDATE_CURRENT_TIME();
 
     fd=fd_socket((family<0? SOCKADDR_FAMILY(addr):family), SOCK_STREAM, 0);
     if(fd < 0)
@@ -4687,6 +4705,7 @@ static void file_connect(INT32 args)
 			    dest_port->u.string->str : NULL),
 			   (TYPEOF(*dest_port) == PIKE_T_INT?
 			    dest_port->u.integer : -1), 0);
+  INVALIDATE_CURRENT_TIME();
 
   if(was_closed)
   {
diff --git a/src/modules/files/socket.c b/src/modules/files/socket.c
index 16f45f142339321c2a20f91094108d067798f01e..58fc0dc09f4ff4153fe651df047667879afa6984 100644
--- a/src/modules/files/socket.c
+++ b/src/modules/files/socket.c
@@ -20,6 +20,7 @@
 #include "threads.h"
 #include "program_id.h"
 #include "module_support.h"
+#include "time_stuff.h"
 
 #include "file_machine.h"
 #include "file.h"
@@ -75,6 +76,7 @@ struct port
 {
   struct fd_callback_box box;	/* Must be first. */
   int my_errno;
+  unsigned int immediate_cnt;
   struct svalue accept_callback; /* Mapped. */
   struct svalue id;		/* Mapped. */
 };
@@ -95,6 +97,7 @@ static int got_port_event (struct fd_callback_box *box, int event)
 #endif
 
   p->my_errno = errno;		/* Propagate backend setting. */
+  p->immediate_cnt++;
   push_svalue (&p->id);
   apply_svalue(& p->accept_callback, 1);
   pop_stack();
@@ -261,6 +264,7 @@ static void port_bind(INT32 args)
 			    Pike_sp[-args].u.string->str : NULL),
 			   (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
 			    Pike_sp[-args].u.integer : -1), 0);
+  INVALIDATE_CURRENT_TIME();
 
   fd=fd_socket(SOCKADDR_FAMILY(addr), SOCK_STREAM, 0);
 
@@ -536,6 +540,7 @@ static void port_accept(INT32 args)
     err = errno;
   } while (fd < 0 && err == EINTR);
   THREADS_DISALLOW();
+  INVALIDATE_CURRENT_TIME();
 
   if(fd < 0)
   {
diff --git a/src/modules/files/udp.c b/src/modules/files/udp.c
index 51147eff877d6b693c961630095e7e174e07ecab..a43b902f2298e9aeefca79c5ed425215305f892f 100644
--- a/src/modules/files/udp.c
+++ b/src/modules/files/udp.c
@@ -18,6 +18,7 @@
 #include "mapping.h"
 #include "object.h"
 #include "backend.h"
+#include "time_stuff.h"
 #include "fd_control.h"
 
 #include "pike_error.h"
@@ -133,6 +134,8 @@ struct udp_storage {
   struct fd_callback_box box;	/* Must be first. */
   int my_errno;
    
+  int nonblocking;
+
   int type;
   int protocol;
 
@@ -215,6 +218,7 @@ static void udp_bind(INT32 args)
 			    Pike_sp[-args].u.string->str : NULL),
 			   (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
 			    Pike_sp[-args].u.integer : -1), 1);
+  INVALIDATE_CURRENT_TIME();
 
   fd = fd_socket(SOCKADDR_FAMILY(addr), THIS->type, THIS->protocol);
   if(fd < 0)
@@ -328,6 +332,7 @@ void udp_enable_multicast(INT32 args)
   get_all_args("enable_multicast", args, "%s", &ip);
 
   get_inet_addr(&reply, ip, NULL, -1, 1);
+  INVALIDATE_CURRENT_TIME();
 
   if(SOCKADDR_FAMILY(reply) != AF_INET)
     Pike_error("Multicast only supported for IPv4.\n");
@@ -378,6 +383,7 @@ void udp_add_membership(INT32 args)
   get_all_args("add_membership", args, "%s.%s%d", &group, &address, &face);
 
   get_inet_addr(&addr, group, NULL, -1, 1);
+  INVALIDATE_CURRENT_TIME();
 
   if(SOCKADDR_FAMILY(addr) != AF_INET)
     Pike_error("Multicast only supported for IPv4.\n");
@@ -388,6 +394,7 @@ void udp_add_membership(INT32 args)
     sock.imr_interface.s_addr = htonl( INADDR_ANY );
   else {
     get_inet_addr(&addr, address, NULL, -1, 1);
+    INVALIDATE_CURRENT_TIME();
 
     if(SOCKADDR_FAMILY(addr) != AF_INET)
       Pike_error("Multicast only supported for IPv4.\n");
@@ -419,6 +426,7 @@ void udp_drop_membership(INT32 args)
   get_all_args("drop_membership", args, "%s.%s%d", &group, &address, &face);
 
   get_inet_addr(&addr, group, NULL, -1, 1);
+  INVALIDATE_CURRENT_TIME();
 
   if(SOCKADDR_FAMILY(addr) != AF_INET)
     Pike_error("Multicast only supported for IPv4.\n");
@@ -429,6 +437,7 @@ void udp_drop_membership(INT32 args)
     sock.imr_interface.s_addr = htonl( INADDR_ANY );
   else {
     get_inet_addr(&addr, address, NULL, -1, 1);
+    INVALIDATE_CURRENT_TIME();
 
     if(SOCKADDR_FAMILY(addr) != AF_INET)
       Pike_error("Multicast only supported for IPv4.\n");
@@ -656,6 +665,9 @@ void udp_read(INT32 args)
   push_constant_text("port");
   push_int(ntohs(from.ipv4.sin_port));
   f_aggregate_mapping( 6 );
+
+  if (!THIS->nonblocking)
+    INVALIDATE_CURRENT_TIME();
 }
 
 /*! @decl int send(string to, int|string port, string message)
@@ -708,6 +720,7 @@ void udp_sendto(INT32 args)
 			  Pike_sp[1-args].u.string->str : NULL),
 			 (TYPEOF(Pike_sp[1-args]) == PIKE_T_INT?
 			  Pike_sp[1-args].u.integer : -1), 1);
+  INVALIDATE_CURRENT_TIME();
 
   fd = FD;
   str = Pike_sp[2-args].u.string->str;
@@ -752,6 +765,8 @@ void udp_sendto(INT32 args)
   }
   pop_n_elems(args);
   push_int64(res);
+  if (!THIS->nonblocking)
+    INVALIDATE_CURRENT_TIME();
 }
 
 
@@ -843,6 +858,7 @@ static void udp_set_nonblocking(INT32 args)
      pop_stack();
   }
   set_nonblocking(FD,1);
+  THIS->nonblocking = 1;
   ref_push_object(THISOBJ);
 }
 
@@ -854,6 +870,7 @@ static void udp_set_blocking(INT32 args)
 {
   if (FD < 0) Pike_error("File not open.\n");
   set_nonblocking(FD,0);
+  THIS->nonblocking = 0;
   pop_n_elems(args);
   ref_push_object(THISOBJ);
 }
@@ -897,6 +914,7 @@ static void udp_connect(INT32 args)
 			     dest_port->u.string->str : NULL),
 			    (TYPEOF(*dest_port) == PIKE_T_INT?
 			     dest_port->u.integer : -1), 0);
+  INVALIDATE_CURRENT_TIME();
 
   if(FD < 0)
   {
@@ -914,6 +932,9 @@ static void udp_connect(INT32 args)
   tmp=fd_connect(tmp, (struct sockaddr *)&addr, addr_len);
   THREADS_DISALLOW();
 
+  if (!THIS->nonblocking)
+    INVALIDATE_CURRENT_TIME();
+
   if(tmp < 0)
   {
     THIS->my_errno=errno;
diff --git a/src/modules/system/system.c b/src/modules/system/system.c
index a972d438eda6d51923c6fd16f8b444d6fa2ddc1d..b529dbff17e709ff142bf0498fc63c23e836bdc9 100644
--- a/src/modules/system/system.c
+++ b/src/modules/system/system.c
@@ -36,6 +36,7 @@
 #include "mapping.h"
 #include "builtin_functions.h"
 #include "constants.h"
+#include "time_stuff.h"
 #include "pike_memory.h"
 #include "pike_security.h"
 #include "bignum.h"
@@ -2069,6 +2070,7 @@ void f_gethostbyaddr(INT32 args)
   pop_n_elems(args);
 
   CALL_GETHOSTBYADDR((char *)&addr, sizeof (addr), AF_INET);
+  INVALIDATE_CURRENT_TIME();
 
   if(!ret) {
     push_int(0);
@@ -2108,6 +2110,7 @@ void f_gethostbyname(INT32 args)
   get_all_args("gethostbyname", args, "%s", &name);
 
   CALL_GETHOSTBYNAME(name);
+  INVALIDATE_CURRENT_TIME();
  
   pop_n_elems(args);
   
diff --git a/src/pike_embed.c b/src/pike_embed.c
index 14f9ede693834aefd1776f5b5f48aa7adb43c53d..e0224ab8ed5a1faa28ba097bcc45295cbb2ec7fe 100644
--- a/src/pike_embed.c
+++ b/src/pike_embed.c
@@ -362,7 +362,7 @@ void init_pike_runtime(void (*exit_cb)(int))
   
   TRACE((stderr, "Init time...\n"));
   
-  GETTIMEOFDAY(&current_time);
+  UPDATE_CURRENT_TIME();
 
   TRACE((stderr, "Init threads...\n"));
 
diff --git a/src/port.c b/src/port.c
index 5ff43f84e95adf4372e63c8b7aec987efc04fa6c..3f55b08e806181028936788c06e057e3b3111f46 100644
--- a/src/port.c
+++ b/src/port.c
@@ -99,7 +99,7 @@ void GETTIMEOFDAY(struct timeval *t)
 time_t TIME(time_t *t)
 {
   struct timeval tv;
-  GETTIMEOFDAY(&tv);
+  ACCURATE_GETTIMEOFDAY(&tv);
   if(t) *t=tv.tv_sec;
   return tv.tv_sec;
 }
@@ -824,7 +824,7 @@ void own_gethrtime_init()
 {
    int fd;
 
-   GETTIMEOFDAY(&hrtime_timeval_zero);
+   ACCURATE_GETTIMEOFDAY(&hrtime_timeval_zero);
    hrtime_rtsc_zero=rtsc();
    hrtime_rtsc_last = hrtime_rtsc_base = hrtime_rtsc_zero;
 #ifdef RTSC_DEBUG
@@ -893,7 +893,7 @@ void own_gethrtime_update(struct timeval *ptr)
    static double w_c_c_sum = 0.0;
    static int count = -COUNT_THRESHOLD;
 
-   GETTIMEOFDAY(ptr);
+   ACCURATE_GETTIMEOFDAY(ptr);
    now=rtsc();
 
 #ifdef RTSC_DEBUG
diff --git a/src/post_modules/GTK1/source/global.pre b/src/post_modules/GTK1/source/global.pre
index 35564893290adf0de84f0afba532b180b889698b..72080eb923e7dbe24dcd8a1b42849d05ae95b926 100644
--- a/src/post_modules/GTK1/source/global.pre
+++ b/src/post_modules/GTK1/source/global.pre
@@ -28,7 +28,8 @@ static void backend_callback(struct callback *_cb,
 {
   if(backend)
   {
-    struct timeval timeout = current_time;
+    struct timeval timeout;
+    INACCURATE_GETTIMEOFDAY(&timeout);
     timeout.tv_usec += 20000;
     if(timeout.tv_usec > 1000000)
     {
diff --git a/src/post_modules/GTK2/source/global.pre b/src/post_modules/GTK2/source/global.pre
index 4f0fed1cc94e4aa1e78305b101791b1c1be143c4..a290cec814e03773cb23c66918b1566fe642eccc 100644
--- a/src/post_modules/GTK2/source/global.pre
+++ b/src/post_modules/GTK2/source/global.pre
@@ -58,7 +58,8 @@ static void backend_callback(struct callback *_cb,
 {
   if(backend)
   {
-    struct timeval timeout = current_time;
+    struct timeval timeout;
+    INACCURATE_GETTIMEOFDAY(&timeout);
     timeout.tv_usec += 20000;
     if(timeout.tv_usec > 1000000)
     {
diff --git a/src/program.c b/src/program.c
index c5b8f318a293d53e3a507abb01ad5885ec5c8abf..5b5ae40c0979be050a2a9f1674aead43b8d308e0 100644
--- a/src/program.c
+++ b/src/program.c
@@ -2574,7 +2574,7 @@ struct program *low_allocate_program(void)
   INIT_PIKE_MEMOBJ(p, T_PROGRAM);
 
   DOUBLELINK(first_program, p);
-  GETTIMEOFDAY(& p->timestamp);
+  ACCURATE_GETTIMEOFDAY(& p->timestamp);
   return p;
 }
 
diff --git a/src/rusage.c b/src/rusage.c
index ee684f2a2a3adf9285251879f2233cc0e56d2597..064b3dc661a7e16963bf77a99ab0473ffb84f7f1 100644
--- a/src/rusage.c
+++ b/src/rusage.c
@@ -325,7 +325,11 @@ PMOD_EXPORT int pike_get_rusage(pike_rusage_t rusage_values)
   /* This is totally wrong, but hey, if you can't do it _right_... */
   struct timeval tm;
   MEMSET(rusage_values, 0, sizeof(pike_rusage_t));
+#ifndef CONFIGURE_TEST
+  ACCURATE_GETTIMEOFDAY(&tm);
+#else
   GETTIMEOFDAY(&tm);
+#endif
   rusage_values[0]=tm.tv_sec*1000L + tm.tv_usec/1000;
   return 1;
 }
@@ -814,7 +818,13 @@ PMOD_EXPORT int fallback_grt_is_monotonic = 0;
 PMOD_EXPORT cpu_time_t fallback_grt(void)
 {
   struct timeval tv;
+  int gtod_rval;
+#ifndef CONFIGURE_TEST
+  ACCURATE_GETTIMEOFDAY_RVAL(&tv, gtod_rval);
+  if (gtod_rval < 0) return -1;
+#else
   if (GETTIMEOFDAY(&tv) < 0) return -1;
+#endif
   return tv.tv_sec * CPU_TIME_TICKS + USEC_TO_CPU_TIME_T (tv.tv_usec);
 }
 
diff --git a/src/signal_handler.c b/src/signal_handler.c
index 20fbece1f13ebfa937fdb35219ffc7b4383aa146..85242353e6b067783531a17eae19adbaabd1baca 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -23,6 +23,7 @@
 #include "builtin_functions.h"
 #include "pike_security.h"
 #include "main.h"
+#include "time_stuff.h"
 #include <signal.h>
 
 #ifdef HAVE_PASSWD_H
@@ -1716,6 +1717,8 @@ static void f_pid_status_wait(INT32 args)
   }
   }
 #endif /* __NT__ */
+
+  INVALIDATE_CURRENT_TIME();
 }
 
 /*! @decl int(-1..2) status()
diff --git a/src/threads.c b/src/threads.c
index 4e191b3384d2566d367399fda63a9f7076d54b2e..a0c0be138141eb79142536fb2700e3bb9e6d8cae 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -283,6 +283,7 @@ PMOD_EXPORT int co_destroy(COND_T *c)
 #ifndef CONFIGURE_TEST
 PMOD_EXPORT int co_wait_timeout(COND_T *c, PIKE_MUTEX_T *m, long s, long nanos)
 {
+  struct timeval ct;
 #ifdef POSIX_THREADS
   struct timespec timeout;
 #ifdef HAVE_PTHREAD_COND_RELTIMEDWAIT_NP
@@ -292,9 +293,9 @@ PMOD_EXPORT int co_wait_timeout(COND_T *c, PIKE_MUTEX_T *m, long s, long nanos)
   return pthread_cond_reltimedwait_np(c, m, &timeout);
 #else /* !HAVE_PTHREAD_COND_RELTIMEDWAIT_NP */
   /* Absolute timeout. */
-  GETTIMEOFDAY(&current_time);
-  timeout.tv_sec = current_time.tv_sec + s;
-  timeout.tv_nsec = current_time.tv_usec * 1000 + nanos;
+  ACCURATE_GETTIMEOFDAY(&ct);
+  timeout.tv_sec = ct.tv_sec + s;
+  timeout.tv_nsec = ct.tv_usec * 1000 + nanos;
   return pthread_cond_timedwait(c, m, &timeout);
 #endif /* HAVE_PTHREAD_COND_RELTIMEDWAIT_NP */
 #else /* !POSIX_THREADS */
@@ -1500,7 +1501,7 @@ static void check_threads(struct callback *cb, void *arg, void * arg2)
        preliminary check that at least 35 ms real time has passed. If
        not yet true we'll postpone the next check a full interval. */
     struct timeval                tv;
-    if (GETTIMEOFDAY(&tv) == 0) {
+    if (ACCURATE_GETTIMEOFDAY(&tv) == 0) {
 #ifdef INT64
       static INT64 real_time_last_check = 0;
       INT64 real_time_now = tv.tv_sec * 1000000 + tv.tv_usec;
@@ -1588,7 +1589,7 @@ static void check_threads(struct callback *cb, void *arg, void * arg2)
 #endif
 #endif
 
-    GETTIMEOFDAY (&now);
+    ACCURATE_GETTIMEOFDAY (&now);
     if (now.tv_sec > last_time) {
       fprintf (stderr, "[%d:%f] check_threads: %lu calls, "
 	       "%lu clocks, %lu no advs, %lu yields"
diff --git a/src/time_stuff.h b/src/time_stuff.h
index 23c47292e1f86ce3767d85e1e7db6f3f48f59b4f..5d3e4c3d986e69e251a1619906324e1a73153d89 100644
--- a/src/time_stuff.h
+++ b/src/time_stuff.h
@@ -77,4 +77,28 @@ struct timeval
 };
 #endif
 
+PMOD_EXPORT extern struct timeval current_time;
+PMOD_EXPORT extern int current_time_invalid;
+
+#define INVALIDATE_CURRENT_TIME() do { current_time_invalid = 1; } while (0)
+#define UPDATE_CURRENT_TIME() do {					\
+	    GETTIMEOFDAY(&current_time);				\
+	    current_time_invalid = 0;					\
+	} while (0)
+#define ACCURATE_GETTIMEOFDAY(X) do {					\
+	    UPDATE_CURRENT_TIME();					\
+	    *(X) = current_time;					\
+	} while (0)
+#define ACCURATE_GETTIMEOFDAY_RVAL(X, ___rval) do {			\
+	    (___rval) = GETTIMEOFDAY(&current_time);			\
+	    current_time_invalid = 0;					\
+	    *(X) = current_time;					\
+	} while (0)
+#define INACCURATE_GETTIMEOFDAY(X) do {					\
+	    /* unlikely() not available */				\
+	    if (!(current_time_invalid)) { }				\
+	    else UPDATE_CURRENT_TIME();					\
+	    *(X) = current_time;					\
+	} while (0)
+
 #endif