diff options
Diffstat (limited to '')
-rw-r--r-- | proc.c | 73 |
1 files changed, 73 insertions, 0 deletions
@@ -0,0 +1,73 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +size_t +getnproc(size_t default_count) +{ + char buf[128]; + int fd, num = 0; + size_t n = 0, off = 0, len = 0; + size_t nums[] = {0, 0}; + ssize_t r; + size_t last = 0; + + fd = open("/sys/devices/system/cpu/online", O_RDONLY); + if (fd < 0) + return default_count; + + for (;; off++) { + if (off == len) { + r = read(fd, buf, sizeof(buf)); + if (r <= 0) { + if (!r) + break; + if (errno == EINTR) + continue; + error: + n = default_count; + goto out; + } + len = (size_t)r; + off = 0; + } + + if (buf[off] == '-') { + if (num++ == 1) + goto error; + } else if (buf[off] == ',' || buf[off] == '\n') { + if (num == 0) { + nums[1] = nums[0]; + } else { + num = 0; + if (nums[1] < nums[0]) + goto error; + } + if (nums[0] < last) + goto error; + last = nums[0]; + if (nums[1] - nums[0] + 1U > SIZE_MAX - n) + goto error; + n += nums[1] - nums[0] + 1U; + } else if (isdigit(buf[off])) { + if (nums[num] > (SIZE_MAX - (size_t)(buf[off] & 15)) / 10U) + goto error; + nums[num] = nums[num] * 10U + (size_t)(buf[off] & 15); + } else { + goto error; + } + } + + n = n ? n : default_count; +out: + close(fd); + return n; +} + + +size_t +getautonthreads(void) +{ + size_t n = getnproc(8U); + return n < 3U ? 1U : n - 2U; +} |