perf: Build with warnings and -Werror
[akaros.git] / tools / profile / 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 ros_get_low_latency_core_set(struct core_set *cores)
22 {
23         for (size_t i = 0; i < COUNT_OF(llcores); i++)
24                 ros_set_bit(cores, llcores[i]);
25 }
26
27 size_t ros_get_low_latency_core_count(void)
28 {
29         return COUNT_OF(llcores);
30 }
31
32 size_t ros_total_cores(void)
33 {
34         return max_vcores() + ros_get_low_latency_core_count();
35 }
36
37 void ros_parse_cores(const char *str, struct core_set *cores)
38 {
39         unsigned int fcpu, ncpu;
40         char *dstr = xstrdup(str);
41         char *sptr = NULL;
42         char *tok, *sptr2;
43
44         ZERO_DATA(*cores);
45         for (tok = strtok_r(dstr, ":", &sptr); tok;
46                  tok = strtok_r(NULL, ":", &sptr)) {
47                 bool neg_core = FALSE;
48
49                 if (*tok == '!') {
50                         neg_core = TRUE;
51                         tok++;
52                 }
53                 if (!strcmp(tok, "all")) {
54                         size_t max_cores = ros_total_cores();
55
56                         if (max_cores > MAX_NUM_CORES) {
57                                 fprintf(stderr, "The number of system CPU exceeds the "
58                                                 "structure limits: num_cores=%u limits=%u\n", max_cores,
59                                                 CHAR_BIT * CORE_SET_SIZE);
60                                 exit(1);
61                         }
62                         if (neg_core)
63                                 memset(cores->core_set, 0,
64                                            DIV_ROUND_UP(max_cores, CHAR_BIT));
65                         else
66                                 memset(cores->core_set, 0xff,
67                                            DIV_ROUND_UP(max_cores, CHAR_BIT));
68                 } else if (!strcmp(tok, "llall")) {
69                         ros_get_low_latency_core_set(cores);
70                 } else if (strchr(tok, '-')) {
71                         if (sscanf(tok, "%u-%u", &fcpu, &ncpu) != 2) {
72                                 fprintf(stderr, "Invalid CPU range: %s\n", tok);
73                                 exit(1);
74                         }
75                         if ((fcpu >= MAX_NUM_CORES) ||
76                                 (ncpu >= MAX_NUM_CORES) || (fcpu > ncpu)) {
77                                 fprintf(stderr, "CPU number out of bound: %u\n",
78                                                 fcpu);
79                                 exit(1);
80                         }
81                         for (; fcpu <= ncpu; fcpu++) {
82                                 if (neg_core)
83                                         ros_clear_bit(cores->core_set, fcpu);
84                                 else
85                                         ros_set_bit(cores->core_set, fcpu);
86                         }
87                 } else {
88                         for (tok = strtok_r(tok, ".", &sptr2); tok;
89                                  tok = strtok_r(NULL, ".", &sptr2)) {
90                                 fcpu = atoi(tok);
91                                 if (fcpu >= MAX_NUM_CORES) {
92                                         fprintf(stderr, "CPU number out of bound: %u\n",
93                                                         fcpu);
94                                         exit(1);
95                                 }
96                                 if (neg_core)
97                                         ros_clear_bit(cores->core_set, fcpu);
98                                 else
99                                         ros_set_bit(cores->core_set, fcpu);
100                         }
101                 }
102         }
103         free(dstr);
104 }
105
106 void ros_get_all_cores_set(struct core_set *cores)
107 {
108         size_t max_cores = ros_total_cores();
109
110         memset(cores->core_set, 0xff, DIV_ROUND_UP(max_cores, CHAR_BIT));
111 }
112
113 void ros_not_core_set(struct core_set *dcs)
114 {
115         size_t max_cores = ros_total_cores();
116
117         for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++) {
118                 size_t nb = (max_cores >= CHAR_BIT) ? CHAR_BIT : max_cores;
119
120                 dcs->core_set[i] = (~dcs->core_set[i]) & ((1 << nb) - 1);
121                 max_cores -= nb;
122         }
123 }
124
125 void ros_and_core_sets(struct core_set *dcs, const struct core_set *scs)
126 {
127         for (size_t i = 0; i < sizeof(dcs->core_set); i++)
128                 dcs->core_set[i] &= scs->core_set[i];
129 }
130
131 void ros_or_core_sets(struct core_set *dcs, const struct core_set *scs)
132 {
133         for (size_t i = 0; i < sizeof(dcs->core_set); i++)
134                 dcs->core_set[i] |= scs->core_set[i];
135 }