Module: kamailio
Branch: master
Commit: b22c63a930a3c8d4055ddeea48bb29b7fb3b2eb1
URL:
https://github.com/kamailio/kamailio/commit/b22c63a930a3c8d4055ddeea48bb29b…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2015-01-07T18:08:35+01:00
ratelimite: take in consideration number of cpus for load
- on multi core systems, the sums of stats can go over 100%, resulting
in out of range for expected load_value to be 0.0 to 1.0
- safety checks to avoid overflows
---
Modified: modules/ratelimit/ratelimit.c
---
Diff:
https://github.com/kamailio/kamailio/commit/b22c63a930a3c8d4055ddeea48bb29b…
Patch:
https://github.com/kamailio/kamailio/commit/b22c63a930a3c8d4055ddeea48bb29b…
---
diff --git a/modules/ratelimit/ratelimit.c b/modules/ratelimit/ratelimit.c
index 1d6d1a5..561185f 100644
--- a/modules/ratelimit/ratelimit.c
+++ b/modules/ratelimit/ratelimit.c
@@ -293,6 +293,36 @@ static int str_cpy(str * dest, str * src)
return 0;
}
+#if defined (__OS_darwin) || defined (__OS_freebsd)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#else
+#include <unistd.h>
+#endif
+
+int get_num_cpus() {
+ int count = 0;
+
+#if defined (__OS_darwin) || defined (__OS_freebsd)
+ int nm[2];
+ size_t len;
+
+ len = sizeof(count);
+
+ nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
+ sysctl(nm, 2, &count, &len, NULL, 0);
+
+ if(count < 1) {
+ nm[1] = HW_NCPU;
+ sysctl(nm, 2, &count, &len, NULL, 0);
+ }
+#else
+ count = sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+ if(count < 1) return 1;
+ return count;
+}
+
/* not using /proc/loadavg because it only works when our_timer_interval == theirs */
static int get_cpuload(double * load)
{
@@ -301,6 +331,8 @@ static int get_cpuload(double * load)
long long n_user, n_nice, n_sys, n_idle, n_iow, n_irq, n_sirq, n_stl;
static int first_time = 1;
FILE * f = fopen("/proc/stat", "r");
+ double vload;
+ int ncpu;
if (! f) {
LM_ERR("could not open /proc/stat\n");
@@ -327,7 +359,16 @@ static int get_cpuload(double * load)
(n_stl - o_stl);
long long d_idle = (n_idle - o_idle);
- *load = 1.0 - ((double)d_idle) / (double)d_total;
+ vload = ((double)d_idle) / (double)d_total;
+
+ /* divide by numbers of cpu */
+ ncpu = get_num_cpus();
+ vload = vload/ncpu;
+ vload = 1.0 - vload;
+ if(vload<0.0) vload = 0.0;
+ else if (vload>1.0) vload = 1.0;
+
+ *load = vload;
}
o_user = n_user;