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