perf: Rename the ros_ core_set code
[akaros.git] / tools / dev-util / perf / akaros.c
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #include <ros/arch/arch.h>
7 #include <ros/common.h>
8 #include <sys/types.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <parlib/parlib.h>
14 #include "xlib.h"
15 #include "akaros.h"
16
17 static const unsigned int llcores[] = {
18         0
19 };
20
21 void parlib_get_ll_core_set(struct core_set *cores)
22 {
23         parlib_get_none_core_set(cores);
24         for (size_t i = 0; i < COUNT_OF(llcores); i++)
25                 parlib_set_core(cores, llcores[i]);
26 }
27
28 size_t parlib_nr_ll_cores(void)
29 {
30         return COUNT_OF(llcores);
31 }
32
33 static int guess_nr_cores(void)
34 {
35         return max_vcores() + parlib_nr_ll_cores();
36 }
37
38 static int get_vars_nr_cores(void)
39 {
40         int fd, ret;
41         char buf[10];
42
43         fd = xopen("#vars/num_cores!dw", O_READ, 0);
44         if (fd < 0)
45                 return -1;
46         if (read(fd, buf, sizeof(buf)) <= 0) {
47                 close(fd);
48                 return -1;
49         }
50         ret = atoi(buf);
51         return ret;
52 }
53
54 static int nr_cores;
55
56 static void set_nr_cores(void *arg)
57 {
58         nr_cores = get_vars_nr_cores();
59         if (nr_cores == -1)
60                 nr_cores = guess_nr_cores();
61 }
62
63 size_t parlib_nr_total_cores(void)
64 {
65         static parlib_once_t once = PARLIB_ONCE_INIT;
66
67         parlib_run_once(&once, set_nr_cores, NULL);
68         return nr_cores;
69 }
70
71 void parlib_parse_cores(const char *str, struct core_set *cores)
72 {
73         unsigned int fcpu, ncpu;
74         char *dstr = xstrdup(str);
75         char *sptr = NULL;
76         char *tok, *sptr2;
77
78         ZERO_DATA(*cores);
79         for (tok = strtok_r(dstr, ",", &sptr); tok;
80                  tok = strtok_r(NULL, ",", &sptr)) {
81
82                 if (strchr(tok, '-')) {
83                         if (sscanf(tok, "%u-%u", &fcpu, &ncpu) != 2) {
84                                 fprintf(stderr, "Invalid CPU range: %s\n", tok);
85                                 exit(1);
86                         }
87                         if (fcpu >= parlib_nr_total_cores()) {
88                                 fprintf(stderr, "CPU number out of bound: %u\n", fcpu);
89                                 exit(1);
90                         }
91                         if (ncpu >= parlib_nr_total_cores()) {
92                                 fprintf(stderr, "CPU number out of bound: %u\n", ncpu);
93                                 exit(1);
94                         }
95                         if (fcpu > ncpu) {
96                                 fprintf(stderr, "CPU range is backwards: %u-%u\n", fcpu, ncpu);
97                                 exit(1);
98                         }
99                         for (; fcpu <= ncpu; fcpu++)
100                                 parlib_set_core(cores, fcpu);
101                 } else {
102                         fcpu = atoi(tok);
103                         if (fcpu >= parlib_nr_total_cores()) {
104                                 fprintf(stderr, "CPU number out of bound: %u\n",
105                                                 fcpu);
106                                 exit(1);
107                         }
108                         parlib_set_core(cores, fcpu);
109                 }
110         }
111         free(dstr);
112 }
113
114 void parlib_get_all_core_set(struct core_set *cores)
115 {
116         size_t max_cores = parlib_nr_total_cores();
117
118         memset(cores->core_set, 0xff, DIV_ROUND_UP(max_cores, CHAR_BIT));
119 }
120
121 void parlib_get_none_core_set(struct core_set *cores)
122 {
123         size_t max_cores = parlib_nr_total_cores();
124
125         memset(cores->core_set, 0, DIV_ROUND_UP(max_cores, CHAR_BIT));
126 }
127
128 void parlib_not_core_set(struct core_set *dcs)
129 {
130         size_t max_cores = parlib_nr_total_cores();
131
132         for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++) {
133                 size_t nb = (max_cores >= CHAR_BIT) ? CHAR_BIT : max_cores;
134
135                 dcs->core_set[i] = (~dcs->core_set[i]) & ((1 << nb) - 1);
136                 max_cores -= nb;
137         }
138 }
139
140 void parlib_and_core_sets(struct core_set *dcs, const struct core_set *scs)
141 {
142         for (size_t i = 0; i < sizeof(dcs->core_set); i++)
143                 dcs->core_set[i] &= scs->core_set[i];
144 }
145
146 void parlib_or_core_sets(struct core_set *dcs, const struct core_set *scs)
147 {
148         for (size_t i = 0; i < sizeof(dcs->core_set); i++)
149                 dcs->core_set[i] |= scs->core_set[i];
150 }