Advertisement
rockdrilla

Linux: get CPU count without /proc or /sys

Nov 14th, 2018
495
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.40 KB | None | 0 0
  1. // task: get CPU count without /proc or /sys
  2. // solution: get CPU affinity mask from PID 1
  3.  
  4. #define _GNU_SOURCE
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <sched.h>
  9. #include <errno.h>
  10.  
  11. size_t get_cpu_count(void) {
  12.     const pid_t     ack_pid = 1;
  13.     cpu_set_t       * cs = NULL;
  14.     cpu_set_t       * cs_t = NULL;
  15.     const size_t    alloc_thres = 4096, reallocs_max = 10;
  16.     size_t          cs_len = 0, reallocs = 0;
  17.     size_t          r = 0, i = 0, k = 0;
  18.  
  19.     cs_len = alloc_thres;
  20.     cs = malloc(cs_len);
  21.     if (!cs) { return 0; }
  22.  
  23.     while (reallocs < reallocs_max) {
  24.         CPU_ZERO_S(cs_len, cs);
  25.         if (!sched_getaffinity(ack_pid, cs_len, cs)) { break; }
  26.  
  27.         if (errno != EINVAL) { goto cs_cleanup; }
  28.  
  29.         cs_len += alloc_thres;
  30.         cs_t = realloc(cs, cs_len);
  31.         if (!cs_t) { goto cs_cleanup; }
  32.  
  33.         cs = cs_t;
  34.         reallocs++;
  35.     }
  36.  
  37.     if (reallocs == reallocs_max) {
  38.         // is it better return 0 instead of this?..
  39.         return CPU_COUNT_S(cs_len, cs);
  40.     }
  41.  
  42.     k = CPU_COUNT_S(cs_len, cs);
  43.     for (i = 0; i < k; i++) {
  44.         if (CPU_ISSET_S(i, cs_len, cs)) { r++; }
  45.     }
  46.  
  47. cs_cleanup:
  48.     if (cs) { free(cs); cs = NULL; }
  49.  
  50.     return r;
  51. }
  52.  
  53. // #include <sys/sysinfo.h>
  54.  
  55. int main(void) {
  56.     // printf("cpu count = %d\n", get_nprocs_conf());
  57.     printf("cpu count = %ld\n", get_cpu_count());
  58.     return 0;
  59. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement