env.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614
  1. /* Copyright (C) 2005-2022 Free Software Foundation, Inc.
  2. Contributed by Richard Henderson <rth@redhat.com>.
  3. This file is part of the GNU Offloading and Multi Processing Library
  4. (libgomp).
  5. Libgomp is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. more details.
  13. Under Section 7 of GPL version 3, you are granted additional
  14. permissions described in the GCC Runtime Library Exception, version
  15. 3.1, as published by the Free Software Foundation.
  16. You should have received a copy of the GNU General Public License and
  17. a copy of the GCC Runtime Library Exception along with this program;
  18. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. <http://www.gnu.org/licenses/>. */
  20. /* This file defines the OpenMP internal control variables and arranges
  21. for them to be initialized from environment variables at startup. */
  22. #define _GNU_SOURCE
  23. #include "libgomp.h"
  24. #include "gomp-constants.h"
  25. #include <limits.h>
  26. #ifndef LIBGOMP_OFFLOADED_ONLY
  27. #include "libgomp_f.h"
  28. #include "oacc-int.h"
  29. #include <ctype.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #ifdef HAVE_INTTYPES_H
  33. # include <inttypes.h> /* For PRIu64. */
  34. #endif
  35. #ifdef STRING_WITH_STRINGS
  36. # include <string.h>
  37. # include <strings.h>
  38. #else
  39. # ifdef HAVE_STRING_H
  40. # include <string.h>
  41. # else
  42. # ifdef HAVE_STRINGS_H
  43. # include <strings.h>
  44. # endif
  45. # endif
  46. #endif
  47. #include <errno.h>
  48. #include "thread-stacksize.h"
  49. #ifndef HAVE_STRTOULL
  50. # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
  51. #endif
  52. #endif /* LIBGOMP_OFFLOADED_ONLY */
  53. #include "secure_getenv.h"
  54. struct gomp_task_icv gomp_global_icv = {
  55. .nthreads_var = 1,
  56. .thread_limit_var = UINT_MAX,
  57. .run_sched_var = GFS_DYNAMIC,
  58. .run_sched_chunk_size = 1,
  59. .default_device_var = 0,
  60. .dyn_var = false,
  61. .max_active_levels_var = 1,
  62. .bind_var = omp_proc_bind_false,
  63. .target_data = NULL
  64. };
  65. bool gomp_cancel_var = false;
  66. enum gomp_target_offload_t gomp_target_offload_var
  67. = GOMP_TARGET_OFFLOAD_DEFAULT;
  68. int gomp_max_task_priority_var = 0;
  69. #ifndef HAVE_SYNC_BUILTINS
  70. gomp_mutex_t gomp_managed_threads_lock;
  71. #endif
  72. unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1;
  73. unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
  74. unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
  75. char *gomp_bind_var_list;
  76. unsigned long gomp_bind_var_list_len;
  77. void **gomp_places_list;
  78. unsigned long gomp_places_list_len;
  79. uintptr_t gomp_def_allocator = omp_default_mem_alloc;
  80. int gomp_debug_var;
  81. unsigned int gomp_num_teams_var;
  82. int gomp_nteams_var;
  83. int gomp_teams_thread_limit_var;
  84. bool gomp_display_affinity_var;
  85. char *gomp_affinity_format_var = "level %L thread %i affinity %A";
  86. size_t gomp_affinity_format_len;
  87. char *goacc_device_type;
  88. int goacc_device_num;
  89. int goacc_default_dims[GOMP_DIM_MAX];
  90. #ifndef LIBGOMP_OFFLOADED_ONLY
  91. static int wait_policy;
  92. static unsigned long stacksize = GOMP_DEFAULT_STACKSIZE;
  93. /* Parse the OMP_SCHEDULE environment variable. */
  94. static void
  95. parse_schedule (void)
  96. {
  97. char *env, *end;
  98. unsigned long value;
  99. int monotonic = 0;
  100. env = getenv ("OMP_SCHEDULE");
  101. if (env == NULL)
  102. return;
  103. while (isspace ((unsigned char) *env))
  104. ++env;
  105. if (strncasecmp (env, "monotonic", 9) == 0)
  106. {
  107. monotonic = 1;
  108. env += 9;
  109. }
  110. else if (strncasecmp (env, "nonmonotonic", 12) == 0)
  111. {
  112. monotonic = -1;
  113. env += 12;
  114. }
  115. if (monotonic)
  116. {
  117. while (isspace ((unsigned char) *env))
  118. ++env;
  119. if (*env != ':')
  120. goto unknown;
  121. ++env;
  122. while (isspace ((unsigned char) *env))
  123. ++env;
  124. }
  125. if (strncasecmp (env, "static", 6) == 0)
  126. {
  127. gomp_global_icv.run_sched_var = GFS_STATIC;
  128. env += 6;
  129. }
  130. else if (strncasecmp (env, "dynamic", 7) == 0)
  131. {
  132. gomp_global_icv.run_sched_var = GFS_DYNAMIC;
  133. env += 7;
  134. }
  135. else if (strncasecmp (env, "guided", 6) == 0)
  136. {
  137. gomp_global_icv.run_sched_var = GFS_GUIDED;
  138. env += 6;
  139. }
  140. else if (strncasecmp (env, "auto", 4) == 0)
  141. {
  142. gomp_global_icv.run_sched_var = GFS_AUTO;
  143. env += 4;
  144. }
  145. else
  146. goto unknown;
  147. if (monotonic == 1
  148. || (monotonic == 0 && gomp_global_icv.run_sched_var == GFS_STATIC))
  149. gomp_global_icv.run_sched_var |= GFS_MONOTONIC;
  150. while (isspace ((unsigned char) *env))
  151. ++env;
  152. if (*env == '\0')
  153. {
  154. gomp_global_icv.run_sched_chunk_size
  155. = (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC;
  156. return;
  157. }
  158. if (*env++ != ',')
  159. goto unknown;
  160. while (isspace ((unsigned char) *env))
  161. ++env;
  162. if (*env == '\0')
  163. goto invalid;
  164. errno = 0;
  165. value = strtoul (env, &end, 10);
  166. if (errno || end == env)
  167. goto invalid;
  168. while (isspace ((unsigned char) *end))
  169. ++end;
  170. if (*end != '\0')
  171. goto invalid;
  172. if ((int)value != value)
  173. goto invalid;
  174. if (value == 0
  175. && (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC)
  176. value = 1;
  177. gomp_global_icv.run_sched_chunk_size = value;
  178. return;
  179. unknown:
  180. gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
  181. return;
  182. invalid:
  183. gomp_error ("Invalid value for chunk size in "
  184. "environment variable OMP_SCHEDULE");
  185. return;
  186. }
  187. /* Parse an unsigned long environment variable. Return true if one was
  188. present and it was successfully parsed. If SECURE, use secure_getenv to the
  189. environment variable. */
  190. static bool
  191. parse_unsigned_long_1 (const char *name, unsigned long *pvalue, bool allow_zero,
  192. bool secure)
  193. {
  194. char *env, *end;
  195. unsigned long value;
  196. env = (secure ? secure_getenv (name) : getenv (name));
  197. if (env == NULL)
  198. return false;
  199. while (isspace ((unsigned char) *env))
  200. ++env;
  201. if (*env == '\0')
  202. goto invalid;
  203. errno = 0;
  204. value = strtoul (env, &end, 10);
  205. if (errno || end == env || (long) value <= 0 - allow_zero)
  206. goto invalid;
  207. while (isspace ((unsigned char) *end))
  208. ++end;
  209. if (*end != '\0')
  210. goto invalid;
  211. *pvalue = value;
  212. return true;
  213. invalid:
  214. gomp_error ("Invalid value for environment variable %s", name);
  215. return false;
  216. }
  217. /* As parse_unsigned_long_1, but always use getenv. */
  218. static bool
  219. parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero)
  220. {
  221. return parse_unsigned_long_1 (name, pvalue, allow_zero, false);
  222. }
  223. /* Parse a positive int environment variable. Return true if one was
  224. present and it was successfully parsed. If SECURE, use secure_getenv to the
  225. environment variable. */
  226. static bool
  227. parse_int_1 (const char *name, int *pvalue, bool allow_zero, bool secure)
  228. {
  229. unsigned long value;
  230. if (!parse_unsigned_long_1 (name, &value, allow_zero, secure))
  231. return false;
  232. if (value > INT_MAX)
  233. {
  234. gomp_error ("Invalid value for environment variable %s", name);
  235. return false;
  236. }
  237. *pvalue = (int) value;
  238. return true;
  239. }
  240. /* As parse_int_1, but use getenv. */
  241. static bool
  242. parse_int (const char *name, int *pvalue, bool allow_zero)
  243. {
  244. return parse_int_1 (name, pvalue, allow_zero, false);
  245. }
  246. /* As parse_int_1, but use getenv_secure. */
  247. static bool
  248. parse_int_secure (const char *name, int *pvalue, bool allow_zero)
  249. {
  250. return parse_int_1 (name, pvalue, allow_zero, true);
  251. }
  252. /* Parse an unsigned long list environment variable. Return true if one was
  253. present and it was successfully parsed. */
  254. static bool
  255. parse_unsigned_long_list (const char *name, unsigned long *p1stvalue,
  256. unsigned long **pvalues,
  257. unsigned long *pnvalues)
  258. {
  259. char *env, *end;
  260. unsigned long value, *values = NULL;
  261. env = getenv (name);
  262. if (env == NULL)
  263. return false;
  264. while (isspace ((unsigned char) *env))
  265. ++env;
  266. if (*env == '\0')
  267. goto invalid;
  268. errno = 0;
  269. value = strtoul (env, &end, 10);
  270. if (errno || (long) value <= 0)
  271. goto invalid;
  272. while (isspace ((unsigned char) *end))
  273. ++end;
  274. if (*end != '\0')
  275. {
  276. if (*end == ',')
  277. {
  278. unsigned long nvalues = 0, nalloced = 0;
  279. do
  280. {
  281. env = end + 1;
  282. if (nvalues == nalloced)
  283. {
  284. unsigned long *n;
  285. nalloced = nalloced ? nalloced * 2 : 16;
  286. n = realloc (values, nalloced * sizeof (unsigned long));
  287. if (n == NULL)
  288. {
  289. free (values);
  290. gomp_error ("Out of memory while trying to parse"
  291. " environment variable %s", name);
  292. return false;
  293. }
  294. values = n;
  295. if (nvalues == 0)
  296. values[nvalues++] = value;
  297. }
  298. while (isspace ((unsigned char) *env))
  299. ++env;
  300. if (*env == '\0')
  301. goto invalid;
  302. errno = 0;
  303. value = strtoul (env, &end, 10);
  304. if (errno || (long) value <= 0)
  305. goto invalid;
  306. values[nvalues++] = value;
  307. while (isspace ((unsigned char) *end))
  308. ++end;
  309. if (*end == '\0')
  310. break;
  311. if (*end != ',')
  312. goto invalid;
  313. }
  314. while (1);
  315. *p1stvalue = values[0];
  316. *pvalues = values;
  317. *pnvalues = nvalues;
  318. return true;
  319. }
  320. goto invalid;
  321. }
  322. *p1stvalue = value;
  323. return true;
  324. invalid:
  325. free (values);
  326. gomp_error ("Invalid value for environment variable %s", name);
  327. return false;
  328. }
  329. static void
  330. parse_target_offload (const char *name, enum gomp_target_offload_t *offload)
  331. {
  332. const char *env;
  333. int new_offload = -1;
  334. env = getenv (name);
  335. if (env == NULL)
  336. return;
  337. while (isspace ((unsigned char) *env))
  338. ++env;
  339. if (strncasecmp (env, "default", 7) == 0)
  340. {
  341. env += 7;
  342. new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
  343. }
  344. else if (strncasecmp (env, "mandatory", 9) == 0)
  345. {
  346. env += 9;
  347. new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
  348. }
  349. else if (strncasecmp (env, "disabled", 8) == 0)
  350. {
  351. env += 8;
  352. new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
  353. }
  354. while (isspace ((unsigned char) *env))
  355. ++env;
  356. if (new_offload != -1 && *env == '\0')
  357. {
  358. *offload = new_offload;
  359. return;
  360. }
  361. gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
  362. }
  363. /* Parse environment variable set to a boolean or list of omp_proc_bind_t
  364. enum values. Return true if one was present and it was successfully
  365. parsed. */
  366. static bool
  367. parse_bind_var (const char *name, char *p1stvalue,
  368. char **pvalues, unsigned long *pnvalues)
  369. {
  370. char *env;
  371. char value = omp_proc_bind_false, *values = NULL;
  372. int i;
  373. static struct proc_bind_kinds
  374. {
  375. const char name[7];
  376. const char len;
  377. omp_proc_bind_t kind;
  378. } kinds[] =
  379. {
  380. { "false", 5, omp_proc_bind_false },
  381. { "true", 4, omp_proc_bind_true },
  382. { "master", 6, omp_proc_bind_master },
  383. { "primary", 7, omp_proc_bind_primary },
  384. { "close", 5, omp_proc_bind_close },
  385. { "spread", 6, omp_proc_bind_spread }
  386. };
  387. env = getenv (name);
  388. if (env == NULL)
  389. return false;
  390. while (isspace ((unsigned char) *env))
  391. ++env;
  392. if (*env == '\0')
  393. goto invalid;
  394. for (i = 0; i < 6; i++)
  395. if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
  396. {
  397. value = kinds[i].kind;
  398. env += kinds[i].len;
  399. break;
  400. }
  401. if (i == 6)
  402. goto invalid;
  403. while (isspace ((unsigned char) *env))
  404. ++env;
  405. if (*env != '\0')
  406. {
  407. if (*env == ',')
  408. {
  409. unsigned long nvalues = 0, nalloced = 0;
  410. if (value == omp_proc_bind_false
  411. || value == omp_proc_bind_true)
  412. goto invalid;
  413. do
  414. {
  415. env++;
  416. if (nvalues == nalloced)
  417. {
  418. char *n;
  419. nalloced = nalloced ? nalloced * 2 : 16;
  420. n = realloc (values, nalloced);
  421. if (n == NULL)
  422. {
  423. free (values);
  424. gomp_error ("Out of memory while trying to parse"
  425. " environment variable %s", name);
  426. return false;
  427. }
  428. values = n;
  429. if (nvalues == 0)
  430. values[nvalues++] = value;
  431. }
  432. while (isspace ((unsigned char) *env))
  433. ++env;
  434. if (*env == '\0')
  435. goto invalid;
  436. for (i = 2; i < 6; i++)
  437. if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
  438. {
  439. value = kinds[i].kind;
  440. env += kinds[i].len;
  441. break;
  442. }
  443. if (i == 6)
  444. goto invalid;
  445. values[nvalues++] = value;
  446. while (isspace ((unsigned char) *env))
  447. ++env;
  448. if (*env == '\0')
  449. break;
  450. if (*env != ',')
  451. goto invalid;
  452. }
  453. while (1);
  454. *p1stvalue = values[0];
  455. *pvalues = values;
  456. *pnvalues = nvalues;
  457. return true;
  458. }
  459. goto invalid;
  460. }
  461. *p1stvalue = value;
  462. return true;
  463. invalid:
  464. free (values);
  465. gomp_error ("Invalid value for environment variable %s", name);
  466. return false;
  467. }
  468. static bool
  469. parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
  470. long *stridep)
  471. {
  472. char *env = *envp, *start;
  473. void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
  474. unsigned long len = 1;
  475. long stride = 1;
  476. int pass;
  477. bool any_negate = false;
  478. bool has_braces = true;
  479. *negatep = false;
  480. while (isspace ((unsigned char) *env))
  481. ++env;
  482. if (*env == '!')
  483. {
  484. *negatep = true;
  485. ++env;
  486. while (isspace ((unsigned char) *env))
  487. ++env;
  488. }
  489. if (*env != '{')
  490. {
  491. char *end;
  492. unsigned long this_num;
  493. errno = 0;
  494. this_num = strtoul (env, &end, 10);
  495. if (errno || end == env)
  496. return false;
  497. env = end - 1;
  498. has_braces = false;
  499. if (gomp_places_list
  500. && !gomp_affinity_add_cpus (p, this_num, 1, 1, false))
  501. return false;
  502. }
  503. else
  504. {
  505. ++env;
  506. while (isspace ((unsigned char) *env))
  507. ++env;
  508. }
  509. start = env;
  510. for (pass = 0; pass < (any_negate ? 2 : has_braces); pass++)
  511. {
  512. env = start;
  513. do
  514. {
  515. unsigned long this_num, this_len = 1;
  516. long this_stride = 1;
  517. bool this_negate = (*env == '!');
  518. char *end;
  519. if (this_negate)
  520. {
  521. if (gomp_places_list)
  522. any_negate = true;
  523. ++env;
  524. while (isspace ((unsigned char) *env))
  525. ++env;
  526. }
  527. errno = 0;
  528. this_num = strtoul (env, &end, 10);
  529. if (errno || end == env)
  530. return false;
  531. env = end;
  532. while (isspace ((unsigned char) *env))
  533. ++env;
  534. if (*env == ':')
  535. {
  536. ++env;
  537. if (this_negate)
  538. return false;
  539. while (isspace ((unsigned char) *env))
  540. ++env;
  541. errno = 0;
  542. this_len = strtoul (env, &env, 10);
  543. if (errno || this_len == 0)
  544. return false;
  545. while (isspace ((unsigned char) *env))
  546. ++env;
  547. if (*env == ':')
  548. {
  549. ++env;
  550. while (isspace ((unsigned char) *env))
  551. ++env;
  552. errno = 0;
  553. this_stride = strtol (env, &end, 10);
  554. if (errno || end == env)
  555. return false;
  556. env = end;
  557. while (isspace ((unsigned char) *env))
  558. ++env;
  559. }
  560. }
  561. if (gomp_places_list && pass == this_negate)
  562. {
  563. if (this_negate)
  564. {
  565. if (!gomp_affinity_remove_cpu (p, this_num))
  566. return false;
  567. }
  568. else if (!gomp_affinity_add_cpus (p, this_num, this_len,
  569. this_stride, false))
  570. return false;
  571. }
  572. if (*env == '}')
  573. break;
  574. if (*env != ',')
  575. return false;
  576. ++env;
  577. }
  578. while (1);
  579. }
  580. ++env;
  581. while (isspace ((unsigned char) *env))
  582. ++env;
  583. if (*env == ':')
  584. {
  585. char *end;
  586. if (*negatep)
  587. return false;
  588. ++env;
  589. while (isspace ((unsigned char) *env))
  590. ++env;
  591. errno = 0;
  592. len = strtoul (env, &env, 10);
  593. if (errno || len == 0 || len >= 65536)
  594. return false;
  595. while (isspace ((unsigned char) *env))
  596. ++env;
  597. if (*env == ':')
  598. {
  599. ++env;
  600. while (isspace ((unsigned char) *env))
  601. ++env;
  602. errno = 0;
  603. stride = strtol (env, &end, 10);
  604. if (errno || end == env)
  605. return false;
  606. env = end;
  607. while (isspace ((unsigned char) *env))
  608. ++env;
  609. }
  610. }
  611. *envp = env;
  612. *lenp = len;
  613. *stridep = stride;
  614. return true;
  615. }
  616. static bool
  617. parse_places_var (const char *name, bool ignore)
  618. {
  619. char *env = getenv (name), *end;
  620. bool any_negate = false;
  621. int level = 0;
  622. unsigned long count = 0;
  623. if (env == NULL)
  624. return false;
  625. while (isspace ((unsigned char) *env))
  626. ++env;
  627. if (*env == '\0')
  628. goto invalid;
  629. if (strncasecmp (env, "threads", 7) == 0)
  630. {
  631. env += 7;
  632. level = 1;
  633. }
  634. else if (strncasecmp (env, "cores", 5) == 0)
  635. {
  636. env += 5;
  637. level = 2;
  638. }
  639. else if (strncasecmp (env, "sockets", 7) == 0)
  640. {
  641. env += 7;
  642. level = 3;
  643. }
  644. else if (strncasecmp (env, "ll_caches", 9) == 0)
  645. {
  646. env += 9;
  647. level = 4;
  648. }
  649. else if (strncasecmp (env, "numa_domains", 12) == 0)
  650. {
  651. env += 12;
  652. level = 5;
  653. }
  654. if (level)
  655. {
  656. count = ULONG_MAX;
  657. while (isspace ((unsigned char) *env))
  658. ++env;
  659. if (*env != '\0')
  660. {
  661. if (*env++ != '(')
  662. goto invalid;
  663. while (isspace ((unsigned char) *env))
  664. ++env;
  665. errno = 0;
  666. count = strtoul (env, &end, 10);
  667. if (errno || end == env)
  668. goto invalid;
  669. env = end;
  670. while (isspace ((unsigned char) *env))
  671. ++env;
  672. if (*env != ')')
  673. goto invalid;
  674. ++env;
  675. while (isspace ((unsigned char) *env))
  676. ++env;
  677. if (*env != '\0')
  678. goto invalid;
  679. }
  680. if (ignore)
  681. return false;
  682. return gomp_affinity_init_level (level, count, false);
  683. }
  684. count = 0;
  685. end = env;
  686. do
  687. {
  688. bool negate;
  689. unsigned long len;
  690. long stride;
  691. if (!parse_one_place (&end, &negate, &len, &stride))
  692. goto invalid;
  693. if (negate)
  694. {
  695. if (!any_negate)
  696. count++;
  697. any_negate = true;
  698. }
  699. else
  700. count += len;
  701. if (count > 65536)
  702. goto invalid;
  703. if (*end == '\0')
  704. break;
  705. if (*end != ',')
  706. goto invalid;
  707. end++;
  708. }
  709. while (1);
  710. if (ignore)
  711. return false;
  712. gomp_places_list_len = 0;
  713. gomp_places_list = gomp_affinity_alloc (count, false);
  714. if (gomp_places_list == NULL)
  715. return false;
  716. do
  717. {
  718. bool negate;
  719. unsigned long len;
  720. long stride;
  721. gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
  722. if (!parse_one_place (&env, &negate, &len, &stride))
  723. goto invalid;
  724. if (negate)
  725. {
  726. void *p;
  727. for (count = 0; count < gomp_places_list_len; count++)
  728. if (gomp_affinity_same_place
  729. (gomp_places_list[count],
  730. gomp_places_list[gomp_places_list_len]))
  731. break;
  732. if (count == gomp_places_list_len)
  733. {
  734. gomp_error ("Trying to remove a non-existing place from list "
  735. "of places");
  736. goto invalid;
  737. }
  738. p = gomp_places_list[count];
  739. memmove (&gomp_places_list[count],
  740. &gomp_places_list[count + 1],
  741. (gomp_places_list_len - count - 1) * sizeof (void *));
  742. --gomp_places_list_len;
  743. gomp_places_list[gomp_places_list_len] = p;
  744. }
  745. else if (len == 1)
  746. ++gomp_places_list_len;
  747. else
  748. {
  749. for (count = 0; count < len - 1; count++)
  750. if (!gomp_affinity_copy_place
  751. (gomp_places_list[gomp_places_list_len + count + 1],
  752. gomp_places_list[gomp_places_list_len + count],
  753. stride))
  754. goto invalid;
  755. gomp_places_list_len += len;
  756. }
  757. if (*env == '\0')
  758. break;
  759. env++;
  760. }
  761. while (1);
  762. if (gomp_places_list_len == 0)
  763. {
  764. gomp_error ("All places have been removed");
  765. goto invalid;
  766. }
  767. if (!gomp_affinity_finalize_place_list (false))
  768. goto invalid;
  769. return true;
  770. invalid:
  771. free (gomp_places_list);
  772. gomp_places_list = NULL;
  773. gomp_places_list_len = 0;
  774. gomp_error ("Invalid value for environment variable %s", name);
  775. return false;
  776. }
  777. /* Parse the OMP_STACKSIZE environment varible. Return true if one was
  778. present and it was successfully parsed. */
  779. static bool
  780. parse_stacksize (const char *name, unsigned long *pvalue)
  781. {
  782. char *env, *end;
  783. unsigned long value, shift = 10;
  784. env = getenv (name);
  785. if (env == NULL)
  786. return false;
  787. while (isspace ((unsigned char) *env))
  788. ++env;
  789. if (*env == '\0')
  790. goto invalid;
  791. errno = 0;
  792. value = strtoul (env, &end, 10);
  793. if (errno || end == env)
  794. goto invalid;
  795. while (isspace ((unsigned char) *end))
  796. ++end;
  797. if (*end != '\0')
  798. {
  799. switch (tolower ((unsigned char) *end))
  800. {
  801. case 'b':
  802. shift = 0;
  803. break;
  804. case 'k':
  805. break;
  806. case 'm':
  807. shift = 20;
  808. break;
  809. case 'g':
  810. shift = 30;
  811. break;
  812. default:
  813. goto invalid;
  814. }
  815. ++end;
  816. while (isspace ((unsigned char) *end))
  817. ++end;
  818. if (*end != '\0')
  819. goto invalid;
  820. }
  821. if (((value << shift) >> shift) != value)
  822. goto invalid;
  823. *pvalue = value << shift;
  824. return true;
  825. invalid:
  826. gomp_error ("Invalid value for environment variable %s", name);
  827. return false;
  828. }
  829. /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
  830. present and it was successfully parsed. */
  831. static bool
  832. parse_spincount (const char *name, unsigned long long *pvalue)
  833. {
  834. char *env, *end;
  835. unsigned long long value, mult = 1;
  836. env = getenv (name);
  837. if (env == NULL)
  838. return false;
  839. while (isspace ((unsigned char) *env))
  840. ++env;
  841. if (*env == '\0')
  842. goto invalid;
  843. if (strncasecmp (env, "infinite", 8) == 0
  844. || strncasecmp (env, "infinity", 8) == 0)
  845. {
  846. value = ~0ULL;
  847. end = env + 8;
  848. goto check_tail;
  849. }
  850. errno = 0;
  851. value = strtoull (env, &end, 10);
  852. if (errno || end == env)
  853. goto invalid;
  854. while (isspace ((unsigned char) *end))
  855. ++end;
  856. if (*end != '\0')
  857. {
  858. switch (tolower ((unsigned char) *end))
  859. {
  860. case 'k':
  861. mult = 1000LL;
  862. break;
  863. case 'm':
  864. mult = 1000LL * 1000LL;
  865. break;
  866. case 'g':
  867. mult = 1000LL * 1000LL * 1000LL;
  868. break;
  869. case 't':
  870. mult = 1000LL * 1000LL * 1000LL * 1000LL;
  871. break;
  872. default:
  873. goto invalid;
  874. }
  875. ++end;
  876. check_tail:
  877. while (isspace ((unsigned char) *end))
  878. ++end;
  879. if (*end != '\0')
  880. goto invalid;
  881. }
  882. if (value > ~0ULL / mult)
  883. value = ~0ULL;
  884. else
  885. value *= mult;
  886. *pvalue = value;
  887. return true;
  888. invalid:
  889. gomp_error ("Invalid value for environment variable %s", name);
  890. return false;
  891. }
  892. /* Parse a boolean value for environment variable NAME and store the
  893. result in VALUE. Return true if one was present and it was
  894. successfully parsed. */
  895. static bool
  896. parse_boolean (const char *name, bool *value)
  897. {
  898. const char *env;
  899. env = getenv (name);
  900. if (env == NULL)
  901. return false;
  902. while (isspace ((unsigned char) *env))
  903. ++env;
  904. if (strncasecmp (env, "true", 4) == 0)
  905. {
  906. *value = true;
  907. env += 4;
  908. }
  909. else if (strncasecmp (env, "false", 5) == 0)
  910. {
  911. *value = false;
  912. env += 5;
  913. }
  914. else
  915. env = "X";
  916. while (isspace ((unsigned char) *env))
  917. ++env;
  918. if (*env != '\0')
  919. {
  920. gomp_error ("Invalid value for environment variable %s", name);
  921. return false;
  922. }
  923. return true;
  924. }
  925. /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
  926. static int
  927. parse_wait_policy (void)
  928. {
  929. const char *env;
  930. int ret = -1;
  931. env = getenv ("OMP_WAIT_POLICY");
  932. if (env == NULL)
  933. return -1;
  934. while (isspace ((unsigned char) *env))
  935. ++env;
  936. if (strncasecmp (env, "active", 6) == 0)
  937. {
  938. ret = 1;
  939. env += 6;
  940. }
  941. else if (strncasecmp (env, "passive", 7) == 0)
  942. {
  943. ret = 0;
  944. env += 7;
  945. }
  946. else
  947. env = "X";
  948. while (isspace ((unsigned char) *env))
  949. ++env;
  950. if (*env == '\0')
  951. return ret;
  952. gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
  953. return -1;
  954. }
  955. /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
  956. present and it was successfully parsed. */
  957. static bool
  958. parse_affinity (bool ignore)
  959. {
  960. char *env, *end, *start;
  961. int pass;
  962. unsigned long cpu_beg, cpu_end, cpu_stride;
  963. size_t count = 0, needed;
  964. env = getenv ("GOMP_CPU_AFFINITY");
  965. if (env == NULL)
  966. return false;
  967. start = env;
  968. for (pass = 0; pass < 2; pass++)
  969. {
  970. env = start;
  971. if (pass == 1)
  972. {
  973. if (ignore)
  974. return false;
  975. gomp_places_list_len = 0;
  976. gomp_places_list = gomp_affinity_alloc (count, true);
  977. if (gomp_places_list == NULL)
  978. return false;
  979. }
  980. do
  981. {
  982. while (isspace ((unsigned char) *env))
  983. ++env;
  984. errno = 0;
  985. cpu_beg = strtoul (env, &end, 0);
  986. if (errno || end == env || cpu_beg >= 65536)
  987. goto invalid;
  988. cpu_end = cpu_beg;
  989. cpu_stride = 1;
  990. env = end;
  991. if (*env == '-')
  992. {
  993. errno = 0;
  994. cpu_end = strtoul (++env, &end, 0);
  995. if (errno || end == env || cpu_end >= 65536 || cpu_end < cpu_beg)
  996. goto invalid;
  997. env = end;
  998. if (*env == ':')
  999. {
  1000. errno = 0;
  1001. cpu_stride = strtoul (++env, &end, 0);
  1002. if (errno || cpu_stride == 0 || cpu_stride >= 65536)
  1003. goto invalid;
  1004. env = end;
  1005. }
  1006. }
  1007. needed = (cpu_end - cpu_beg) / cpu_stride + 1;
  1008. if (pass == 0)
  1009. count += needed;
  1010. else
  1011. {
  1012. while (needed--)
  1013. {
  1014. void *p = gomp_places_list[gomp_places_list_len];
  1015. gomp_affinity_init_place (p);
  1016. if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
  1017. ++gomp_places_list_len;
  1018. cpu_beg += cpu_stride;
  1019. }
  1020. }
  1021. while (isspace ((unsigned char) *env))
  1022. ++env;
  1023. if (*env == ',')
  1024. env++;
  1025. else if (*env == '\0')
  1026. break;
  1027. }
  1028. while (1);
  1029. }
  1030. if (gomp_places_list_len == 0)
  1031. {
  1032. free (gomp_places_list);
  1033. gomp_places_list = NULL;
  1034. return false;
  1035. }
  1036. return true;
  1037. invalid:
  1038. gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
  1039. return false;
  1040. }
  1041. /* Parse the OMP_ALLOCATOR environment variable and return the value. */
  1042. static uintptr_t
  1043. parse_allocator (void)
  1044. {
  1045. const char *env;
  1046. uintptr_t ret = omp_default_mem_alloc;
  1047. env = getenv ("OMP_ALLOCATOR");
  1048. if (env == NULL)
  1049. return ret;
  1050. while (isspace ((unsigned char) *env))
  1051. ++env;
  1052. if (0)
  1053. ;
  1054. #define C(v) \
  1055. else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
  1056. { \
  1057. ret = v; \
  1058. env += sizeof (#v) - 1; \
  1059. }
  1060. C (omp_default_mem_alloc)
  1061. C (omp_large_cap_mem_alloc)
  1062. C (omp_const_mem_alloc)
  1063. C (omp_high_bw_mem_alloc)
  1064. C (omp_low_lat_mem_alloc)
  1065. C (omp_cgroup_mem_alloc)
  1066. C (omp_pteam_mem_alloc)
  1067. C (omp_thread_mem_alloc)
  1068. #undef C
  1069. else
  1070. env = "X";
  1071. while (isspace ((unsigned char) *env))
  1072. ++env;
  1073. if (*env == '\0')
  1074. return ret;
  1075. gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
  1076. return omp_default_mem_alloc;
  1077. }
  1078. static void
  1079. parse_acc_device_type (void)
  1080. {
  1081. const char *env = getenv ("ACC_DEVICE_TYPE");
  1082. if (env && *env != '\0')
  1083. goacc_device_type = strdup (env);
  1084. else
  1085. goacc_device_type = NULL;
  1086. }
  1087. static void
  1088. parse_gomp_openacc_dim (void)
  1089. {
  1090. /* The syntax is the same as for the -fopenacc-dim compilation option. */
  1091. const char *var_name = "GOMP_OPENACC_DIM";
  1092. const char *env_var = getenv (var_name);
  1093. const char *pos = env_var;
  1094. int i;
  1095. if (!env_var)
  1096. return;
  1097. for (i = 0; *pos && i != GOMP_DIM_MAX; i++)
  1098. {
  1099. char *eptr;
  1100. long val;
  1101. if (i && *pos++ != ':')
  1102. break;
  1103. if (*pos == ':')
  1104. continue;
  1105. errno = 0;
  1106. val = strtol (pos, &eptr, 10);
  1107. if (errno || eptr == pos || val < 0 || (unsigned)val != val)
  1108. break;
  1109. goacc_default_dims[i] = (int)val;
  1110. pos = (const char *) eptr;
  1111. }
  1112. }
  1113. void
  1114. omp_display_env (int verbose)
  1115. {
  1116. int i;
  1117. fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
  1118. fputs (" _OPENMP = '201511'\n", stderr);
  1119. fprintf (stderr, " OMP_DYNAMIC = '%s'\n",
  1120. gomp_global_icv.dyn_var ? "TRUE" : "FALSE");
  1121. fprintf (stderr, " OMP_NESTED = '%s'\n",
  1122. gomp_global_icv.max_active_levels_var > 1 ? "TRUE" : "FALSE");
  1123. fprintf (stderr, " OMP_NUM_THREADS = '%lu", gomp_global_icv.nthreads_var);
  1124. for (i = 1; i < gomp_nthreads_var_list_len; i++)
  1125. fprintf (stderr, ",%lu", gomp_nthreads_var_list[i]);
  1126. fputs ("'\n", stderr);
  1127. fprintf (stderr, " OMP_SCHEDULE = '");
  1128. if ((gomp_global_icv.run_sched_var & GFS_MONOTONIC))
  1129. {
  1130. if (gomp_global_icv.run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
  1131. fputs ("MONOTONIC:", stderr);
  1132. }
  1133. else if (gomp_global_icv.run_sched_var == GFS_STATIC)
  1134. fputs ("NONMONOTONIC:", stderr);
  1135. switch (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC)
  1136. {
  1137. case GFS_RUNTIME:
  1138. fputs ("RUNTIME", stderr);
  1139. if (gomp_global_icv.run_sched_chunk_size != 1)
  1140. fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
  1141. break;
  1142. case GFS_STATIC:
  1143. fputs ("STATIC", stderr);
  1144. if (gomp_global_icv.run_sched_chunk_size != 0)
  1145. fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
  1146. break;
  1147. case GFS_DYNAMIC:
  1148. fputs ("DYNAMIC", stderr);
  1149. if (gomp_global_icv.run_sched_chunk_size != 1)
  1150. fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
  1151. break;
  1152. case GFS_GUIDED:
  1153. fputs ("GUIDED", stderr);
  1154. if (gomp_global_icv.run_sched_chunk_size != 1)
  1155. fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
  1156. break;
  1157. case GFS_AUTO:
  1158. fputs ("AUTO", stderr);
  1159. break;
  1160. }
  1161. fputs ("'\n", stderr);
  1162. fputs (" OMP_PROC_BIND = '", stderr);
  1163. switch (gomp_global_icv.bind_var)
  1164. {
  1165. case omp_proc_bind_false:
  1166. fputs ("FALSE", stderr);
  1167. break;
  1168. case omp_proc_bind_true:
  1169. fputs ("TRUE", stderr);
  1170. break;
  1171. case omp_proc_bind_master:
  1172. fputs ("MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
  1173. break;
  1174. case omp_proc_bind_close:
  1175. fputs ("CLOSE", stderr);
  1176. break;
  1177. case omp_proc_bind_spread:
  1178. fputs ("SPREAD", stderr);
  1179. break;
  1180. }
  1181. for (i = 1; i < gomp_bind_var_list_len; i++)
  1182. switch (gomp_bind_var_list[i])
  1183. {
  1184. case omp_proc_bind_master:
  1185. fputs (",MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
  1186. break;
  1187. case omp_proc_bind_close:
  1188. fputs (",CLOSE", stderr);
  1189. break;
  1190. case omp_proc_bind_spread:
  1191. fputs (",SPREAD", stderr);
  1192. break;
  1193. }
  1194. fputs ("'\n", stderr);
  1195. fputs (" OMP_PLACES = '", stderr);
  1196. for (i = 0; i < gomp_places_list_len; i++)
  1197. {
  1198. fputs ("{", stderr);
  1199. gomp_affinity_print_place (gomp_places_list[i]);
  1200. fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
  1201. }
  1202. fputs ("'\n", stderr);
  1203. fprintf (stderr, " OMP_STACKSIZE = '%lu'\n", stacksize);
  1204. /* GOMP's default value is actually neither active nor passive. */
  1205. fprintf (stderr, " OMP_WAIT_POLICY = '%s'\n",
  1206. wait_policy > 0 ? "ACTIVE" : "PASSIVE");
  1207. fprintf (stderr, " OMP_THREAD_LIMIT = '%u'\n",
  1208. gomp_global_icv.thread_limit_var);
  1209. fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
  1210. gomp_global_icv.max_active_levels_var);
  1211. fprintf (stderr, " OMP_NUM_TEAMS = '%u'\n", gomp_nteams_var);
  1212. fprintf (stderr, " OMP_TEAMS_THREAD_LIMIT = '%u'\n",
  1213. gomp_teams_thread_limit_var);
  1214. fprintf (stderr, " OMP_CANCELLATION = '%s'\n",
  1215. gomp_cancel_var ? "TRUE" : "FALSE");
  1216. fprintf (stderr, " OMP_DEFAULT_DEVICE = '%d'\n",
  1217. gomp_global_icv.default_device_var);
  1218. fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
  1219. gomp_max_task_priority_var);
  1220. fprintf (stderr, " OMP_DISPLAY_AFFINITY = '%s'\n",
  1221. gomp_display_affinity_var ? "TRUE" : "FALSE");
  1222. fprintf (stderr, " OMP_AFFINITY_FORMAT = '%s'\n",
  1223. gomp_affinity_format_var);
  1224. fprintf (stderr, " OMP_ALLOCATOR = '");
  1225. switch (gomp_def_allocator)
  1226. {
  1227. #define C(v) case v: fputs (#v, stderr); break;
  1228. C (omp_default_mem_alloc)
  1229. C (omp_large_cap_mem_alloc)
  1230. C (omp_const_mem_alloc)
  1231. C (omp_high_bw_mem_alloc)
  1232. C (omp_low_lat_mem_alloc)
  1233. C (omp_cgroup_mem_alloc)
  1234. C (omp_pteam_mem_alloc)
  1235. C (omp_thread_mem_alloc)
  1236. #undef C
  1237. default: break;
  1238. }
  1239. fputs ("'\n", stderr);
  1240. fputs (" OMP_TARGET_OFFLOAD = '", stderr);
  1241. switch (gomp_target_offload_var)
  1242. {
  1243. case GOMP_TARGET_OFFLOAD_DEFAULT:
  1244. fputs ("DEFAULT", stderr);
  1245. break;
  1246. case GOMP_TARGET_OFFLOAD_MANDATORY:
  1247. fputs ("MANDATORY", stderr);
  1248. break;
  1249. case GOMP_TARGET_OFFLOAD_DISABLED:
  1250. fputs ("DISABLED", stderr);
  1251. break;
  1252. }
  1253. fputs ("'\n", stderr);
  1254. if (verbose)
  1255. {
  1256. fputs (" GOMP_CPU_AFFINITY = ''\n", stderr);
  1257. fprintf (stderr, " GOMP_STACKSIZE = '%lu'\n", stacksize);
  1258. #ifdef HAVE_INTTYPES_H
  1259. fprintf (stderr, " GOMP_SPINCOUNT = '%"PRIu64"'\n",
  1260. (uint64_t) gomp_spin_count_var);
  1261. #else
  1262. fprintf (stderr, " GOMP_SPINCOUNT = '%lu'\n",
  1263. (unsigned long) gomp_spin_count_var);
  1264. #endif
  1265. }
  1266. fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
  1267. }
  1268. ialias (omp_display_env)
  1269. static void
  1270. handle_omp_display_env (void)
  1271. {
  1272. const char *env;
  1273. bool display = false;
  1274. bool verbose = false;
  1275. env = getenv ("OMP_DISPLAY_ENV");
  1276. if (env == NULL)
  1277. return;
  1278. while (isspace ((unsigned char) *env))
  1279. ++env;
  1280. if (strncasecmp (env, "true", 4) == 0)
  1281. {
  1282. display = true;
  1283. env += 4;
  1284. }
  1285. else if (strncasecmp (env, "false", 5) == 0)
  1286. {
  1287. display = false;
  1288. env += 5;
  1289. }
  1290. else if (strncasecmp (env, "verbose", 7) == 0)
  1291. {
  1292. display = true;
  1293. verbose = true;
  1294. env += 7;
  1295. }
  1296. else
  1297. env = "X";
  1298. while (isspace ((unsigned char) *env))
  1299. ++env;
  1300. if (*env != '\0')
  1301. gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
  1302. if (display)
  1303. ialias_call (omp_display_env) (verbose);
  1304. }
  1305. static void __attribute__((constructor))
  1306. initialize_env (void)
  1307. {
  1308. unsigned long thread_limit_var;
  1309. unsigned long max_active_levels_var;
  1310. /* Do a compile time check that mkomp_h.pl did good job. */
  1311. omp_check_defines ();
  1312. parse_schedule ();
  1313. parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
  1314. parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
  1315. parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
  1316. parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
  1317. parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var);
  1318. parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
  1319. gomp_def_allocator = parse_allocator ();
  1320. if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
  1321. {
  1322. gomp_global_icv.thread_limit_var
  1323. = thread_limit_var > INT_MAX ? UINT_MAX : thread_limit_var;
  1324. }
  1325. parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
  1326. #ifndef HAVE_SYNC_BUILTINS
  1327. gomp_mutex_init (&gomp_managed_threads_lock);
  1328. #endif
  1329. gomp_init_num_threads ();
  1330. gomp_available_cpus = gomp_global_icv.nthreads_var;
  1331. if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
  1332. &gomp_global_icv.nthreads_var,
  1333. &gomp_nthreads_var_list,
  1334. &gomp_nthreads_var_list_len))
  1335. gomp_global_icv.nthreads_var = gomp_available_cpus;
  1336. parse_int ("OMP_NUM_TEAMS", &gomp_nteams_var, false);
  1337. parse_int ("OMP_TEAMS_THREAD_LIMIT", &gomp_teams_thread_limit_var, false);
  1338. bool ignore = false;
  1339. if (parse_bind_var ("OMP_PROC_BIND",
  1340. &gomp_global_icv.bind_var,
  1341. &gomp_bind_var_list,
  1342. &gomp_bind_var_list_len)
  1343. && gomp_global_icv.bind_var == omp_proc_bind_false)
  1344. ignore = true;
  1345. if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
  1346. &max_active_levels_var, true))
  1347. gomp_global_icv.max_active_levels_var
  1348. = (max_active_levels_var > gomp_supported_active_levels)
  1349. ? gomp_supported_active_levels : max_active_levels_var;
  1350. else
  1351. {
  1352. bool nested = true;
  1353. /* OMP_NESTED is deprecated in OpenMP 5.0. */
  1354. if (parse_boolean ("OMP_NESTED", &nested))
  1355. gomp_global_icv.max_active_levels_var
  1356. = nested ? gomp_supported_active_levels : 1;
  1357. else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
  1358. gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
  1359. }
  1360. /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
  1361. parsed if present in the environment. If OMP_PROC_BIND was set
  1362. explicitly to false, don't populate places list though. If places
  1363. list was successfully set from OMP_PLACES, only parse but don't process
  1364. GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
  1365. default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
  1366. was successfully parsed into a places list, otherwise to
  1367. OMP_PROC_BIND=false. */
  1368. if (parse_places_var ("OMP_PLACES", ignore))
  1369. {
  1370. if (gomp_global_icv.bind_var == omp_proc_bind_false)
  1371. gomp_global_icv.bind_var = true;
  1372. ignore = true;
  1373. }
  1374. if (parse_affinity (ignore))
  1375. {
  1376. if (gomp_global_icv.bind_var == omp_proc_bind_false)
  1377. gomp_global_icv.bind_var = true;
  1378. ignore = true;
  1379. }
  1380. if (gomp_global_icv.bind_var != omp_proc_bind_false)
  1381. gomp_init_affinity ();
  1382. {
  1383. const char *env = getenv ("OMP_AFFINITY_FORMAT");
  1384. if (env != NULL)
  1385. gomp_set_affinity_format (env, strlen (env));
  1386. }
  1387. wait_policy = parse_wait_policy ();
  1388. if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
  1389. {
  1390. /* Using a rough estimation of 100000 spins per msec,
  1391. use 5 min blocking for OMP_WAIT_POLICY=active,
  1392. 3 msec blocking when OMP_WAIT_POLICY is not specificed
  1393. and 0 when OMP_WAIT_POLICY=passive.
  1394. Depending on the CPU speed, this can be e.g. 5 times longer
  1395. or 5 times shorter. */
  1396. if (wait_policy > 0)
  1397. gomp_spin_count_var = 30000000000LL;
  1398. else if (wait_policy < 0)
  1399. gomp_spin_count_var = 300000LL;
  1400. }
  1401. /* gomp_throttled_spin_count_var is used when there are more libgomp
  1402. managed threads than available CPUs. Use very short spinning. */
  1403. if (wait_policy > 0)
  1404. gomp_throttled_spin_count_var = 1000LL;
  1405. else if (wait_policy < 0)
  1406. gomp_throttled_spin_count_var = 100LL;
  1407. if (gomp_throttled_spin_count_var > gomp_spin_count_var)
  1408. gomp_throttled_spin_count_var = gomp_spin_count_var;
  1409. /* Not strictly environment related, but ordering constructors is tricky. */
  1410. pthread_attr_init (&gomp_thread_attr);
  1411. if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
  1412. || parse_stacksize ("GOMP_STACKSIZE", &stacksize)
  1413. || GOMP_DEFAULT_STACKSIZE)
  1414. {
  1415. int err;
  1416. err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
  1417. #ifdef PTHREAD_STACK_MIN
  1418. if (err == EINVAL)
  1419. {
  1420. if (stacksize < PTHREAD_STACK_MIN)
  1421. gomp_error ("Stack size less than minimum of %luk",
  1422. PTHREAD_STACK_MIN / 1024ul
  1423. + (PTHREAD_STACK_MIN % 1024 != 0));
  1424. else
  1425. gomp_error ("Stack size larger than system limit");
  1426. }
  1427. else
  1428. #endif
  1429. if (err != 0)
  1430. gomp_error ("Stack size change failed: %s", strerror (err));
  1431. }
  1432. handle_omp_display_env ();
  1433. /* OpenACC. */
  1434. if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num, true))
  1435. goacc_device_num = 0;
  1436. parse_acc_device_type ();
  1437. parse_gomp_openacc_dim ();
  1438. goacc_runtime_initialize ();
  1439. goacc_profiling_initialize ();
  1440. }
  1441. #endif /* LIBGOMP_OFFLOADED_ONLY */