#include #include #include #include #include #include #include #include #include "syscall.h" #include "libc.h" #define JT(x) (-256|(x)) #define VER JT(1) #define JT_ARG_MAX JT(2) #define JT_MQ_PRIO_MAX JT(3) #define JT_PAGE_SIZE JT(4) #define JT_SEM_VALUE_MAX JT(5) #define JT_NPROCESSORS_CONF JT(6) #define JT_NPROCESSORS_ONLN JT(7) #define JT_PHYS_PAGES JT(8) #define JT_AVPHYS_PAGES JT(9) #define JT_ZERO JT(10) #define JT_DELAYTIMER_MAX JT(11) #define RLIM(x) (-32768|(RLIMIT_ ## x)) #define PRESENT_MAX_READ 128 #define char_to_int(prev, num) (10 * prev + (num - '0')) static inline int get_nrprocessors_conf(void) { FILE *f; char buffer[PRESENT_MAX_READ]; int start_chunk = 0, end_chunk = -1; unsigned int cnt = 0, i = 0; size_t ret; f = fopen("/sys/devices/system/cpu/present", "r"); if (!f) return 0; ret = fread(buffer, sizeof(*buffer), sizeof(buffer) / sizeof(*buffer), f); if (!feof(f) || ferror(f) || ret < 2) goto end; /* * Count the number of CPUs in the CPU mask. A CPU Mask is described by * chunks. Chunks have the following format: "-" and are * separated by ",". A chunk can be composed of a single CPU. * * e.g. "0-1,4" -> 3 CPUs */ while (i < PRESENT_MAX_READ) { if (buffer[i] == ',' || buffer[i] == '\0') { if (end_chunk > -1) cnt += (end_chunk - start_chunk) + 1; else cnt++; start_chunk = 0; end_chunk = -1; if (buffer[i] == '\0') break; } else if (buffer[i] == '-') { end_chunk = 0; } else if (isdigit(buffer[i])) { if (end_chunk == -1) start_chunk = char_to_int(start_chunk, buffer[i]); else end_chunk = char_to_int(end_chunk, buffer[i]); } i++; } end: fclose(f); return cnt; } static inline int get_nrprocessors_onln(void) { unsigned char set[128] = {1}; int i, cnt; __syscall(SYS_sched_getaffinity, 0, sizeof set, set); for (i=cnt=0; i= sizeof(values)/sizeof(values[0]) || !values[name]) { errno = EINVAL; return -1; } else if (values[name] >= -1) { return values[name]; } else if (values[name] < -256) { struct rlimit lim; getrlimit(values[name]&16383, &lim); if (lim.rlim_cur == RLIM_INFINITY) return -1; return lim.rlim_cur > LONG_MAX ? LONG_MAX : lim.rlim_cur; } switch ((unsigned char)values[name]) { case VER & 255: return _POSIX_VERSION; case JT_ARG_MAX & 255: return ARG_MAX; case JT_MQ_PRIO_MAX & 255: return MQ_PRIO_MAX; case JT_PAGE_SIZE & 255: return PAGE_SIZE; case JT_SEM_VALUE_MAX & 255: return SEM_VALUE_MAX; case JT_DELAYTIMER_MAX & 255: return DELAYTIMER_MAX; case JT_NPROCESSORS_CONF & 255: ; int cnt = get_nrprocessors_conf(); if (cnt > 0) return cnt; return get_nrprocessors_onln(); case JT_NPROCESSORS_ONLN & 255: ; return get_nrprocessors_onln(); case JT_PHYS_PAGES & 255: case JT_AVPHYS_PAGES & 255: ; unsigned long long mem; struct sysinfo si; __lsysinfo(&si); if (!si.mem_unit) si.mem_unit = 1; if (name==_SC_PHYS_PAGES) mem = si.totalram; else mem = si.freeram + si.bufferram; mem *= si.mem_unit; mem /= PAGE_SIZE; return (mem > LONG_MAX) ? LONG_MAX : mem; case JT_ZERO & 255: return 0; } return values[name]; }