Commit | Line | Data |
---|---|---|
fcb45ec0 ME |
1 | /* |
2 | * Copyright 2013-2015, Michael Ellerman, IBM Corp. | |
3 | * Licensed under GPLv2. | |
4 | */ | |
5 | ||
d1301afd ME |
6 | #define _GNU_SOURCE /* For CPU_ZERO etc. */ |
7 | ||
fcb45ec0 ME |
8 | #include <elf.h> |
9 | #include <errno.h> | |
10 | #include <fcntl.h> | |
11 | #include <link.h> | |
d1301afd | 12 | #include <sched.h> |
fcb45ec0 ME |
13 | #include <stdio.h> |
14 | #include <sys/stat.h> | |
15 | #include <sys/types.h> | |
16 | #include <unistd.h> | |
17 | ||
18 | #include "utils.h" | |
19 | ||
20 | static char auxv[4096]; | |
21 | ||
22 | void *get_auxv_entry(int type) | |
23 | { | |
24 | ElfW(auxv_t) *p; | |
25 | void *result; | |
26 | ssize_t num; | |
27 | int fd; | |
28 | ||
29 | fd = open("/proc/self/auxv", O_RDONLY); | |
30 | if (fd == -1) { | |
31 | perror("open"); | |
32 | return NULL; | |
33 | } | |
34 | ||
35 | result = NULL; | |
36 | ||
37 | num = read(fd, auxv, sizeof(auxv)); | |
38 | if (num < 0) { | |
39 | perror("read"); | |
40 | goto out; | |
41 | } | |
42 | ||
43 | if (num > sizeof(auxv)) { | |
44 | printf("Overflowed auxv buffer\n"); | |
45 | goto out; | |
46 | } | |
47 | ||
48 | p = (ElfW(auxv_t) *)auxv; | |
49 | ||
50 | while (p->a_type != AT_NULL) { | |
51 | if (p->a_type == type) { | |
52 | result = (void *)p->a_un.a_val; | |
53 | break; | |
54 | } | |
55 | ||
56 | p++; | |
57 | } | |
58 | out: | |
59 | close(fd); | |
60 | return result; | |
61 | } | |
d1301afd ME |
62 | |
63 | int pick_online_cpu(void) | |
64 | { | |
65 | cpu_set_t mask; | |
66 | int cpu; | |
67 | ||
68 | CPU_ZERO(&mask); | |
69 | ||
70 | if (sched_getaffinity(0, sizeof(mask), &mask)) { | |
71 | perror("sched_getaffinity"); | |
72 | return -1; | |
73 | } | |
74 | ||
75 | /* We prefer a primary thread, but skip 0 */ | |
76 | for (cpu = 8; cpu < CPU_SETSIZE; cpu += 8) | |
77 | if (CPU_ISSET(cpu, &mask)) | |
78 | return cpu; | |
79 | ||
80 | /* Search for anything, but in reverse */ | |
81 | for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--) | |
82 | if (CPU_ISSET(cpu, &mask)) | |
83 | return cpu; | |
84 | ||
85 | printf("No cpus in affinity mask?!\n"); | |
86 | return -1; | |
87 | } |