Mercurial > hg > CbC > CbC_gcc
comparison liboffloadmic/runtime/offload_env.cpp @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* | |
2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved. | |
3 | |
4 Redistribution and use in source and binary forms, with or without | |
5 modification, are permitted provided that the following conditions | |
6 are met: | |
7 | |
8 * Redistributions of source code must retain the above copyright | |
9 notice, this list of conditions and the following disclaimer. | |
10 * Redistributions in binary form must reproduce the above copyright | |
11 notice, this list of conditions and the following disclaimer in the | |
12 documentation and/or other materials provided with the distribution. | |
13 * Neither the name of Intel Corporation nor the names of its | |
14 contributors may be used to endorse or promote products derived | |
15 from this software without specific prior written permission. | |
16 | |
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
30 | |
31 #include "offload_env.h" | |
32 #include <string.h> | |
33 #include <ctype.h> | |
34 #include "offload_util.h" | |
35 #include "liboffload_error_codes.h" | |
36 | |
37 // for environment variables valid on all cards | |
38 const int MicEnvVar::any_card = -1; | |
39 | |
40 MicEnvVar::~MicEnvVar() | |
41 { | |
42 for (std::list<MicEnvVar::CardEnvVars*>::const_iterator | |
43 it = card_spec_list.begin(); | |
44 it != card_spec_list.end(); it++) { | |
45 CardEnvVars *card_data = *it; | |
46 delete card_data; | |
47 } | |
48 } | |
49 | |
50 MicEnvVar::VarValue::~VarValue() | |
51 { | |
52 free(env_var_value); | |
53 } | |
54 | |
55 MicEnvVar::CardEnvVars::~CardEnvVars() | |
56 { | |
57 for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin(); | |
58 it != env_vars.end(); it++) { | |
59 VarValue *var_value = *it; | |
60 delete var_value; | |
61 } | |
62 } | |
63 | |
64 // Searching for card in "card_spec_list" list with the same "number" | |
65 | |
66 MicEnvVar::CardEnvVars* MicEnvVar::get_card(int number) | |
67 { | |
68 if (number == any_card) { | |
69 return &common_vars; | |
70 } | |
71 for (std::list<MicEnvVar::CardEnvVars*>::const_iterator | |
72 it = card_spec_list.begin(); | |
73 it != card_spec_list.end(); it++) { | |
74 CardEnvVars *card_data = *it; | |
75 if (card_data->card_number == number) { | |
76 return card_data; | |
77 } | |
78 } | |
79 return NULL; | |
80 } | |
81 | |
82 // Searching for environment variable in "env_var" list with the same name | |
83 | |
84 MicEnvVar::VarValue* MicEnvVar::CardEnvVars::find_var( | |
85 char* env_var_name, | |
86 int env_var_name_length | |
87 ) | |
88 { | |
89 for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin(); | |
90 it != env_vars.end(); it++) { | |
91 VarValue *var_value = *it; | |
92 if (var_value->length == env_var_name_length && | |
93 !strncmp(var_value->env_var, env_var_name, | |
94 env_var_name_length)) { | |
95 return var_value; | |
96 } | |
97 } | |
98 return NULL; | |
99 } | |
100 | |
101 void MicEnvVar::analyze_env_var(char *env_var_string) | |
102 { | |
103 char *env_var_name; | |
104 char *env_var_def; | |
105 int card_number; | |
106 int env_var_name_length; | |
107 MicEnvVarKind env_var_kind; | |
108 | |
109 env_var_kind = get_env_var_kind(env_var_string, | |
110 &card_number, | |
111 &env_var_name, | |
112 &env_var_name_length, | |
113 &env_var_def); | |
114 switch (env_var_kind) { | |
115 case c_mic_var: | |
116 case c_mic_card_var: | |
117 add_env_var(card_number, | |
118 env_var_name, | |
119 env_var_name_length, | |
120 env_var_def); | |
121 break; | |
122 case c_mic_card_env: | |
123 mic_parse_env_var_list(card_number, env_var_def); | |
124 break; | |
125 case c_no_mic: | |
126 default: | |
127 break; | |
128 } | |
129 } | |
130 | |
131 void MicEnvVar::add_env_var( | |
132 int card_number, | |
133 char *env_var_name, | |
134 int env_var_name_length, | |
135 char *env_var_def | |
136 ) | |
137 { | |
138 VarValue *var; | |
139 CardEnvVars *card; | |
140 | |
141 // The case corresponds to common env var definition of kind | |
142 // <mic-prefix>_<var> | |
143 if (card_number == any_card) { | |
144 card = &common_vars; | |
145 } | |
146 else { | |
147 card = get_card(card_number); | |
148 if (!card) { | |
149 // definition for new card occurred | |
150 card = new CardEnvVars(card_number); | |
151 card_spec_list.push_back(card); | |
152 } | |
153 | |
154 } | |
155 var = card->find_var(env_var_name, env_var_name_length); | |
156 if (!var) { | |
157 // put new env var definition in "env_var" list | |
158 var = new VarValue(env_var_name, env_var_name_length, env_var_def); | |
159 card->env_vars.push_back(var); | |
160 } | |
161 } | |
162 | |
163 // The routine analyses string pointed by "env_var_string" argument | |
164 // according to the following syntax: | |
165 // | |
166 // Specification of prefix for MIC environment variables | |
167 // MIC_ENV_PREFIX=<mic-prefix> | |
168 // | |
169 // Setting single MIC environment variable | |
170 // <mic-prefix>_<var>=<value> | |
171 // <mic-prefix>_<card-number>_<var>=<value> | |
172 | |
173 // Setting multiple MIC environment variables | |
174 // <mic-prefix>_<card-number>_ENV=<env-vars> | |
175 | |
176 MicEnvVarKind MicEnvVar::get_env_var_kind( | |
177 char *env_var_string, | |
178 int *card_number, | |
179 char **env_var_name, | |
180 int *env_var_name_length, | |
181 char **env_var_def | |
182 ) | |
183 { | |
184 int len = strlen(prefix); | |
185 char *c = env_var_string; | |
186 int num = 0; | |
187 bool card_is_set = false; | |
188 | |
189 if (strncmp(c, prefix, len) != 0 || c[len] != '_') { | |
190 return c_no_mic; | |
191 } | |
192 c += len + 1; | |
193 | |
194 *card_number = any_card; | |
195 if (isdigit(*c)) { | |
196 while (isdigit (*c)) { | |
197 num = (*c++ - '0') + (num * 10); | |
198 } | |
199 if (*c != '_') { | |
200 return c_no_mic; | |
201 } | |
202 c++; | |
203 *card_number = num; | |
204 card_is_set = true; | |
205 } | |
206 if (!isalpha(*c)) { | |
207 return c_no_mic; | |
208 } | |
209 *env_var_name = *env_var_def = c; | |
210 if (strncmp(c, "ENV=", 4) == 0) { | |
211 if (!card_is_set) { | |
212 *env_var_name_length = 3; | |
213 *env_var_name = *env_var_def = c; | |
214 *env_var_def = strdup(*env_var_def); | |
215 if (*env_var_def == NULL) | |
216 LIBOFFLOAD_ERROR(c_malloc); | |
217 return c_mic_var; | |
218 } | |
219 *env_var_def = c + strlen("ENV="); | |
220 *env_var_def = strdup(*env_var_def); | |
221 if (*env_var_def == NULL) | |
222 LIBOFFLOAD_ERROR(c_malloc); | |
223 return c_mic_card_env; | |
224 } | |
225 if (isalpha(*c)) { | |
226 *env_var_name_length = 0; | |
227 while (isalnum(*c) || *c == '_') { | |
228 c++; | |
229 (*env_var_name_length)++; | |
230 } | |
231 } | |
232 if (*c != '=') { | |
233 return c_no_mic; | |
234 } | |
235 *env_var_def = strdup(*env_var_def); | |
236 if (*env_var_def == NULL) | |
237 LIBOFFLOAD_ERROR(c_malloc); | |
238 return card_is_set? c_mic_card_var : c_mic_var; | |
239 } | |
240 | |
241 // analysing <env-vars> in form: | |
242 // <mic-prefix>_<card-number>_ENV=<env-vars> | |
243 // where: | |
244 // | |
245 // <env-vars>: | |
246 // <env-var> | |
247 // <env-vars> | <env-var> | |
248 // | |
249 // <env-var>: | |
250 // variable=value | |
251 // variable="value" | |
252 // variable= | |
253 | |
254 void MicEnvVar::mic_parse_env_var_list( | |
255 int card_number, char *env_vars_def_list) | |
256 { | |
257 char *c = env_vars_def_list; | |
258 char *env_var_name; | |
259 int env_var_name_length; | |
260 char *env_var_def; | |
261 bool var_is_quoted; | |
262 | |
263 if (*c == '"') { | |
264 c++; | |
265 } | |
266 while (*c != 0) { | |
267 var_is_quoted = false; | |
268 env_var_name = c; | |
269 env_var_name_length = 0; | |
270 if (isalpha(*c)) { | |
271 while (isalnum(*c) || *c == '_') { | |
272 c++; | |
273 env_var_name_length++; | |
274 } | |
275 } | |
276 else { | |
277 LIBOFFLOAD_ERROR(c_mic_parse_env_var_list1); | |
278 return; | |
279 } | |
280 if (*c != '=') { | |
281 LIBOFFLOAD_ERROR(c_mic_parse_env_var_list2); | |
282 return; | |
283 } | |
284 c++; | |
285 | |
286 if (*c == '"') { | |
287 var_is_quoted = true; | |
288 c++; | |
289 } | |
290 // Environment variable values that contain | will need to be escaped. | |
291 while (*c != 0 && *c != '|' && | |
292 (!var_is_quoted || *c != '"')) | |
293 { | |
294 // skip escaped symbol | |
295 if (*c == '\\') { | |
296 c++; | |
297 } | |
298 c++; | |
299 } | |
300 if (var_is_quoted) { | |
301 c++; // for " | |
302 while (*c != 0 && *c != '|') { | |
303 c++; | |
304 } | |
305 } | |
306 | |
307 int sz = c - env_var_name; | |
308 env_var_def = (char*)malloc(sz); | |
309 if (env_var_def == NULL) | |
310 LIBOFFLOAD_ERROR(c_malloc); | |
311 memcpy(env_var_def, env_var_name, sz); | |
312 env_var_def[sz] = 0; | |
313 | |
314 if (*c == '|') { | |
315 c++; | |
316 while (*c != 0 && *c == ' ') { | |
317 c++; | |
318 } | |
319 } | |
320 add_env_var(card_number, | |
321 env_var_name, | |
322 env_var_name_length, | |
323 env_var_def); | |
324 } | |
325 } | |
326 | |
327 // Collect all definitions for the card with number "card_num". | |
328 // The returned result is vector of string pointers defining one | |
329 // environment variable. The vector is terminated by NULL pointer. | |
330 // In the beginning of the vector there are env vars defined as | |
331 // <mic-prefix>_<card-number>_<var>=<value> | |
332 // or | |
333 // <mic-prefix>_<card-number>_ENV=<env-vars> | |
334 // where <card-number> is equal to "card_num" | |
335 // They are followed by definitions valid for any card | |
336 // and absent in previous definitions. | |
337 | |
338 char** MicEnvVar::create_environ_for_card(int card_num) | |
339 { | |
340 VarValue *var_value; | |
341 VarValue *var_value_find; | |
342 CardEnvVars *card_data = get_card(card_num); | |
343 CardEnvVars *card_data_common; | |
344 std::list<char*> new_env; | |
345 char **rez; | |
346 | |
347 if (!prefix) { | |
348 return NULL; | |
349 } | |
350 // There is no personel env var definitions for the card with | |
351 // number "card_num" | |
352 if (!card_data) { | |
353 return create_environ_for_card(any_card); | |
354 } | |
355 | |
356 for (std::list<MicEnvVar::VarValue*>::const_iterator | |
357 it = card_data->env_vars.begin(); | |
358 it != card_data->env_vars.end(); it++) { | |
359 var_value = *it; | |
360 new_env.push_back(var_value->env_var_value); | |
361 } | |
362 | |
363 if (card_num != any_card) { | |
364 card_data_common = get_card(any_card); | |
365 for (std::list<MicEnvVar::VarValue*>::const_iterator | |
366 it = card_data_common->env_vars.begin(); | |
367 it != card_data_common->env_vars.end(); it++) { | |
368 var_value = *it; | |
369 var_value_find = card_data->find_var(var_value->env_var, | |
370 var_value->length); | |
371 if (!var_value_find) { | |
372 new_env.push_back(var_value->env_var_value); | |
373 } | |
374 } | |
375 } | |
376 | |
377 int new_env_size = new_env.size(); | |
378 rez = (char**) malloc((new_env_size + 1) * sizeof(char*)); | |
379 if (rez == NULL) | |
380 LIBOFFLOAD_ERROR(c_malloc); | |
381 std::copy(new_env.begin(), new_env.end(), rez); | |
382 rez[new_env_size] = 0; | |
383 return rez; | |
384 } |