3ae2a22568aac86bf65f10d55b7a96ffef6c5b1d
[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 static int guess_nr_cores(void)
33 {
34         return max_vcores() + ros_get_low_latency_core_count();
35 }
36
37 static int get_vars_nr_cores(void)
38 {
39         int fd, ret;
40         char buf[10];
41
42         fd = xopen("#vars/num_cores!dw", O_READ, 0);
43         if (fd < 0)
44                 return -1;
45         if (read(fd, buf, sizeof(buf)) <= 0) {
46                 close(fd);
47                 return -1;
48         }
49         ret = atoi(buf);
50         return ret;
51 }
52
53 static int nr_cores;
54
55 static void set_nr_cores(void)
56 {
57         nr_cores = get_vars_nr_cores();
58         if (nr_cores == -1)
59                 nr_cores = guess_nr_cores();
60 }
61
62
63 size_t ros_total_cores(void)
64 {
65         run_once(set_nr_cores());
66         return nr_cores;
67 }
68
69 void ros_parse_cores(const char *str, struct core_set *cores)
70 {
71         unsigned int fcpu, ncpu;
72         char *dstr = xstrdup(str);
73         char *sptr = NULL;
74         char *tok, *sptr2;
75
76         ZERO_DATA(*cores);
77         for (tok = strtok_r(dstr, ",", &sptr); tok;
78                  tok = strtok_r(NULL, ",", &sptr)) {
79
80                 if (strchr(tok, '-')) {
81                         if (sscanf(tok, "%u-%u", &fcpu, &ncpu) != 2) {
82                                 fprintf(stderr, "Invalid CPU range: %s\n", tok);
83                                 exit(1);
84                         }
85                         if (fcpu >= ros_total_cores()) {
86                                 fprintf(stderr, "CPU number out of bound: %u\n", fcpu);
87                                 exit(1);
88                         }
89                         if (ncpu >= ros_total_cores()) {
90                                 fprintf(stderr, "CPU number out of bound: %u\n", ncpu);
91                                 exit(1);
92                         }
93                         if (fcpu > ncpu) {
94                                 fprintf(stderr, "CPU range is backwards: %u-%u\n", fcpu, ncpu);
95                                 exit(1);
96                         }
97                         for (; fcpu <= ncpu; fcpu++)
98                                 ros_set_bit(cores->core_set, fcpu);
99                 } else {
100                         fcpu = atoi(tok);
101                         if (fcpu >= ros_total_cores()) {
102                                 fprintf(stderr, "CPU number out of bound: %u\n",
103                                                 fcpu);
104                                 exit(1);
105                         }
106                         ros_set_bit(cores->core_set, fcpu);
107                 }
108         }
109         free(dstr);
110 }
111
112 void ros_get_all_cores_set(struct core_set *cores)
113 {
114         size_t max_cores = ros_total_cores();
115
116         memset(cores->core_set, 0xff, DIV_ROUND_UP(max_cores, CHAR_BIT));
117 }
118
119 void ros_not_core_set(struct core_set *dcs)
120 {
121         size_t max_cores = ros_total_cores();
122
123         for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++) {
124                 size_t nb = (max_cores >= CHAR_BIT) ? CHAR_BIT : max_cores;
125
126                 dcs->core_set[i] = (~dcs->core_set[i]) & ((1 << nb) - 1);
127                 max_cores -= nb;
128         }
129 }
130
131 void ros_and_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 }
136
137 void ros_or_core_sets(struct core_set *dcs, const struct core_set *scs)
138 {
139         for (size_t i = 0; i < sizeof(dcs->core_set); i++)
140                 dcs->core_set[i] |= scs->core_set[i];
141 }