gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r1378 - GNUnet/src/util


From: grothoff
Subject: [GNUnet-SVN] r1378 - GNUnet/src/util
Date: Sun, 10 Jul 2005 16:16:09 -0700 (PDT)

Author: grothoff
Date: 2005-07-10 16:16:05 -0700 (Sun, 10 Jul 2005)
New Revision: 1378

Modified:
   GNUnet/src/util/statuscalls.c
   GNUnet/src/util/statuscallstest.c
Log:
trying to fix 766 -- please check Win32 ports

Modified: GNUnet/src/util/statuscalls.c
===================================================================
--- GNUnet/src/util/statuscalls.c       2005-07-10 21:14:49 UTC (rev 1377)
+++ GNUnet/src/util/statuscalls.c       2005-07-10 23:16:05 UTC (rev 1378)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003 Christian Grothoff (and other contributing authors)
+     (C) 2001, 2002, 2003, 2005 Christian Grothoff (and other contributing 
authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -26,11 +26,6 @@
  * @author Igor Wronsky
  *
  * Status calls implementation for load management.
- *
- * Todo:
- * - determining load between calls to /proc might be made
- *   interface specific
- * - port to other platforms
  */
 
 #include "platform.h"
@@ -55,38 +50,71 @@
 
 #define DEBUG_STATUSCALLS NO
 
-/* where to read network interface information from
-   under Linux */
+/**
+ * where to read network interface information from
+ * under Linux 
+ */
 #define PROC_NET_DEV "/proc/net/dev"
 
 typedef struct {
+  char * name;
   unsigned long long last_in;
   unsigned long long last_out;
 } NetworkStats;
 
-static char ** interfacePtrs = NULL; /* Pointer to the name of each interface, 
has numInterfaces entries */
-static int numInterfaces = 0; /* how many interfaces do we have? */
+/**
+ * Traffic counter for only gnunetd traffic.
+ */
+static NetworkStats globalTrafficBetweenProc;
 
-/* configuration */
+/**
+ * tracking 
+ */
+static NetworkStats * ifcs; 
+
+/**
+ * how many interfaces do we have? 
+ */
+static int ifcsSize; 
+
+/**
+ * Current load of the machine, -1 for error
+ */
+static int currentLoad;
+
+/**
+ * Maximum bandwidth (down) as per config.
+ */
 static int maxNetDownBPS;
+
+/**
+ * Maximum bandwidth (up) as per config.
+ */
 static int maxNetUpBPS;
-static int maxCPULoad;                    /* in percent of 1 CPU */
-static double lastNetResultUp = -1;   /* the max upstream load we saw last 
time */
-static double lastNetResultDown = -1; /* the max dnstream load we saw last 
time */
-static cron_t lastnettimeUp =  0;  /* when did we check last time? */
-static cron_t lastnettimeDown =  0;  /* when did we check last time? */
-static int useBasicMethod = YES;   /* how to measure traffic */
 
-/* tracking */
-static NetworkStats * last_net_results; /* has numInterfaces entries */
+/**
+ * Maximum load as per config.
+ */
+static int maxCPULoad;
 
-/* for async configuration update! */
+/**
+ * How to measure traffic (YES == only gnunetd,
+ * NO == try to include all apps)
+ */
+static int useBasicMethod = YES;  
+
+/**
+ * Lock.
+ */
 static Mutex statusMutex;
 
-static NetworkStats globalTrafficBetweenProc;
-
 static int initialized_ = NO;
 
+#ifdef LINUX
+static FILE * proc_stat;
+static FILE * proc_net_dev;
+#endif
+
 /**
  * Increment the number of bytes sent.  Transports should use this
  * so that statuscalls module can measure gnunet traffic usage between
@@ -112,700 +140,158 @@
   MUTEX_UNLOCK(&statusMutex);
 }
 
-
-static void cronLoadUpdate(void * unused) {
-  getCPULoad();
-  getNetworkLoadUp();
-  getNetworkLoadDown();
-}
-
 /**
- * Re-read the configuration for statuscalls.
+ * Reset the traffic counters for GNUnet traffic between
+ * systemwide readings.
  */
-static void resetStatusCalls() {
-  char * interfaces;
-  char * ifcs;
-  int start;
-
-  MUTEX_LOCK(&statusMutex);
-  interfaces
-    = getConfigurationString("LOAD",
-                            "INTERFACES");
-  ifcs = interfaces;
-  /* fail if config-file is incomplete */
-  if (interfaces == NULL) {
-    LOG(LOG_ERROR,
-       _("No network interfaces defined in configuration section '%s' under 
'%s'!\n"),
-       "LOAD",
-       "INTERFACES");
-    numInterfaces = 0;
-  }
-       else {
-               /* The string containing the interfaces is formatted in the 
following way:
-                * each comma is replaced by '\0' and the pointers to the 
beginning of every
-                * interface are stored
-                */
-               numInterfaces = 0;
-               start = YES;
-               while (1) {
-                       if (*interfaces == '\0') {
-                               if (start == NO)
-                                       numInterfaces++;
-                                       break;
-                               }
-                               if ( ((*interfaces>='a') && (*interfaces<='z')) 
||
-                                       ((*interfaces>='A') && 
(*interfaces<='Z')) ||
-                                       ((*interfaces>='0') && 
(*interfaces<='9')) ) {
-
-                                       start = NO;
-                                       } else {
-                                               if (*interfaces != ',')
-                                                       errexit(_("Interfaces 
string (%s) in configuration section '%s' under '%s' is malformed.\n"),
-                                                               ifcs,
-                                                               "LOAD",
-                                                               "INTERFACES");
-                                               if (start == NO) {
-                                                       start = YES;
-                                                       numInterfaces++;
-                                               }
-                                       }
-                               interfaces++;
-                       }
-                       if (numInterfaces <= 0) {
-                               LOG(LOG_ERROR,
-                                       _("No network interfaces specified in 
the configuration file in section '%s' under '%s'.\n"),
-                                       "LOAD",
-                                       "INTERFACES");
-                       }
-                       else {
-                               if (interfacePtrs != NULL) {
-                                       FREE(interfacePtrs[0]);
-                                       FREE(interfacePtrs);
-                       }
-                       interfacePtrs = MALLOC(sizeof(char*) * numInterfaces);
-                       last_net_results = MALLOC(sizeof(NetworkStats) * 
numInterfaces);
-                       memset(last_net_results, 0,
-                               sizeof(NetworkStats) * numInterfaces);
-               
-                       /* 2nd pass, this time remember the positions */
-                       interfaces = ifcs;
-                       numInterfaces = 0;
-                       start = YES;
-                       while (1) {
-                               if (*interfaces=='\0') {
-                                       if (start == NO)
-                                               numInterfaces++;
-                                       break;
-                               }
-                               if ( ((*interfaces>='a') && (*interfaces<='z')) 
||
-                                       ((*interfaces>='A') && 
(*interfaces<='Z')) ||
-                                       ((*interfaces>='0') && 
(*interfaces<='9')) ) {
-                     
-                     if (start == YES) {
-                       start = NO;
-                       interfacePtrs[numInterfaces] = interfaces;      
-                     }
-                               } else {
-                                       if (start == NO) {
-                                               start = YES;
-                                               *interfaces = '\0';     
-                                               numInterfaces++;
-                                       }
-                               }
-                               interfaces++;
-                       }
-               }
-       }
-
-  useBasicMethod
-    = testConfigurationString("LOAD",
-                             "BASICLIMITING",
-                             "YES");
-  maxNetDownBPS
-    = getConfigurationInt("LOAD",
-                         "MAXNETDOWNBPSTOTAL");
-  if (maxNetDownBPS == 0)
-    maxNetDownBPS = 50000;
-  maxNetUpBPS
-    = getConfigurationInt("LOAD",
-                         "MAXNETUPBPSTOTAL");
-  if (maxNetUpBPS == 0)
-    maxNetUpBPS = 50000;
-  maxCPULoad
-    = getConfigurationInt("LOAD",
-                         "MAXCPULOAD");
-  if (maxCPULoad == 0)
-    maxCPULoad = 100;
-  MUTEX_UNLOCK(&statusMutex);
+static void resetBetweenProc() {
+  globalTrafficBetweenProc.last_in = 0;
+  globalTrafficBetweenProc.last_out = 0;
 }
 
-#ifdef LINUX
-static FILE * proc_stat = NULL;
-#endif
-
-/**
- * The basic usage meter considers only gnunetd traffic.
- */
-static int networkUsageBasicUp() {
-  cron_t now, elapsedTime;
-  double upUsage;
-  double etc;
-
-  MUTEX_LOCK(&statusMutex);
-  /* If called less than 1 seconds ago, calc average
-     between avg. traffic of last second and the additional
-     gained traffic.  If more than 1 second between calls,
-     set the avg bytes/sec as the usage of last second. */
-  cronTime(&now);
-  elapsedTime = now - lastnettimeUp;
-  etc = (double) elapsedTime / (double) cronSECONDS;
-  if (elapsedTime < cronSECONDS) {
-    upUsage = ( ( lastNetResultUp +
-                 ((double)globalTrafficBetweenProc.last_out * etc) )
-               / (1.0 + etc) );
-  } else {
-    upUsage = (double)globalTrafficBetweenProc.last_out / etc;
-    lastNetResultUp = upUsage;
-    globalTrafficBetweenProc.last_out = 0;
-    lastnettimeUp = now;
-  }
-  MUTEX_UNLOCK(&statusMutex);
-  return (int)(100.0 * ((double)upUsage / (double)maxNetUpBPS));
-}
-
-/**
- * The basic usage meter considers only gnunetd traffic.
- */
-static int networkUsageBasicDown() {
-  cron_t now, elapsedTime;
-  double downUsage;
-  double etc;
-
-  MUTEX_LOCK(&statusMutex);
-  /* If called less than 1 seconds ago, calc average
-     between avg. traffic of last second and the additional
-     gained traffic. If more than 1 second between calls,
-     set the avg bytes/sec as the usage of last second. */
-  cronTime(&now);
-  elapsedTime = now - lastnettimeDown;
-  etc = (double) elapsedTime / (double) cronSECONDS;
-  if (elapsedTime < cronSECONDS) {
-    downUsage = ( ( lastNetResultDown +
-                   ((double)globalTrafficBetweenProc.last_in * etc) )
-                 / (1.0 + etc) );
-  } else {
-    downUsage = (double)globalTrafficBetweenProc.last_in / etc;
-    lastNetResultDown = downUsage;
-    globalTrafficBetweenProc.last_in = 0;
-    lastnettimeDown = now;
-  }
-  MUTEX_UNLOCK(&statusMutex);
-  return (int)(100.0 * (double)downUsage / (double)maxNetDownBPS);
-}
-
-/**
- * The advanced usage meter takes into account all network traffic.
- * This might be problematic on systems where the same interface
- * can have different capabilities for different types of traffic
- * (like support for very fast local traffic but capable of
- * handling only small-scale inet traffic).
- */
-static int networkUsageAdvancedDown() {
 #define MAX_PROC_LINE 5000
-  char line[MAX_PROC_LINE];
-  unsigned long long rxnew, txnew;
-  unsigned long long rxdiff;
-  int i=0;
-  int ifnum;
-  cron_t now, elapsedtime;
 
+static void updateInterfaceTraffic() {
 #ifdef LINUX
-  FILE * proc_net_dev;
+  char line[MAX_PROC_LINE];
+  unsigned long long rxnew;
+  unsigned long long txnew;
   char * data;
-#else
-  FILE * command;
-#endif
+  int i;
+  int found;
 
   MUTEX_LOCK(&statusMutex);
-
-  /* first, make sure maxNetDownBPS is not 0, we don't want
-     to divide by 0, really. */
-  if (maxNetDownBPS == 0) {
-    lastNetResultDown = -1;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-
-  /* If we checked /proc less than 2 seconds ago, don't do
-     it again, but add internal gnunet traffic increments */
-  cronTime(&now);
-  elapsedtime = now - lastnettimeDown;
-  if (elapsedtime == 0) {
-    MUTEX_UNLOCK(&statusMutex);
-    return (int) lastNetResultDown;
-  }
-  if (elapsedtime < 2 * cronSECONDS) {
-    /* Only take additional gnunetd traffic into account, don't try to
-       measure other *system* traffic more frequently than every 2s */
-    double gnunetBPS;
-    double gnunetLOAD;
-    int ret;
-
-    gnunetBPS
-      = (cronMILLIS/cronSECONDS) * globalTrafficBetweenProc.last_in / 
elapsedtime;
-    gnunetLOAD
-      = 100 * gnunetBPS / maxNetDownBPS;
-    /* weigh last global measurement and gnunetd load,
-       with 100% global measurement at first and 50/50 mix
-       just before we take the next measurement */
-    ret = ( (2 * cronSECONDS * lastNetResultDown + elapsedtime * gnunetLOAD) /
-           (2 * cronSECONDS + elapsedtime));
-    MUTEX_UNLOCK(&statusMutex);
-    return ret;
-  }
-
-  globalTrafficBetweenProc.last_in = 0;
-  lastnettimeDown = now;
-
-  /* ok, full program... */
-  rxdiff = 0;
-
-#ifdef LINUX
-  proc_net_dev = fopen(PROC_NET_DEV, "r");
-  /* Try to open the file*/
-  if (NULL == proc_net_dev) {
-    LOG_FILE_STRERROR(LOG_ERROR, "fopen", PROC_NET_DEV);
-    MUTEX_UNLOCK(&statusMutex);
-    lastNetResultDown = -1;
-    return -1;
-  }
-  ifnum = 0;
-  /* Parse the line matching the interface ('eth0') */
-  while ( (!feof(proc_net_dev)) &&
-         ( ifnum < numInterfaces) ) {
-    fgets(line,
-         MAX_PROC_LINE,
-         proc_net_dev);
-
-    for (i=0;i<numInterfaces;i++) {
-      if (NULL != strstr(line, interfacePtrs[i]) ) {
-       data = (char*)strchr(line, ':');
-       data++; 
-       if (SSCANF(data,
-                  "%llu %*s %*s %*s %*s %*s %*s %*s %llu",
-                 &rxnew, &txnew) != 2) {
-         fclose(proc_net_dev); 
-         errexit(_("Failed to parse interface data from '%s' at %s:%d.\n"),
-                 PROC_NET_DEV, __FILE__, __LINE__);
-       }
-       if ( (signed long long)(rxnew - last_net_results[ifnum].last_in) > 0) {
-         /* ignore the result if it is currently overflowing */
-         rxdiff += rxnew - last_net_results[ifnum].last_in;
-       }
-       last_net_results[ifnum].last_in = rxnew;
-       ifnum++;
+  if (proc_net_dev != NULL) {
+    found = 0;
+    rewind(proc_net_dev);
+    fflush(proc_net_dev);
+    /* Parse the line matching the interface ('eth0') */
+    while (! feof(proc_net_dev) ) {
+      if (NULL == fgets(line,
+                       MAX_PROC_LINE,
+                       proc_net_dev))
        break;
+      for (i=0;i<ifcsSize;i++) {
+       if (NULL != strstr(line, ifcs[i].name) ) {
+         data = strchr(line, ':');
+         if (data == NULL)
+           continue;
+         data++;       
+         if (2 != SSCANF(data,
+                         "%llu %*s %*s %*s %*s %*s %*s %*s %llu",
+                         &rxnew, 
+                         &txnew)) {
+           LOG(LOG_ERROR,
+               _("Failed to parse interface data from '%s' at %s:%d.\n"),
+               PROC_NET_DEV, 
+               __FILE__, 
+               __LINE__);
+           continue;
+         }     
+         ifcs[i].last_in  = rxnew;
+         ifcs[i].last_out = txnew;
+         resetBetweenProc();
+         break;
+       }
       }
     }
   }
-  fclose(proc_net_dev);
-#elif MINGW
-  /* Win 98 and NT SP 4 */
-  if (GNGetIfEntry)
-  {
-    for (ifnum=0; ifnum < numInterfaces; ifnum++)
-    {
-      PMIB_IFTABLE pTable;
-      DWORD dwIfIdx;
-      int found = 0;
-
-      EnumNICs(&pTable, NULL);
-
-      for(dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
-        unsigned long long l;
-        BYTE bPhysAddr[MAXLEN_PHYSADDR];
-
-        l = _atoi64(interfacePtrs[i]);
-
-        memset(bPhysAddr, 0, MAXLEN_PHYSADDR);
-        memcpy(bPhysAddr,
-          pTable->table[dwIfIdx].bPhysAddr,
-          pTable->table[dwIfIdx].dwPhysAddrLen);
-
-        if (memcmp(bPhysAddr, &l, sizeof(l)) == 0) {
-          found = 1;
-          break;
-        }
-      }
-
-      if (found)
-        rxnew = pTable->table[dwIfIdx].dwInOctets;
-      else
-        rxnew = last_net_results[ifnum].last_in;
-
-      rxdiff += rxnew - last_net_results[ifnum].last_in;
-      last_net_results[ifnum].last_in = rxnew;
-
-      GlobalFree(pTable);
-    }
-  }
-  else
-  {
-    /* Win 95 */
-    int iLine = 0;
-
-    if ( ( command = popen("netstat -e", "rt") ) == NULL )
-    {
-      LOG_FILE_STRERROR(LOG_ERROR, "popen", "netstat -e");
-      lastNetResultDown = -1;
-      MUTEX_UNLOCK(&statusMutex);
-      return -1;
-    }
-    while (!feof(command))
-    {
-      fgets(line, MAX_PROC_LINE, command);
-      if (iLine == 1)
-      {
-        char szDummy[100];
-        sscanf("%s%i%i", szDummy, &rxnew, &txnew);
-             rxdiff += rxnew - last_net_results[0].last_in;    
-             last_net_results[0].last_in = rxnew;
-      }
-      iLine++;
-    }
-    pclose(command);
-  }
-#else
-  if (1) {
-    MUTEX_UNLOCK(&statusMutex);
-    return 0;
-  }
-  if ( ( command = popen("netstat -n -f inet -i", "r") ) == NULL ) {
-    LOG_FILE_STRERROR(LOG_ERROR, "popen", "netstat -n -f inet -i");
-    lastNetResultDown = -1;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  ifnum = 0;
-  while ( (!feof(command)) &&
-         (ifnum < numInterfaces ) ) {
-    fgets(line,
-         MAX_PROC_LINE,
-         command);
-    for (i=0; i < numInterfaces; i++) {
-      if ( NULL != strstr(line, interfacePtrs[i]) ) {
-       if(SSCANF(line, "%*s %*s %*s %*s %llu %*s %llu %*s %*s",
-                 &rxnew, &txnew) != 2 ) {
-         pclose(command);
-         errexit(_("Failed to parse interface data '%s' output at %s:%d.\n"),
-                 "netstat -n -f inet -i",
-                 __FILE__, __LINE__);
-       }
-       if ( (signed long long)(rxnew - last_net_results[ifnum].last_in) > 0) {
-         /* ignore the result if it is currently overflowing */
-         rxdiff += rxnew - last_net_results[ifnum].last_in;
-       }
-       last_net_results[ifnum].last_in = rxnew;
-       ifnum++;
-       break;
-      } /* if match */
-    }  /* for all interfaces, find match */
-  } /* while: for all lines in proc */
-  pclose(command);
-#endif
-
-  lastNetResultDown
-    = (100 * rxdiff * cronSECONDS) / (elapsedtime * maxNetDownBPS);
-       
   MUTEX_UNLOCK(&statusMutex);
-  return (int) lastNetResultDown;
-}
-
-
-/**
- * The advanced usage meter takes into account all network traffic.
- * This might be problematic on systems where the same interface
- * can have different capabilities for different types of traffic
- * (like support for very fast local traffic but capable of
- * handling only small-scale inet traffic).
- */
-static int networkUsageAdvancedUp() {
-#define MAX_PROC_LINE 5000
+    
+#elif MINGW
+  int i;
+  PMIB_IFTABLE pTable;
+  DWORD dwIfIdx;
+  unsigned long long l;
+  BYTE bPhysAddr[MAXLEN_PHYSADDR];
+  int iLine = 0;
   char line[MAX_PROC_LINE];
-  unsigned long long rxnew, txnew;
-  unsigned long long txdiff;
-  int i=0;
-  int ifnum;
-  cron_t now, elapsedtime;
-
-#ifdef LINUX
-  FILE * proc_net_dev;
-  char * data;
-#else
   FILE * command;
-#endif
 
   MUTEX_LOCK(&statusMutex);
-
-  /* first, make sure maxNetUpBPS is not 0, we don't want
-     to divide by 0, really. */
-  if (maxNetUpBPS == 0) {
-    lastNetResultUp = -1;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-
-  /* If we checked /proc less than 2 seconds ago, don't do
-     it again, but add internal gnunet traffic increments */
-  cronTime(&now);
-  elapsedtime = now - lastnettimeUp;
-  if (elapsedtime == 0) {
-    MUTEX_UNLOCK(&statusMutex);
-    return (int) lastNetResultUp;
-  }
-
-  if (elapsedtime < 2 * cronSECONDS) {
-    /* Only take additional gnunetd traffic into account, don't try to
-       measure other *system* traffic more frequently than every 2s */
-    double gnunetBPS;
-    double gnunetLOAD;
-    int ret;
-
-    gnunetBPS
-      = (cronMILLIS/cronSECONDS) * globalTrafficBetweenProc.last_out / 
elapsedtime;
-    gnunetLOAD
-      = 100 * gnunetBPS / maxNetUpBPS;
-    /* weigh last global measurement and gnunetd load,
-       with 100% global measurement at first and 50/50 mix
-       just before we take the next measurement */
-    ret = ( (2 * cronSECONDS * lastNetResultUp + elapsedtime * gnunetLOAD) /
-           (2 * cronSECONDS + elapsedtime));
-    MUTEX_UNLOCK(&statusMutex);
-    return ret;
-  }
-
-  globalTrafficBetweenProc.last_out = 0;
-  lastnettimeUp = now;
-
-  /* ok, full program... */
-  txdiff = 0;
-
-#ifdef LINUX
-  proc_net_dev = fopen(PROC_NET_DEV, "r");
-  /* Try to open the file*/
-  if (NULL == proc_net_dev) {
-    LOG_FILE_STRERROR(LOG_ERROR, "fopen", PROC_NET_DEV);
-    MUTEX_UNLOCK(&statusMutex);
-    lastNetResultUp = -1;
-    return -1;
-  }
-  ifnum = 0;
-  /* Parse the line matching the interface ('eth0') */
-  while ( (!feof(proc_net_dev)) &&
-         ( ifnum < numInterfaces) ) {
-    fgets(line,
-         MAX_PROC_LINE,
-         proc_net_dev);
-
-    for (i=0;i<numInterfaces;i++) {
-      if (NULL != strstr(line, interfacePtrs[i]) ) {
-       data = (char*)strchr(line, ':');
-       data++; 
-       if (SSCANF(data,
-                  "%llu %*s %*s %*s %*s %*s %*s %*s %llu",
-                 &rxnew, &txnew) != 2) {
-         fclose(proc_net_dev);
-         errexit(_("Failed to parse interface data from '%s' at %s:%d.\n"),
-                 PROC_NET_DEV, __FILE__, __LINE__);
-       }       
-       if ( (signed long long)(txnew - last_net_results[ifnum].last_out) > 0) {
-         /* ignore the result if it is currently overflowing */
-         txdiff += txnew - last_net_results[ifnum].last_out;
-       }
-       last_net_results[ifnum].last_out = txnew;
-       ifnum++;
-       break;
-      }
-    }
-  }
-  fclose(proc_net_dev);
-#elif MINGW
   /* Win 98 and NT SP 4 */
-  if (GNGetIfEntry)
-  {
-    for (ifnum=0; ifnum < numInterfaces; ifnum++)
-    {
-      PMIB_IFTABLE pTable;
-      DWORD dwIfIdx;
-      int found = 0;
+  if (GNGetIfEntry) {
+    EnumNICs(&pTable, NULL);
+    for (i=0;i<ifcsSize;i++) {
+      for (dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
+        l = _atoi64(ifcs[i]->name);
 
-      EnumNICs(&pTable, NULL);
-
-      for(dwIfIdx=0; dwIfIdx < pTable->dwNumEntries; dwIfIdx++) {
-        unsigned long long l;
-        BYTE bPhysAddr[MAXLEN_PHYSADDR];
-
-        l = _atoi64(interfacePtrs[i]);
-
-        memset(bPhysAddr, 0, MAXLEN_PHYSADDR);
+        memset(bPhysAddr,
+              0,
+              MAXLEN_PHYSADDR);
         memcpy(bPhysAddr,
-          pTable->table[dwIfIdx].bPhysAddr,
-          pTable->table[dwIfIdx].dwPhysAddrLen);
+              pTable->table[dwIfIdx].bPhysAddr,
+              pTable->table[dwIfIdx].dwPhysAddrLen);
 
-        if (memcmp(bPhysAddr, &l, sizeof(l)) == 0) {
-          found = 1;
+        if (0 == memcmp(bPhysAddr,
+                       &l, 
+                       sizeof(unsigned long long))) {
+         ifcs[i].last_in 
+           = pTable->table[dwIfIdx].dwInOctets;
+         ifcs[i].last_out 
+           = pTable->table[dwIfIdx].dwOutOctets;
+         resetBetweenProc();
           break;
         }
       }
-
-      if (found)
-        txnew = pTable->table[dwIfIdx].dwOutOctets;
-      else
-        txnew = last_net_results[ifnum].last_out;
-
-      txdiff += txnew - last_net_results[ifnum].last_out;
-      last_net_results[ifnum].last_out = txnew;
-
-      GlobalFree(pTable);
     }
-  }
-  else
-  {
-    /* Win 95 */
-    int iLine = 0;
-
-    if ((command = popen("netstat -e", "rt")) == NULL)
-    {
-      LOG_FILE_STRERROR(LOG_ERROR, "popen", "netstat -e");
-      lastNetResultUp = -1;
+    GlobalFree(pTable);
+  } else { /* Win 95 */
+    if ( ( command = popen("netstat -e", "rt") ) == NULL ) {
+      LOG_FILE_STRERROR(LOG_ERROR, 
+                       "popen", 
+                       "netstat -e");
       MUTEX_UNLOCK(&statusMutex);
-      return -1;
+      return;
     }
-    while (!feof(command))
-    {
-      fgets(line, MAX_PROC_LINE, command);
-      if (iLine == 1)
-      {
-        char szDummy[100];
-        sscanf("%s%i%i", szDummy, &rxnew, &txnew);
-             txdiff += txnew - last_net_results[0].last_out;   
-             last_net_results[0].last_out = txnew;
-      }
-      iLine++;
+    while (!feof(command)) {
+      if (NULL == fgets(line, 
+                       MAX_PROC_LINE, 
+                       command))
+       break;
+      /* PORT-ME: any way to do this per-ifc? */
+      if (iLine == 1) {
+        sscanf("%*s%i%i", 
+              &rxnew, 
+              &txnew);
+       ifcs[0].last_in 
+         = rxnew;
+       ifcs[0].last_out 
+         = txnew;
+       resetBetweenProc();
+       break;
+      } 
+      iline++;
     }
     pclose(command);
   }
+  MUTEX_UNLOCK(&statusMutex);
 #else
-  if (1) {
-    MUTEX_UNLOCK(&statusMutex);
-    return 0;
-  }
-  if ( ( command = popen("netstat -n -f inet -i", "r") ) == NULL ) {
-    LOG_FILE_STRERROR(LOG_ERROR, "popen", "netstat -n -f inet -i");
-    lastNetResultUp = -1;
-    MUTEX_UNLOCK(&statusMutex);
-    return -1;
-  }
-  ifnum = 0;
-  while ( (!feof(command)) &&
-         (ifnum < numInterfaces ) ) {
-    fgets(line,
-         MAX_PROC_LINE,
-         command);
-    for (i=0; i < numInterfaces; i++) {
-      if ( NULL != strstr(line, interfacePtrs[i]) ) {
-       if(SSCANF(line, "%*s %*s %*s %*s %llu %*s %llu %*s %*s",
-                 &rxnew, &txnew) != 2 ) {
-         pclose(command);
-         errexit(" reading interface data using netstat\n");
-       }
-       if ( (signed long long)(txnew - last_net_results[ifnum].last_out) > 0) {
-         /* ignore the result if it is currently overflowing */
-         txdiff += txnew - last_net_results[ifnum].last_out;
-       }
-       last_net_results[ifnum].last_out = txnew;
-       ifnum++;
-       break;
-      } /* if match */
-    }  /* for all interfaces, find match */
-  } /* while: for all lines in proc */
-  pclose(command);
+  /* PORT-ME! */
 #endif
-
-  lastNetResultUp
-    = (100 * txdiff * cronSECONDS) / (elapsedtime * maxNetUpBPS);
-       
-  MUTEX_UNLOCK(&statusMutex);
-  return (int) lastNetResultUp;
 }
 
 /**
- * The following routine returns the percentage of available used
- * bandwidth.  Example: If 81 is returned this means that 81% of the
- * network bandwidth of the host is consumed.  The method
- * initStatusCalls() should be called before this routine is invoked.
- * If there is an error the method returns -1.
- */
-int networkUsageUp() {
-  if (initialized_ == NO)
-    return -1;
-  if (useBasicMethod == YES)
-    return networkUsageBasicUp();
-  else
-    return networkUsageAdvancedUp();
-}
-
-/**
- * The following routine returns the percentage of available used
- * bandwidth.  Example: If 81 is returned this means that 81% of the
- * network bandwidth of the host is consumed.  The method
- * initStatusCalls() should be called before this routine is invoked.
- * If there is an error the method returns -1.
- */
-int networkUsageDown() {
-  if (initialized_ == NO)
-    return -1;
-  if (useBasicMethod == YES)
-    return networkUsageBasicDown();
-  else
-    return networkUsageAdvancedDown();
-}
-
-
-/**
- * The following routine returns a number between 0-100 (can be larger than 100
- * if the load is > 1) which indicates the percentage CPU usage.
+ * The following routine returns a number between 0-100 (can be larger
+ * than 100 if the load is > 1) which indicates the percentage CPU
+ * usage.
  *
  * Before its first invocation the method initStatusCalls() must be called.
  * If there is an error the method returns -1
  */
-int cpuUsage(){
-  static cron_t lastcputime = 0;
-  static int lastcpuresult = -1;
-  cron_t now, elapsedtime;
-#ifdef HAVE_GETLOADAVG
-  double loadavg;
-#endif
-
-  if (initialized_ == NO)
-    return -1;
-  MUTEX_LOCK(&statusMutex);
-  cronTime(&now);
-  elapsedtime = now - lastcputime;
-  if ( (elapsedtime < 10 * cronSECONDS) &&
-       (lastcpuresult != -1) ) {
-    MUTEX_UNLOCK(&statusMutex);
-    return lastcpuresult;
+static void updateCpuUsage(){
+  if (initialized_ == NO) {
+    currentLoad = -1;
+    return;
   }
-  lastcputime = now;
-
+  MUTEX_LOCK(&statusMutex);
+  
+#ifdef LINUX
   /* under linux, first try %idle/usage using /proc/stat;
      if that does not work, disable /proc/stat for the future
      by closing the file and use the next-best method. */
-#ifdef LINUX
   if (proc_stat != NULL) {
     static int last_cpu_results[4] = { 0, 0, 0, 0 };
-    int ret = -1;
     char line[128];
     int user_read, system_read, nice_read, idle_read;
     int user, system, nice, idle;
@@ -814,76 +300,75 @@
     /* Get the first line with the data */
     rewind(proc_stat);
     fflush(proc_stat);
-    if (fgets(line, 128, proc_stat)==NULL) {
-      LOG_FILE_STRERROR(LOG_ERROR, "fgets", "/proc/stat");
+    if (NULL == fgets(line, 128, proc_stat)) {
+      LOG_FILE_STRERROR(LOG_ERROR, 
+                       "fgets",
+                       "/proc/stat");
       fclose(proc_stat);
-      proc_stat = NULL;
+      proc_stat = NULL; /* don't try again */
     } else {
       if (sscanf(line, "%*s %i %i %i %i",
-                &user_read, &system_read, &nice_read,
+                &user_read, 
+                &system_read, 
+                &nice_read,
                 &idle_read) != 4) {
+       LOG_FILE_STRERROR(LOG_ERROR, 
+                         "fgets-sscanf",
+                         "/proc/stat");
        fclose(proc_stat);
-       LOG(LOG_ERROR,
-           _("Could not decoding file '%s' at %s:%d.\n"),
-           "/proc/stat",
-           __FILE__, __LINE__);
        proc_stat = NULL; /* don't try again */
       } else {
-
        /* Store the current usage*/
-       user = user_read - last_cpu_results[0];
+       user   = user_read - last_cpu_results[0];
        system = system_read - last_cpu_results[1];
-       nice = nice_read - last_cpu_results[2];
-       idle = idle_read - last_cpu_results[3]; 
+       nice   = nice_read - last_cpu_results[2];
+       idle   = idle_read - last_cpu_results[3];       
        /* Calculate the % usage */
-       if ((user + system + nice + idle) > 0) {
+       if ( (user + system + nice + idle) > 0) {
          usage_time = user + system + nice;
          total_time = usage_time + idle;
        }
-       if (total_time == 0)
-         total_time = 1; /* avoid fpe */
-       ret = (100 * usage_time) / total_time;
-       /*LOG(LOG_DEBUG,
-           "LOAD: u%d s%d n%d i%d => ret %d\n",
-           user, system, nice, idle, ret);*/
+       if ( (total_time > 0) &&
+            ( (last_cpu_results[0] +
+               last_cpu_results[1] +
+               last_cpu_results[2] +
+               last_cpu_results[3]) > 0) )
+         currentLoad = (100 * usage_time) / total_time;
+       else
+         currentLoad = -1;
        /* Store the values for the next calculation*/
        last_cpu_results[0] = user_read;
        last_cpu_results[1] = system_read;
        last_cpu_results[2] = nice_read;
        last_cpu_results[3] = idle_read;
-       lastcpuresult = ret;
        MUTEX_UNLOCK(&statusMutex);
-       return ret;
+       return;
       }
     }
   }
 #endif
 
   /* try kstat (Solaris only) */
-#if SOLARIS
-#if HAVE_KSTAT_H
-#if HAVE_SYS_SYSINFO_H
+#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H
   {
-    static int kstat_once = 0; /* if open fails, don't keep
-                                 trying */
+    static long long last_idlecount;
+    static long long last_totalcount;
+    static int kstat_once; /* if open fails, don't keep
+                             trying */
     kstat_ctl_t * kc;
     kstat_t * khelper;
     long long idlecount;
     long long totalcount;
-    static long long last_idlecount = 0;
-    static long long last_totalcount = 0;
     long long deltaidle;
     long long deltatotal;
 
-    if (kstat_once == 0) {
-      kc = kstat_open();
-      if (kc == NULL)
-       LOG_STRERROR(LOG_ERROR, "kstat_open");
-    } else {
-      kc = NULL;
-    }
-    if (kc == NULL)
+    if (kstat_once == 1)
       goto ABORT_KSTAT;
+    kc = kstat_open();
+    if (kc == NULL) {
+      LOG_STRERROR(LOG_ERROR, "kstat_open");
+      goto ABORT_KSTAT;
+    }
 
     idlecount = 0;
     totalcount = 0;
@@ -915,142 +400,163 @@
       goto ABORT_KSTAT; /* no stats found => abort */
     deltaidle = idlecount - last_idlecount;
     deltatotal = totalcount - last_totalcount;
+    if ( (deltatotal > 0) && 
+        (last_totalcount > 0) )
+      currentLoad = (int) (100 * deltaidle / deltatotal);    
+    else
+      currentLoad = -1;
     last_idlecount = idlecount;
     last_totalcount = totalcount;
-    if (deltatotal == 0)
-      deltatotal = 1; /* avoid fpe */
-    /* success! */
     MUTEX_UNLOCK(&statusMutex);
-    lastcpuresult = (int) (100 * deltaidle / deltatotal);
-    return lastcpuresult;
-
+    return;
   ABORT_KSTAT:
     kstat_once = 1; /* failed, don't try again */
   }
 #endif
-#endif
-#endif
 
-  /* maybe try kvm (Solaris, BSD, OSX) here?
-     Did Filip say he had some code for this??? */
-
   /* insert methods better than getloadavg for
      other platforms HERE! */
 
   /* ok, maybe we have getloadavg on this platform */
 #if HAVE_GETLOADAVG
-  if (getloadavg(&loadavg, 1) != 1) {
-    /* only warn once, if there is a problem with
-       getloadavg, we're going to hit it frequently... */
-    static int once = 0;
-    if (once == 0) {
-      once = 1;
-      LOG_STRERROR(LOG_ERROR, "getloadavg");
+  {
+    static int warnOnce = 0;
+    double loadavg;
+    if (1 != getloadavg(&loadavg, 1)) {
+      /* only warn once, if there is a problem with
+        getloadavg, we're going to hit it frequently... */
+      if (warnOnce == 0) {
+       warnOnce = 1;
+       LOG_STRERROR(LOG_ERROR, "getloadavg");
+      }
+      currentLoad = -1;
+    } else {
+      /* success with getloadavg */
+      currentLoad = (int) (100 * loadavg);
+      MUTEX_UNLOCK(&statusMutex);
+      return;
     }
-    /* continue with next method -- if we had any... */
-  } else {
-    /* success with getloadavg */
-    lastcpuresult = (int) (100 * loadavg);
-    MUTEX_UNLOCK(&statusMutex);
-    return lastcpuresult;
   }
 #endif
 
 #if MINGW
   /* Win NT? */
-  if (GNNtQuerySystemInformation)
-  {
+  if (GNNtQuerySystemInformation) {
+    static double dLastKernel;
+    static double dLastIdle;
+    static double dLastUser;
+    double dKernel;
+    double dIdle;
+    double dUser;
+    double dDiffKernel;
+    double dDiffIdle;
+    double dDiffUser;
     SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo;
-    if (GNNtQuerySystemInformation(SystemProcessorPerformanceInformation,
-        &theInfo, sizeof(theInfo), NULL) == NO_ERROR)
-    {
-      double dKernel, dIdle, dUser, dDiffKernel, dDiffIdle, dDiffUser;
-      static double dLastKernel = 0, dLastIdle = 0, dLastUser = 0;
 
+    if (GNNtQuerySystemInformation(SystemProcessorPerformanceInformation,
+                                  &theInfo, 
+                                  sizeof(theInfo),
+                                  NULL) == NO_ERROR) {
+      /* PORT-ME MINGW: Multi-processor? */
       dKernel = Li2Double(theInfo.KernelTime);
       dIdle = Li2Double(theInfo.IdleTime);
       dUser = Li2Double(theInfo.UserTime);
+      dDiffKernel = dKernel - dLastKernel;
+      dDiffIdle = dIdle - dLastIdle;
+      dDiffUser = dUser - dLastUser;
 
-      if (dLastIdle != 0)
-      {
-        dDiffKernel = dKernel - dLastKernel;
-        dDiffIdle = dIdle - dLastIdle;
-        dDiffUser = dUser - dLastUser;
-
-        /* PORT-ME MINGW: Multi-processor? */
-        lastcpuresult = 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 
100.0;
-      }
+      if ( ( (dDiffKernel + dDiffUser) > 0) &&
+          (dLastIdle + dLastKernel + dLastUser > 0) ) 
+        currentLoad = 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0;
       else
-        lastcpuresult = 0; /* don't know (yet) */
+        currentLoad = -1; /* don't know (yet) */
 
       dLastKernel = dKernel;
       dLastIdle = dIdle;
       dLastUser = dUser;
 
       MUTEX_UNLOCK(&statusMutex);
-      return lastcpuresult;
+      return;
+    } else {
+      /* only warn once, if there is a problem with
+        NtQuery..., we're going to hit it frequently... */
+      static int once;
+      if (once == 0) {
+       once = 1;
+       LOG(LOG_ERROR,
+           _("Cannot query the CPU usage (Windows NT).\n"));
+      }
     }
-    else
-    {
-         /* only warn once, if there is a problem with
-            NtQuery..., we're going to hit it frequently... */
-         static int once = 0;
-         if (once == 0)
-         {
-           once = 1;
-           LOG(LOG_ERROR,
-               _("Cannot query the CPU usage (Windows NT).\n"));
-         }
-    }
-  }
-  else
-  {
-    /* Win 9x */
+  } else { /* Win 9x */
     HKEY hKey;
     DWORD dwDataSize, dwType, dwDummy;
 
     /* Start query */
-    if (RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StartSrv", 0, KEY_ALL_ACCESS,
-                     &hKey) != ERROR_SUCCESS)
-    {
+    if (RegOpenKeyEx(HKEY_DYN_DATA, 
+                    "PerfStats\\StartSrv", 
+                    0,
+                    KEY_ALL_ACCESS,
+                     &hKey) != ERROR_SUCCESS) {
       /* only warn once */
-         static int once = 0;
-         if (once == 0)
-         {
-           once = 1;
-           LOG(LOG_ERROR,
-               _("Cannot query the CPU usage (Win 9x)\n"));
-         }
+      static int once = 0;
+      if (once == 0) {
+       once = 1;
+       LOG(LOG_ERROR,
+           _("Cannot query the CPU usage (Win 9x)\n"));
+      }
     }
 
-    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StartStat", 0, KEY_ALL_ACCESS,
-                     &hKey);
-
+    RegOpenKeyEx(HKEY_DYN_DATA, 
+                "PerfStats\\StartStat", 
+                0, 
+                KEY_ALL_ACCESS,
+                &hKey);
     dwDataSize = sizeof(dwDummy);
-    RegQueryValueEx(hKey, "KERNEL\\CPUUsage", NULL, &dwType, (LPBYTE) &dwDummy,
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage", 
+                   NULL, 
+                   &dwType, 
+                   (LPBYTE) &dwDummy,
                     &dwDataSize);
     RegCloseKey(hKey);
 
     /* Get CPU usage */
-    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StatData", 0, KEY_ALL_ACCESS,
+    RegOpenKeyEx(HKEY_DYN_DATA, 
+                "PerfStats\\StatData",
+                0, 
+                KEY_ALL_ACCESS,
                  &hKey);
-    dwDataSize = sizeof(lastcpuresult);
-    RegQueryValueEx(hKey, "KERNEL\\CPUUsage", NULL, &dwType,
-                    (LPBYTE) &lastcpuresult, &dwDataSize);
+    dwDataSize = sizeof(currentLoad);
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage", 
+                   NULL, 
+                   &dwType,
+                    (LPBYTE) &currentLoad,
+                   &dwDataSize);
     RegCloseKey(hKey);
 
     /* Stop query */
-    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StopStat", 0, KEY_ALL_ACCESS,
+    RegOpenKeyEx(HKEY_DYN_DATA, 
+                "PerfStats\\StopStat",
+                0, 
+                KEY_ALL_ACCESS,
                  &hKey);
-    RegOpenKeyEx(HKEY_DYN_DATA, "PerfStats\\StopSrv", 0, KEY_ALL_ACCESS,
+    RegOpenKeyEx(HKEY_DYN_DATA, 
+                "PerfStats\\StopSrv", 
+                0, 
+                KEY_ALL_ACCESS,
                  &hKey);
     dwDataSize = sizeof(dwDummy);
-    RegQueryValueEx(hKey, "KERNEL\\CPUUsage", NULL, &dwType, (LPBYTE)&dwDummy,
+    RegQueryValueEx(hKey,
+                   "KERNEL\\CPUUsage", 
+                   NULL, 
+                   &dwType, 
+                   (LPBYTE)&dwDummy,
                     &dwDataSize);
     RegCloseKey(hKey);
 
     MUTEX_UNLOCK(&statusMutex);
-    return lastcpuresult;
+    return;
   }
 #endif
 
@@ -1058,41 +564,129 @@
      specific alternative defined
      => default: error
   */
-  lastcpuresult = -1;
+  currentLoad = -1;
   MUTEX_UNLOCK(&statusMutex);
-  return -1;
 }
 
+static void cronLoadUpdate(void * unused) {
+  updateCpuUsage();
+  if (! useBasicMethod)
+    updateInterfaceTraffic();
+}
+
 /**
+ * Re-read the configuration for statuscalls.
+ */
+static void resetStatusCalls() {
+  char * interfaces;
+  int i;
+  int numInterfaces;
+
+  MUTEX_LOCK(&statusMutex);
+  for (i=0;i<ifcsSize;i++)
+    FREE(ifcs[i].name);
+  GROW(ifcs, 
+       ifcsSize,
+       0);
+  interfaces
+    = getConfigurationString("LOAD",
+                            "INTERFACES");
+  /* fail if config-file is incomplete */
+  if ( (interfaces == NULL) ||
+       (strlen(interfaces) == 0) ) {
+    LOG(LOG_ERROR,
+       _("No network interfaces defined in configuration section '%s' under 
'%s'!\n"),
+       "LOAD",
+       "INTERFACES");
+  } else {
+    /* The string containing the interfaces is formatted in the following way:
+     * each comma is replaced by '\0' and the pointers to the beginning of 
every
+     * interface are stored
+     */
+    numInterfaces = 1;
+    for (i=strlen(interfaces)-1;i>=0;i--)
+      if (interfaces[i] == ',')
+       numInterfaces++;
+    GROW(ifcs,
+        ifcsSize,
+        numInterfaces);
+    for (i=strlen(interfaces)-1;i>=0;i--) {
+      if (interfaces[i] == ',') {
+       ifcs[--numInterfaces].name = STRDUP(&interfaces[i+1]);
+       numInterfaces++;
+       interfaces[i] = '\0';
+      }
+    }
+    ifcs[--numInterfaces].name = STRDUP(interfaces);
+    GNUNET_ASSERT(numInterfaces == 0);
+    for (i=0;i<ifcsSize;i++) {
+      ifcs[i].last_in = 0;
+      ifcs[i].last_out = 0;
+    }
+  }
+  FREENONNULL(interfaces);
+  useBasicMethod
+    = testConfigurationString("LOAD",
+                             "BASICLIMITING",
+                             "YES");
+  maxNetDownBPS
+    = getConfigurationInt("LOAD",
+                         "MAXNETDOWNBPSTOTAL");
+  if (maxNetDownBPS == 0)
+    maxNetDownBPS = 50000;
+  maxNetUpBPS
+    = getConfigurationInt("LOAD",
+                         "MAXNETUPBPSTOTAL");
+  if (maxNetUpBPS == 0)
+    maxNetUpBPS = 50000;
+  maxCPULoad
+    = getConfigurationInt("LOAD",
+                         "MAXCPULOAD");
+  if (maxCPULoad == 0)
+    maxCPULoad = 100; 
+  MUTEX_UNLOCK(&statusMutex);
+}
+
+
+
+/**
  * Get the load of the network relative to what is allowed.
  * @return the network load as a percentage of allowed
  *        (100 is equivalent to full load)
  */
 int getNetworkLoadUp() {
-  static int lastRet = 0;
-  static cron_t lastCall = 0;
-  int ret;
+  static unsigned long long overload;
+  static unsigned long long lastSum;
+  static cron_t lastCall;
   cron_t now;
+  unsigned long long maxExpect;
+  unsigned long long currentLoadSum;
+  int i;
 
-  ret = networkUsageUp();
-  if (ret == -1) /* in the case of error, we do NOT go to 100%
-                   since that would render GNUnet useless on
-                   systems where networkUsageUp is not supported */
-    return -1;
-
+  MUTEX_LOCK(&statusMutex);
+  currentLoadSum = globalTrafficBetweenProc.last_out;
+  for (i=0;i<ifcsSize;i++)
+    currentLoadSum += ifcs[i].last_out;
   cronTime(&now);
-  if (now - lastCall < 250*cronMILLIS) {
-    /* use smoothing, but do NOT update lastRet at frequencies higher
-       than 250ms; this makes the smoothing (mostly) independent from
-       the frequency at which getNetworkLoadUp is called. */
-    return (ret + 7 * lastRet)/8;
+  if ( (lastSum > currentLoadSum) ||
+       (lastSum == 0) ||
+       (now < lastCall) ) {
+    /* integer overflow or first datapoint; since we cannot tell where
+       / by how much the overflow happened, all we can do is ignore
+       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
+    lastSum = currentLoadSum;
+    lastCall = now;
+    return -1;
   }
+  currentLoadSum += overload;
+  maxExpect = ( (lastCall - now) * maxNetDownBPS ) / cronSECONDS;
   lastCall = now;
-
-  ret = (ret + 7 * lastRet)/8;
-  lastRet = ret;
-
-  return ret;
+  if (currentLoadSum < maxExpect) 
+    overload = 0;
+  else 
+    overload = currentLoadSum - maxExpect;  
+  MUTEX_UNLOCK(&statusMutex);
+  return currentLoadSum * 100 / maxExpect;
 }
 
 /**
@@ -1101,32 +695,38 @@
  *        (100 is equivalent to full load)
  */
 int getNetworkLoadDown() {
-  static int lastRet = 0;
-  static cron_t lastCall = 0;
-  int ret;
+  static unsigned long long overload;
+  static unsigned long long lastSum;
+  static cron_t lastCall;
   cron_t now;
-
-
-  if (initialized_ == NO)
-    return -1;
-  ret = networkUsageDown();
-  if (ret == -1) /*  in the case of error, we do NOT go to 100%
-                   since that would render GNUnet useless on
-                   systems where networkUsageUp is not supported */
-    return -1;
-
+  unsigned long long maxExpect;
+  unsigned long long currentLoadSum;
+  int i;
+  
+  MUTEX_LOCK(&statusMutex);
+  currentLoadSum = globalTrafficBetweenProc.last_in;
+  for (i=0;i<ifcsSize;i++)
+    currentLoadSum += ifcs[i].last_in;
   cronTime(&now);
-  if (now - lastCall < 250*cronMILLIS) {
-    /* use smoothing, but do NOT update lastRet at frequencies higher
-       than 250ms; this makes the smoothing (mostly) independent from
-       the frequency at which getNetworkLoadDown is called. */
-    return (ret + 7 * lastRet)/8;
+  if ( (lastSum > currentLoadSum) ||
+       (lastSum == 0) ||
+       (now < lastCall) ) {
+    /* integer overflow or first datapoint; since we cannot tell where
+       / by how much the overflow happened, all we can do is ignore
+       this datapoint.  So we return -1 -- AND reset lastSum / lastCall. */
+    lastSum = currentLoadSum;
+    lastCall = now;
+    return -1;
   }
+  currentLoadSum += overload;
+  maxExpect = ( (lastCall - now) * maxNetDownBPS ) / cronSECONDS;
   lastCall = now;
-
-  ret = (ret + 7 * lastRet)/8;
-  lastRet = ret;
-  return ret;
+  if (currentLoadSum < maxExpect) 
+    overload = 0;
+  else 
+    overload = currentLoadSum - maxExpect;  
+  MUTEX_UNLOCK(&statusMutex);
+  return currentLoadSum * 100 / maxExpect;
 }
 
 /**
@@ -1135,29 +735,33 @@
  *        (100 is equivalent to full load)
  */
 int getCPULoad() {
-  static int lastRet = 0;
-  static cron_t lastCall = 0;
+  static int lastRet = -1;
+  static cron_t lastCall;
   int ret;
   cron_t now;
 
-  if (initialized_ == NO)
+  if (initialized_ == NO) {
+    lastRet = -1;
     return -1;
+  }
+  ret = (100 * currentLoad) / maxCPULoad;
 
-  ret = (100 * cpuUsage()) / maxCPULoad;
-
   cronTime(&now);
-  if (now - lastCall < 250*cronMILLIS) {
+  if ( (lastRet != -1) &&
+       (now - lastCall < 250 * cronMILLIS) ) {
     /* use smoothing, but do NOT update lastRet at frequencies higher
        than 250ms; this makes the smoothing (mostly) independent from
        the frequency at which getCPULoad is called. */
     return (ret + 7 * lastRet)/8;
   }
-  lastCall = now;
 
   /* for CPU, we don't do the 'fast increase' since CPU is much
      more jitterish to begin with */
-  lastRet = (ret + 7 * lastRet)/8;
-
+  if (lastRet != -1)
+    lastRet = (ret + 7 * lastRet)/8;
+  else
+    lastRet = ret;
+  lastCall = now;
   return lastRet;
 }
 
@@ -1167,52 +771,56 @@
  * @return OK on success and SYSERR on error (or calls errexit).
  */
 void initStatusCalls() {
-  initialized_ = YES;
 #ifdef LINUX
   proc_stat = fopen("/proc/stat", "r");
   if (NULL == proc_stat)
-    LOG_FILE_STRERROR(LOG_ERROR, "fopen", "/proc/stat");
+    LOG_FILE_STRERROR(LOG_ERROR,
+                     "fopen",
+                     "/proc/stat");
+  proc_net_dev = fopen(PROC_NET_DEV, "r");
+  if (NULL == proc_net_dev) 
+    LOG_FILE_STRERROR(LOG_ERROR, 
+                     "fopen", 
+                     PROC_NET_DEV);
 #endif
   MUTEX_CREATE_RECURSIVE(&statusMutex);
-  last_net_results = NULL; /* has numInterfaces entries */
-  interfacePtrs = NULL;
-  last_net_results = NULL;
-  globalTrafficBetweenProc.last_in = 0;
-  globalTrafficBetweenProc.last_out = 0;
-  cronTime(&lastnettimeUp);
-  cronTime(&lastnettimeDown);
+  initialized_ = YES;
+  resetBetweenProc();
   registerConfigurationUpdateCallback(&resetStatusCalls);
   resetStatusCalls();
-  networkUsageUp();
-  networkUsageDown();
-  cpuUsage();
+  cronLoadUpdate(NULL);
   addCronJob(&cronLoadUpdate,
             10 * cronSECONDS,
             10 * cronSECONDS,
             NULL);
+  getNetworkLoadUp();
+  getNetworkLoadDown();
 }
 
 /**
  * Shutdown the status calls module.
  */
 void doneStatusCalls() {
-#ifdef LINUX
-  if (proc_stat != NULL)
-    fclose(proc_stat);
-#endif
+  int i;
+  
   unregisterConfigurationUpdateCallback(&resetStatusCalls);
   delCronJob(&cronLoadUpdate,
             10 * cronSECONDS,
             NULL);
-  if (numInterfaces > 0) {
-    FREE(interfacePtrs[0]);
-    FREE(interfacePtrs);
-  }
-  FREENONNULL(last_net_results);
-  MUTEX_DESTROY(&statusMutex);
   initialized_ = NO;
+#ifdef LINUX
+  if (proc_stat != NULL)
+    fclose(proc_stat);
+  if (proc_net_dev != NULL)
+    fclose(proc_net_dev);
+#endif
+  for (i=0;i<ifcsSize;i++)
+    FREE(ifcs[i].name);
+  GROW(ifcs,
+       ifcsSize,
+       0);
+  MUTEX_DESTROY(&statusMutex);
 }
 
 
-
 /* end of statuscalls.c */

Modified: GNUnet/src/util/statuscallstest.c
===================================================================
--- GNUnet/src/util/statuscallstest.c   2005-07-10 21:14:49 UTC (rev 1377)
+++ GNUnet/src/util/statuscallstest.c   2005-07-10 23:16:05 UTC (rev 1378)
@@ -6,34 +6,7 @@
 #include "gnunet_util.h"
 #include "platform.h"
 
-/* OPTIMIZE-ME: avoid making these non-static altogether! */
-
-
 /**
- * The following routine returns a positive number which indicates
- * the percentage CPU usage. 100 corresponds to one runnable process
- * on average.
- */
-int cpuUsage();
-
-/**
- * The following routine returns the percentage of available used
- * bandwidth.  A number from 0-100 is returned.  Example: If 81 is
- * returned this means that 81% of the network bandwidth of the host
- * is consumed.
- */
-int networkUsageUp();
-
-/**
- * The following routine returns the percentage of available used
- * bandwidth. A number from 0-100 is returned.  Example: If 81 is
- * returned this means that 81% of the network bandwidth of the host
- * is consumed.
- */
-int networkUsageDown();
-
-
-/**
  * Perform option parsing from the command line.
  */
 static int parseCommandLine(int argc,
@@ -83,22 +56,7 @@
 
   if (OK != initUtil(argc, argv, &parseCommandLine))
     errexit("Error during initialization!\n");
-
-  for (i=0;i<3;i++) {
-    if (cpuUsage() == -1) {
-      printf("cpuUsage == -1\n");
-      return -1;
-    }
-    if (networkUsageUp() == -1) {
-      printf("networkUsageUp == -1\n");
-      return -1;
-    }
-    if (networkUsageDown() == -1) {
-      printf("networkUsageDown == -1\n");
-      return -1;
-    }
-    sleep(1);
-  }
+  startCron();
   /* need to run each phase for more than 10s since
      statuscalls only refreshes that often... */
   cronTime(&start);
@@ -122,6 +80,7 @@
     if (networkUsageDown() == -1)
       return -1;
   }
+  stopCron();
   doneUtil();
 
   return 0;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]