am 5d228392: am d24240fb: Merge "Fixed the pacing logic in bootchart data collection."

* commit '5d2283927a9527130cad15d33c1e2b360f4bd46f':
  Fixed the pacing logic in bootchart data collection.
diff --git a/init/bootchart.c b/init/bootchart.c
index f72fcaa..a514261 100644
--- a/init/bootchart.c
+++ b/init/bootchart.c
@@ -119,6 +119,18 @@
     }
 }
 
+static long long
+get_uptime_jiffies()
+{
+    char       buff[64];
+    long long  jiffies = 0;
+
+    if (proc_read("/proc/uptime", buff, sizeof(buff)) > 0)
+        jiffies = 100LL*strtod(buff,NULL);
+
+    return jiffies;
+}
+
 static void
 log_header(void)
 {
@@ -185,22 +197,11 @@
 do_log_uptime(FileBuff  log)
 {
     char  buff[65];
-    int   fd, ret, len;
+    int   len;
 
-    fd = open("/proc/uptime",O_RDONLY);
-    if (fd >= 0) {
-        int  ret;
-        ret = unix_read(fd, buff, 64);
-        close(fd);
-        buff[64] = 0;
-        if (ret >= 0) {
-            long long  jiffies = 100LL*strtod(buff,NULL);
-            int        len;
-            snprintf(buff,sizeof(buff),"%lld\n",jiffies);
-            len = strlen(buff);
-            file_buff_write(log, buff, len);
-        }
-    }
+    snprintf(buff,sizeof(buff),"%lld\n",get_uptime_jiffies());
+    len = strlen(buff);
+    file_buff_write(log, buff, len);
 }
 
 static void
@@ -376,3 +377,9 @@
     file_buff_done(log_procs);
     acct(NULL);
 }
+
+/* called to get time (in ms) used by bootchart */
+long long  bootchart_gettime( void )
+{
+    return 10LL*get_uptime_jiffies();
+}
diff --git a/init/bootchart.h b/init/bootchart.h
index 39d2d4f..ed65e8a 100644
--- a/init/bootchart.h
+++ b/init/bootchart.h
@@ -26,6 +26,7 @@
 extern int   bootchart_init(void);
 extern int   bootchart_step(void);
 extern void  bootchart_finish(void);
+extern long long  bootchart_gettime(void);
 
 # define BOOTCHART_POLLING_MS   200   /* polling period in ms */
 # define BOOTCHART_DEFAULT_TIME_SEC    (2*60)  /* default polling time in seconds */
diff --git a/init/init.c b/init/init.c
index bd1db7a..99474e6 100644
--- a/init/init.c
+++ b/init/init.c
@@ -65,6 +65,7 @@
 
 #if BOOTCHART
 static int   bootchart_count;
+static long long bootchart_time = 0;
 #endif
 
 static char console[32];
@@ -1147,11 +1148,29 @@
 
 #if BOOTCHART
         if (bootchart_count > 0) {
-            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
-                timeout = BOOTCHART_POLLING_MS;
-            if (bootchart_step() < 0 || --bootchart_count == 0) {
-                bootchart_finish();
-                bootchart_count = 0;
+            long long current_time;
+            int elapsed_time, remaining_time;
+
+            current_time = bootchart_gettime();
+            elapsed_time = current_time - bootchart_time;
+
+            if (elapsed_time >= BOOTCHART_POLLING_MS) {
+                /* count missed samples */
+                while (elapsed_time >= BOOTCHART_POLLING_MS) {
+                    elapsed_time -= BOOTCHART_POLLING_MS;
+                    bootchart_count--;
+                }
+                /* count may be negative, take a sample anyway */
+                bootchart_time = current_time;
+                if (bootchart_step() < 0 || bootchart_count <= 0) {
+                    bootchart_finish();
+                    bootchart_count = 0;
+                }
+            }
+            if (bootchart_count > 0) {
+                remaining_time = BOOTCHART_POLLING_MS - elapsed_time;
+                if (timeout < 0 || timeout > remaining_time)
+                    timeout = remaining_time;
             }
         }
 #endif