]> granicus.if.org Git - sysstat/blobdiff - sa_wrap.c
Update README.md file
[sysstat] / sa_wrap.c
index fc2dfe20496de98270c2b0dc1563946c7ee4746e..c7577269eaab555f7da5601748f1da2bcf38eb16 100644 (file)
--- a/sa_wrap.c
+++ b/sa_wrap.c
@@ -1,6 +1,6 @@
 /*
  * sysstat - sa_wrap.c: Functions used in activity.c
- * (C) 1999-2017 by Sebastien GODARD (sysstat <at> orange.fr)
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -23,9 +23,7 @@
 #include <string.h>
 
 #include "sa.h"
-#include "rd_stats.h"
 #include "count.h"
-#include "rd_sensors.h"
 
 extern unsigned int flags;
 extern struct record_header record_hdr;
@@ -1060,6 +1058,53 @@ __read_funct_t wrap_read_fchost(struct activity *a)
        return;
 }
 
+/*
+ ***************************************************************************
+ * Look for online CPU and fill corresponding bitmap.
+ *
+ * IN:
+ * @bitmap_size        Size of the CPU bitmap.
+ *
+ * OUT:
+ * @online_cpu_bitmap
+ *             CPU bitmap which has been filled.
+ *
+ * RETURNS:
+ * Number of CPU for which statistics have to be be read.
+ * 1 means CPU "all", 2 means CPU "all" and CPU 0, etc.
+ * Or -1 if the buffer was too small and needs to be reallocated.
+ ***************************************************************************
+ */
+int get_online_cpu_list(unsigned char online_cpu_bitmap[], int bitmap_size)
+{
+       FILE *fp;
+       char line[8192];
+       int proc_nr = -2;
+
+       if ((fp = fopen(STAT, "r")) == NULL)
+               return 0;
+
+       while (fgets(line, sizeof(line), fp) != NULL) {
+
+               if (!strncmp(line, "cpu ", 4))
+                       continue;
+
+               if (!strncmp(line, "cpu", 3)) {
+                       sscanf(line + 3, "%d", &proc_nr);
+
+                       if ((proc_nr + 1 > bitmap_size) || (proc_nr < 0)) {
+                               fclose(fp);
+                               /* Return -1 or 0 */
+                               return ((proc_nr >= 0) * -1);
+                       }
+                       online_cpu_bitmap[proc_nr >> 3] |= 1 << (proc_nr & 0x07);
+               }
+       }
+
+       fclose(fp);
+       return proc_nr + 2;
+}
+
 /*
  ***************************************************************************
  * Read softnet statistics.
@@ -1076,15 +1121,37 @@ __read_funct_t wrap_read_softnet(struct activity *a)
        struct stats_softnet *st_softnet
                = (struct stats_softnet *) a->_buf0;
        __nr_t nr_read = 0;
+       static unsigned char *online_cpu_bitmap = NULL;
+       static int bitmap_size = 0;
 
        /* Read softnet stats */
        do {
-               nr_read = read_softnet(st_softnet, a->nr_allocated);
+               /* Allocate bitmap for online CPU */
+               if (bitmap_size < a->nr_allocated) {
+                       if ((online_cpu_bitmap = (unsigned char *) realloc(online_cpu_bitmap,
+                                                                          BITMAP_SIZE(a->nr_allocated))) == NULL) {
+                               nr_read = 0;
+                               break;
+                       }
+                       bitmap_size = a->nr_allocated;
+               }
+               memset(online_cpu_bitmap, 0, BITMAP_SIZE(a->nr_allocated));
+
+               /* Get online CPU list */
+               nr_read = get_online_cpu_list(online_cpu_bitmap, bitmap_size);
+               if (!nr_read)
+                       break;
 
                if (nr_read < 0) {
                        /* Buffer needs to be reallocated */
                        st_softnet = (struct stats_softnet *) reallocate_buffer(a);
                }
+               else {
+                       if (!read_softnet(st_softnet, a->nr_allocated, online_cpu_bitmap)) {
+                               /* File /proc/net/softnet doesn't exist */
+                               nr_read = 0;
+                       }
+               }
        }
        while (nr_read < 0);