summaryrefslogtreecommitdiff
path: root/ext/etc
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-21 18:46:33 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-21 18:46:33 +0000
commit0fa75e813ecf0f5f3dd01f89aa76d0e25ab4fcd4 (patch)
tree50c314b8cc33ee0bff2b0b1de0643a175740be54 /ext/etc
parenta4f0db49ab75c4e5865b24fa850ad749db8d7543 (diff)
* ext/etc/etc.c (etc_nprocessors_affin): optimize memory usege a
bit. Typical rubyist never use 8k cpus machine. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48080 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/etc')
-rw-r--r--ext/etc/etc.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index a37d77c..58c00b0 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -916,7 +916,7 @@ etc_nprocessors_affin(void)
cpu_set_t *cpuset;
size_t size;
int ret;
- int ncpus;
+ int n;
/*
* XXX:
@@ -934,23 +934,30 @@ etc_nprocessors_affin(void)
* So, we use hardcode number for workaround. Current linux kernel
* (Linux 3.17) support 8192 cpus at maximum. Then 16384 is enough large.
*/
- ncpus = 16384;
-
- cpuset = CPU_ALLOC(ncpus);
- if (!cpuset) {
- return -1;
+ for (n=64; n < 16384; n *= 2) {
+ size = CPU_ALLOC_SIZE(n);
+ if (size >= 1024) {
+ cpuset = xcalloc(1, size);
+ if (!cpuset)
+ return -1;
+ } else {
+ cpuset = alloca(size);
+ CPU_ZERO_S(size, cpuset);
+ }
+
+ ret = sched_getaffinity(0, size, cpuset);
+ if (ret == 0) {
+ /* On success, count number of cpus. */
+ ret = CPU_COUNT_S(size, cpuset);
+ }
+
+ if (size >= 1024) {
+ xfree(cpuset);
+ }
+ if (ret > 0) {
+ return ret;
+ }
}
- size = CPU_ALLOC_SIZE(ncpus);
- CPU_ZERO_S(size, cpuset);
-
- ret = sched_getaffinity(0, size, cpuset);
- if (ret==-1) {
- goto free;
- }
-
- ret = CPU_COUNT_S(size, cpuset);
- free:
- CPU_FREE(cpuset);
return ret;
}