File hwclock-cpufriendly.diff of Package util-linux

From: Kurt Garloff <garloff@suse.de>
Subject: Avoid busy waiting for too long
References: bnc441106

hwclock does up to 1s busy waiting for a hwclock tick, eating precious
CPU cycles.

Instead do a loop with usleeps(0.02s) to get a rough idea on where the
tick is, then only start busy waiting 0.92 s later. This results in
~0.1s CPU time as opposed to 0.5s average before.
(The combination of --adjust followed by --hctosys would unfortunately
 have an average of 1.5s before, we're now down to 0.2s CPU time.)

Downside: We take 1s longer to complete in average.

[Patch 2/4]

Index: util-linux-ng-2.14.1/hwclock/rtc.c
===================================================================
--- util-linux-ng-2.14.1.orig/hwclock/rtc.c
+++ util-linux-ng-2.14.1/hwclock/rtc.c
@@ -170,9 +170,9 @@ do_rtc_read_ioctl(int rtc_fd, struct tm 
 	return 0;
 }
 
 static int
-busywait_for_rtc_clock_tick(const int rtc_fd) {
+busywait_for_rtc_clock_tick(const int rtc_fd, const int pause) {
 /*----------------------------------------------------------------------------
    Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
    we see it.
 -----------------------------------------------------------------------------*/
@@ -180,8 +180,11 @@ busywait_for_rtc_clock_tick(const int rt
     /* The time when we were called (and started waiting) */
   struct tm nowtime;
   int i;  /* local loop index */
   int rc;
+  int maxctr = 1000000;
+  if (pause)
+	  maxctr = 2000000/pause;
 
   if (debug)
     printf(_("Waiting in loop for time from %s to change\n"),
 	   rtc_dev_name);
@@ -196,13 +199,16 @@ busywait_for_rtc_clock_tick(const int rt
      */
   for (i = 0;
        (rc = do_rtc_read_ioctl(rtc_fd, &nowtime)) == 0
         && start_time.tm_sec == nowtime.tm_sec;
-       i++)
-    if (i >= 1000000) {
+       i++) {
+    if (i >= maxctr) {
       fprintf(stderr, _("Timed out waiting for time change.\n"));
       return 2;
     }
+    if (pause)
+      usleep(pause);
+  }
 
   if (rc)
     return 3;
   return 0;
@@ -239,9 +245,16 @@ int ret;
          */
       if (debug)
 	      printf(_("%s does not have interrupt functions. "),
 		     rtc_dev_name);
-      ret = busywait_for_rtc_clock_tick(rtc_fd);
+      /* Poll with sleeps of 20ms */
+      ret = busywait_for_rtc_clock_tick(rtc_fd, 20000);
+      /* Now we're between 0 and ~40ms after the tick, sleep 920ms */
+      usleep(920000);
+      /* Real busy-waiting, but only for max. 80ms, unless we woke up very late.
+       * TODO: We could check for this and do another usleep then, for now
+       *  just deal with the almost 1s busy waiting in this unlikely case. */
+      ret = busywait_for_rtc_clock_tick(rtc_fd, 0);
     } else if (rc == 0) {
 #ifdef Wait_until_update_interrupt
       unsigned long dummy;
 
openSUSE Build Service is sponsored by