15#include "kmp_device_env.h"
25static char const *
const __kmp_device_env_eligible_names[] = {
32static char const *
const __kmp_device_env_denied_bases[] = {
34 "OMP_MAX_TASK_PRIORITY",
37 "OMP_DISPLAY_AFFINITY",
38 "OMP_AFFINITY_FORMAT",
42 "OMP_TOOL_VERBOSE_INIT",
47struct kmp_device_env_dev_node_t {
50 struct kmp_device_env_dev_node_t *next;
53struct kmp_device_env_state_t {
55 char *dev_default_value;
56 kmp_device_env_dev_node_t *per_device;
59static kmp_device_env_state_t *__kmp_device_env_states = NULL;
61static int __kmp_device_env_count(
void) {
62 return sizeof(__kmp_device_env_eligible_names) /
63 sizeof(__kmp_device_env_eligible_names[0]) -
71static void __kmp_device_env_assert_tables_disjoint(
void) {
73 for (
int i = 0; __kmp_device_env_eligible_names[i] != NULL; ++i) {
74 for (
int j = 0; __kmp_device_env_denied_bases[j] != NULL; ++j) {
75 KMP_DEBUG_ASSERT(strcmp(__kmp_device_env_eligible_names[i],
76 __kmp_device_env_denied_bases[j]) != 0);
82static void __kmp_device_env_lazy_init(
void) {
83 if (__kmp_device_env_states != NULL)
85 __kmp_device_env_assert_tables_disjoint();
86 int count = __kmp_device_env_count();
87 __kmp_device_env_states = (kmp_device_env_state_t *)KMP_INTERNAL_MALLOC(
88 sizeof(kmp_device_env_state_t) * count);
89 for (
int i = 0; i < count; ++i) {
90 __kmp_device_env_states[i].all_value = NULL;
91 __kmp_device_env_states[i].dev_default_value = NULL;
92 __kmp_device_env_states[i].per_device = NULL;
96static int __kmp_device_env_index(
char const *base_name) {
97 if (base_name == NULL)
99 for (
int i = 0; __kmp_device_env_eligible_names[i] != NULL; ++i)
100 if (strcmp(__kmp_device_env_eligible_names[i], base_name) == 0)
105extern "C" char const *__kmp_device_env_eligible_name(
int index) {
108 int count = __kmp_device_env_count();
111 return __kmp_device_env_eligible_names[index];
116static char const *__kmp_strip_prefix_and_suffix(
char const *full_name,
117 char const *base_name,
118 char const *suffix) {
119 size_t base_len = strlen(base_name);
120 if (strncmp(full_name, base_name, base_len) != 0)
122 char const *rest = full_name + base_len;
123 size_t sfx_len = strlen(suffix);
124 if (strncmp(rest, suffix, sfx_len) != 0)
126 return rest + sfx_len;
130static int __kmp_is_nonneg_int(
char const *s) {
131 if (s == NULL || *s ==
'\0')
133 for (
char const *p = s; *p; ++p) {
134 if (*p <
'0' || *p >
'9')
143static int __kmp_parse_dev_id(
char const *s) {
144 if (!__kmp_is_nonneg_int(s))
147 for (
char const *p = s; *p; ++p) {
148 v = v * 10 + (*p -
'0');
149 if (v >= (
long long)INT_MAX)
155enum kmp_dev_env_kind_t {
156 kmp_dev_env_none = 0,
158 kmp_dev_env_dev_default,
167static kmp_dev_env_kind_t
168__kmp_match_suffix(
char const *full_name,
char const *base,
int *out_dev_id) {
170 if (
char const *tail = __kmp_strip_prefix_and_suffix(full_name, base,
"_ALL"))
172 return kmp_dev_env_all;
173 if (
char const *tail =
174 __kmp_strip_prefix_and_suffix(full_name, base,
"_DEV_")) {
175 int dev_id = __kmp_parse_dev_id(tail);
176 *out_dev_id = dev_id;
177 return kmp_dev_env_dev_id;
179 if (
char const *tail = __kmp_strip_prefix_and_suffix(full_name, base,
"_DEV"))
181 return kmp_dev_env_dev_default;
182 return kmp_dev_env_none;
196static kmp_dev_env_kind_t __kmp_classify_device_env_name(
char const *full_name,
202 if (full_name == NULL || *full_name ==
'\0')
203 return kmp_dev_env_none;
206 for (
int i = 0; __kmp_device_env_eligible_names[i] != NULL; ++i) {
207 char const *base = __kmp_device_env_eligible_names[i];
209 kmp_dev_env_kind_t k = __kmp_match_suffix(full_name, base, &dev_id);
210 if (k != kmp_dev_env_none) {
212 *out_dev_id = dev_id;
221 for (
int i = 0; __kmp_device_env_denied_bases[i] != NULL; ++i) {
222 char const *base = __kmp_device_env_denied_bases[i];
224 kmp_dev_env_kind_t k = __kmp_match_suffix(full_name, base, &dev_id);
225 if (k != kmp_dev_env_none)
229 return kmp_dev_env_none;
232static void __kmp_device_env_set_string(
char **slot,
char const *value) {
234 __kmp_str_free(slot);
236 *slot = __kmp_str_format(
"%s", value);
239static void __kmp_device_env_set_per_device(kmp_device_env_state_t *st,
240 int device_id,
char const *value) {
241 for (kmp_device_env_dev_node_t *n = st->per_device; n != NULL; n = n->next) {
242 if (n->device_id == device_id) {
243 __kmp_str_free(&n->value);
244 n->value = __kmp_str_format(
"%s", value);
248 kmp_device_env_dev_node_t *node =
249 (kmp_device_env_dev_node_t *)KMP_INTERNAL_MALLOC(
250 sizeof(kmp_device_env_dev_node_t));
251 node->device_id = device_id;
252 node->value = __kmp_str_format(
"%s", value);
253 node->next = st->per_device;
254 st->per_device = node;
257extern "C" int __kmp_device_env_record(
char const *full_name,
259 if (full_name == NULL || value == NULL)
264 kmp_dev_env_kind_t kind =
265 __kmp_classify_device_env_name(full_name, &idx, &dev_id);
266 if (kind == kmp_dev_env_none)
272 KMP_WARNING(DeviceEnvVarOnGlobalScope, full_name);
278 if (kind == kmp_dev_env_dev_id && dev_id < 0) {
279 KMP_WARNING(MalformedDeviceEnvVar, full_name);
283 __kmp_device_env_lazy_init();
284 kmp_device_env_state_t *st = &__kmp_device_env_states[idx];
287 case kmp_dev_env_all:
288 __kmp_device_env_set_string(&st->all_value, value);
290 case kmp_dev_env_dev_default:
291 __kmp_device_env_set_string(&st->dev_default_value, value);
293 case kmp_dev_env_dev_id:
294 __kmp_device_env_set_per_device(st, dev_id, value);
296 case kmp_dev_env_none:
304static kmp_device_env_state_t *__kmp_device_env_lookup(
char const *base_name) {
305 int idx = __kmp_device_env_index(base_name);
306 if (idx < 0 || __kmp_device_env_states == NULL)
308 return &__kmp_device_env_states[idx];
311extern "C" char const *__kmpc_get_device_env(
char const *base_name,
315 KMP_DEBUG_ASSERT(device_id >= 0);
318 kmp_device_env_state_t *st = __kmp_device_env_lookup(base_name);
323 for (kmp_device_env_dev_node_t *n = st->per_device; n != NULL; n = n->next) {
324 if (n->device_id == device_id)
327 if (st->dev_default_value != NULL)
328 return st->dev_default_value;
329 if (st->all_value != NULL)
330 return st->all_value;
334extern "C" void __kmp_device_env_reset(
void) {
335 if (__kmp_device_env_states == NULL)
337 int count = __kmp_device_env_count();
338 for (
int i = 0; i < count; ++i) {
339 kmp_device_env_state_t *st = &__kmp_device_env_states[i];
340 __kmp_str_free(&st->all_value);
341 __kmp_str_free(&st->dev_default_value);
342 kmp_device_env_dev_node_t *n = st->per_device;
344 kmp_device_env_dev_node_t *next = n->next;
345 __kmp_str_free(&n->value);
346 KMP_INTERNAL_FREE(n);
349 st->per_device = NULL;
351 KMP_INTERNAL_FREE(__kmp_device_env_states);
352 __kmp_device_env_states = NULL;