$OpenBSD: patch-misc_c,v 1.2 2004/03/06 02:41:00 naddy Exp $
--- misc.c.orig	1996-11-22 02:28:46.000000000 +0100
+++ misc.c	2004-03-06 02:03:24.000000000 +0100
@@ -89,8 +89,8 @@ void usleep(usec)
 #ifdef SYSV
 #ifdef __clipper__
     struct timeval tv;
-    tv.tv_sec=((usec)/1000);
-    tv.tv_usec=(((usec)%1000)*1000);
+    tv.tv_sec=((usec)/1000000);
+    tv.tv_usec=((usec)%1000000);
     select(1,NULL,NULL,NULL,&tv);
 #else
     poll((struct poll *) 0, (size_t) 0, usec / 1000);   /* ms resolution */
@@ -105,6 +105,68 @@ void usleep(usec)
 #endif
 
 #if NeedFunctionPrototypes
+static	int	kudelay(unsigned long count)
+#else
+static	int	kudelay(count)
+unsigned long count;
+#endif
+{
+    unsigned int	bluff = 1;
+
+    while( count-- != 0 )	/* this can hardly be "optimised out" */
+	bluff = (bluff ^ ((bluff & 1) * 0x6110)) >> 1;
+
+    return( bluff );
+}
+
+#if NeedFunctionPrototypes
+static	void kusleep(unsigned long usec)
+#else
+static	void kusleep(usec)
+        unsigned long usec;
+#endif
+{
+    static float	kuliber_time = 0.0;
+    static float	kuliber_count = 0.0;
+    static unsigned long	kutimerswap = (1000000 / 15);
+    struct timeval	st, et;
+    long		gap;
+    unsigned long	count;
+
+    if( kuliber_time == 0.0 )
+    {
+	count = 0x1000;		/* calibrate delay loop */
+	gettimeofday(&st, NULL);
+
+	while( True )
+	{
+	    kudelay( count );
+	    count = (count << 1);
+	    gettimeofday(&et, NULL);
+	    gap = (((et.tv_sec - st.tv_sec) * 1000000) +
+			(et.tv_usec - st.tv_usec) );
+
+	    if( gap > 400*1000 )
+		break;
+	}
+
+	kuliber_time = (float)(gap/4);
+	kuliber_count = (float)(((count-1)&~0xFFF)>>2);
+    }
+
+    if( usec > kutimerswap )
+    {
+	kutimerswap = (1000000 / 30);
+	usleep( usec );		/* using usleep() for low resolution only */
+    }
+    else
+    {
+	kutimerswap = (1000000 / 15);
+	kudelay( (unsigned long)(kuliber_count*((float)usec/kuliber_time)) );
+    }
+}
+
+#if NeedFunctionPrototypes
 void sleepSync(Display *display, unsigned long ms)
 #else
 void sleepSync(display, ms)
@@ -112,27 +174,85 @@ void sleepSync(display, ms)
     unsigned long ms;
 #endif
 {
-    struct timeval st, et;
-    long SyncTime;
-    static unsigned long accu;
+    static long		Expected_time = 0;
+    static long		Ref_sec = 0;
+    static long		Ref_usec = 0;
+    static long		Sleeping_time = 0;
+    static int		PLL_filter = 0;
+    struct timeval	st;
+    long		elapsed;
+    long		dodelay;
+    float		x;
 
-    gettimeofday(&st, NULL);
     XSync(display, False);
-    gettimeofday(&et, NULL);
 
-    SyncTime = (((et.tv_sec - st.tv_sec) * 1000) +
-               ((et.tv_usec - st.tv_usec) / 1000) );
+    gettimeofday(&st, NULL);
 
-/*    if ((ms) > ((1000 / 60) + SyncTime))
-        usleep(ms - SyncTime);
-*/
-    if ((ms + accu) > ((1000 / 30) + SyncTime)) 
+    if( Ref_sec == 0 )
     {
-        usleep(ms +accu - SyncTime);
-        accu = 0;
+	Ref_sec = st.tv_sec;	/* take the initial reference point */
+	Ref_usec = st.tv_usec;
+	Sleeping_time = ms * 1000;
     }
-    else if (ms > SyncTime)
-       accu += (ms - SyncTime);
+
+    elapsed = (st.tv_sec - Ref_sec) * 1000000 + (st.tv_usec - Ref_usec);
+    dodelay = Sleeping_time;
+
+    if( PLL_filter > 0 && elapsed != 0 )	/* Phase lock loop */
+    {
+	dodelay = Expected_time + Sleeping_time - elapsed;
+
+	if( dodelay < 0 )
+	{
+	    dodelay = 0; PLL_filter--;
+	}
+	else
+	    if( dodelay > 2*Sleeping_time )
+	    {
+		dodelay = 2*Sleeping_time; PLL_filter--;
+	    }
+	    else
+		PLL_filter = 3;
+
+	if( elapsed > 40*Sleeping_time && Expected_time > 40*Sleeping_time )
+	{
+	    elapsed -= 20*Sleeping_time; /* Ref. point shouldn't be far away*/
+	    Expected_time -= 20*Sleeping_time;
+	    Ref_usec += 20*Sleeping_time;
+	    Ref_sec += Ref_usec/1000000; Ref_usec %= 1000000;
+	}
+    }
+
+    if( PLL_filter <= 0 && elapsed > 40000 )	/* Frequency lock loop */
+    {
+	/* feedback filter */
+	x = 0.5 + 0.5 * (float)Expected_time / (float)elapsed;
+
+	if( x < 0.966 )	/* Acceleration must be strongly limited */
+	    x = 0.966;
+
+	if( x > 2.0 )
+	    x = 2.0;
+
+	Sleeping_time = (long)((float)Sleeping_time * x);
+
+	if( Sleeping_time < 500 )
+	    Sleeping_time = 500;
+
+	if( x > 0.99 && x < 1.01 && Sleeping_time > ms*500 )
+	    PLL_filter = -1 - 4*PLL_filter; /* locked - it's time to try PLL */
+	else
+	    PLL_filter = 0;
+
+	Ref_sec = st.tv_sec;
+	Ref_usec = st.tv_usec;
+	Expected_time = 0;
+	dodelay = Sleeping_time;
+    }
+
+    kusleep( dodelay );
+
+    Expected_time += ms * 1000;
 }
 
 #if NeedFunctionPrototypes
@@ -427,7 +547,7 @@ char *GetHomeDir()
      */
 
     if ((ptr = getenv("HOME")) != NULL)
-        (void) strcpy(dest, ptr);
+        (void) strlcpy(dest, ptr, sizeof(dest));
     else
     {
         /* HOME variable is not present so get USER var */
@@ -441,7 +561,7 @@ char *GetHomeDir()
         }
 
         if (pw)
-            (void) strcpy(dest, pw->pw_dir);
+            (void) strlcpy(dest, pw->pw_dir, sizeof(dest));
         else
             *dest = '\0';
     }
