aboutsummaryrefslogtreecommitdiffstats
path: root/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/proc.c b/proc.c
new file mode 100644
index 0000000..08e9252
--- /dev/null
+++ b/proc.c
@@ -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;
+}