ARGOBOTS  c74c160e507a09d5a75aae06b1b52704643c33ca
config.c
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #include "abti.h"
7 
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <string.h>
11 
12 static inline size_t sched_config_type_size(ABT_sched_config_type type);
13 ABTU_ret_err static int sched_config_get(const ABTI_sched_config *p_config,
14  int idx, ABT_sched_config_type *p_type,
15  void *p_val);
16 ABTU_ret_err static int sched_config_set(ABTI_sched_config *p_config, int idx,
18  const void *p_val);
19 static void sched_config_free(ABTI_sched_config *p_config);
20 
25 /* Global configurable parameters */
27  .type =
29 
31  .type = ABT_SCHED_CONFIG_INT };
32 
34  .type =
36 
38  .type = ABT_SCHED_CONFIG_INT };
39 
106 {
107  ABTI_UB_ASSERT(ABTI_initialized());
108 
109  int abt_errno;
110  int i = 0;
111  ABTI_sched_config *p_config;
112 
113  abt_errno = ABTU_calloc(1, sizeof(ABTI_sched_config), (void **)&p_config);
114  ABTI_CHECK_ERROR(abt_errno);
115  /* Initialize index. */
116 
117  for (i = 0; i < ABTI_SCHED_CONFIG_HTABLE_SIZE; i++) {
118  p_config->elements[i].idx = ABTI_SCHED_CONFIG_UNUSED_INDEX;
119  }
120 
121  va_list varg_list;
122  va_start(varg_list, config);
123 
124  /* We read (var, value) until we find ABT_sched_config_var_end */
125  while (1) {
126  ABT_sched_config_var var = va_arg(varg_list, ABT_sched_config_var);
127  int idx = var.idx;
128  if (idx == ABT_sched_config_var_end.idx)
129  break;
130  /* Add the argument */
131  switch (var.type) {
132  case ABT_SCHED_CONFIG_INT: {
133  int int_val = va_arg(varg_list, int);
134  abt_errno = sched_config_set(p_config, idx,
135  ABT_SCHED_CONFIG_INT, &int_val);
136  break;
137  }
139  double double_val = va_arg(varg_list, double);
140  abt_errno =
142  &double_val);
143  break;
144  }
145  case ABT_SCHED_CONFIG_PTR: {
146  void *ptr_val = va_arg(varg_list, void *);
147  abt_errno = sched_config_set(p_config, idx,
148  ABT_SCHED_CONFIG_PTR, &ptr_val);
149  break;
150  }
151  default:
152  abt_errno = ABT_ERR_INV_ARG;
153  }
154  if (abt_errno != ABT_SUCCESS) {
155  sched_config_free(p_config);
156  va_end(varg_list);
157  ABTI_HANDLE_ERROR(abt_errno);
158  }
159  }
160  va_end(varg_list);
161 
162  *config = ABTI_sched_config_get_handle(p_config);
163  return ABT_SUCCESS;
164 }
165 
205 int ABT_sched_config_read(ABT_sched_config config, int num_vars, ...)
206 {
207  ABTI_UB_ASSERT(ABTI_initialized());
208 
209  int idx;
210  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
211  ABTI_CHECK_NULL_SCHED_CONFIG_PTR(p_config);
212 
213  va_list varg_list;
214  va_start(varg_list, num_vars);
215  for (idx = 0; idx < num_vars; idx++) {
216  void *ptr = va_arg(varg_list, void *);
217  if (ptr) {
218  int abt_errno = sched_config_get(p_config, idx, NULL, ptr);
219  /* It's okay even if there's no associated value. */
220  (void)abt_errno;
221  }
222  }
223  va_end(varg_list);
224  return ABT_SUCCESS;
225 }
226 
251 {
252  ABTI_UB_ASSERT(ABTI_initialized());
253 
254  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(*config);
255  ABTI_CHECK_NULL_SCHED_CONFIG_PTR(p_config);
256 
257  sched_config_free(p_config);
258 
259  *config = ABT_SCHED_CONFIG_NULL;
260 
261  return ABT_SUCCESS;
262 }
263 
309  ABT_sched_config_type type, const void *val)
310 {
311  ABTI_UB_ASSERT(ABTI_initialized());
312 
313  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
314  ABTI_CHECK_NULL_SCHED_CONFIG_PTR(p_config);
315  int abt_errno = sched_config_set(p_config, idx, type, val);
316  ABTI_CHECK_ERROR(abt_errno);
317  return ABT_SUCCESS;
318 }
319 
359  ABT_sched_config_type *type, void *val)
360 {
361  ABTI_UB_ASSERT(ABTI_initialized());
362 
363  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
364  ABTI_CHECK_NULL_SCHED_CONFIG_PTR(p_config);
365  int abt_errno = sched_config_get(p_config, idx, type, val);
366  ABTI_CHECK_ERROR(abt_errno);
367  return ABT_SUCCESS;
368 }
369 
370 /*****************************************************************************/
371 /* Private APIs */
372 /*****************************************************************************/
373 
374 ABTU_ret_err int ABTI_sched_config_read(const ABTI_sched_config *p_config,
375  int idx, void *p_val)
376 {
377  return sched_config_get(p_config, idx, NULL, p_val);
378 }
379 
380 /*****************************************************************************/
381 /* Internal static functions */
382 /*****************************************************************************/
383 
384 ABTU_ret_err static int sched_config_get(const ABTI_sched_config *p_config,
385  int idx, ABT_sched_config_type *p_type,
386  void *p_val)
387 {
388  int table_index = ((idx % ABTI_SCHED_CONFIG_HTABLE_SIZE) +
389  ABTI_SCHED_CONFIG_HTABLE_SIZE) %
390  ABTI_SCHED_CONFIG_HTABLE_SIZE;
391  if (p_config->elements[table_index].idx == ABTI_SCHED_CONFIG_UNUSED_INDEX) {
392  return ABT_ERR_INV_ARG;
393  } else {
394  const ABTI_sched_config_element *p_element =
395  &p_config->elements[table_index];
396  while (p_element) {
397  if (p_element->idx == idx) {
398  if (p_val) {
399  memcpy(p_val, p_element->val,
400  sched_config_type_size(p_element->type));
401  }
402  if (p_type) {
403  *p_type = p_element->type;
404  }
405  return ABT_SUCCESS;
406  } else {
407  p_element = p_element->p_next;
408  }
409  }
410  return ABT_ERR_INV_ARG;
411  }
412 }
413 
414 ABTU_ret_err static int sched_config_set(ABTI_sched_config *p_config, int idx,
416  const void *p_val)
417 {
418  int table_index = ((idx % ABTI_SCHED_CONFIG_HTABLE_SIZE) +
419  ABTI_SCHED_CONFIG_HTABLE_SIZE) %
420  ABTI_SCHED_CONFIG_HTABLE_SIZE;
421  if (p_config->elements[table_index].idx == ABTI_SCHED_CONFIG_UNUSED_INDEX) {
422  if (p_val) {
423  /* Newly add. */
424  p_config->elements[table_index].idx = idx;
425  p_config->elements[table_index].type = type;
426  memcpy(p_config->elements[table_index].val, p_val,
427  sched_config_type_size(type));
428  }
429  } else {
430  ABTI_sched_config_element *p_element = &p_config->elements[table_index];
431  ABTI_sched_config_element **pp_element = NULL;
432  while (p_element) {
433  if (p_element->idx == idx) {
434  if (p_val) {
435  /* Update. */
436  p_element->type = type;
437  memcpy(p_element->val, p_val, sched_config_type_size(type));
438  } else {
439  /* Remove the element. */
440  if (pp_element) {
441  *pp_element = p_element->p_next;
442  ABTU_free(p_element);
443  } else {
444  ABTI_sched_config_element *p_next = p_element->p_next;
445  if (p_next) {
446  memcpy(p_element, p_next,
447  sizeof(ABTI_sched_config_element));
448  ABTU_free(p_next);
449  } else {
450  p_element->idx = ABTI_SCHED_CONFIG_UNUSED_INDEX;
451  }
452  }
453  }
454  break;
455  } else if (!p_element->p_next) {
456  if (p_val) {
457  /* Newly add. */
458  ABTI_sched_config_element *p_new_element;
459  int abt_errno =
460  ABTU_calloc(1, sizeof(ABTI_sched_config_element),
461  (void **)&p_new_element);
462  ABTI_CHECK_ERROR(abt_errno);
463  p_new_element->idx = idx;
464  p_new_element->type = type;
465  memcpy(p_new_element->val, p_val,
466  sched_config_type_size(type));
467  p_element->p_next = p_new_element;
468  }
469  break;
470  } else {
471  pp_element = &p_element->p_next;
472  p_element = *pp_element;
473  }
474  }
475  }
476  return ABT_SUCCESS;
477 }
478 
479 static void sched_config_free(ABTI_sched_config *p_config)
480 {
481  /* Check elements. */
482  int i;
483  for (i = 0; i < ABTI_SCHED_CONFIG_HTABLE_SIZE; i++) {
484  ABTI_sched_config_element *p_element = p_config->elements[i].p_next;
485  while (p_element) {
486  ABTI_sched_config_element *p_next = p_element->p_next;
487  ABTU_free(p_element);
488  p_element = p_next;
489  }
490  }
491  ABTU_free(p_config);
492 }
493 
495 {
496  switch (type) {
498  return sizeof(int);
500  return sizeof(double);
502  return sizeof(void *);
503  default:
504  ABTI_ASSERT(0);
506  }
507 }
ABT_sched_config_var
A struct that sets and gets a scheduler configuration.
Definition: abt.h:1240
ABT_sched_config_set
int ABT_sched_config_set(ABT_sched_config config, int idx, ABT_sched_config_type type, const void *val)
Register a value to a scheduler configuration.
Definition: config.c:308
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:815
ABT_sched_config_automatic
ABT_sched_config_var ABT_sched_config_automatic
Predefined ABT_sched_config_var to configure whether the scheduler is freed automatically or not.
Definition: config.c:33
ABT_sched_config_read
int ABT_sched_config_read(ABT_sched_config config, int num_vars,...)
Retrieve values from a scheduler configuration.
Definition: config.c:205
ABTU_unreachable
#define ABTU_unreachable()
Definition: abtu.h:133
abti.h
sched_config_set
static ABTU_ret_err int sched_config_set(ABTI_sched_config *p_config, int idx, ABT_sched_config_type type, const void *p_val)
Definition: config.c:414
ABT_sched_config_access
ABT_sched_config_var ABT_sched_config_access
Unused predefined ABT_sched_config_var.
Definition: config.c:30
sched_config_type_size
static size_t sched_config_type_size(ABT_sched_config_type type)
Definition: config.c:494
ABT_SCHED_CONFIG_PTR
@ ABT_SCHED_CONFIG_PTR
Definition: abt.h:1233
ABT_sched_config_var::type
ABT_sched_config_type type
Definition: abt.h:1244
ABT_sched_config_free
int ABT_sched_config_free(ABT_sched_config *config)
Free a scheduler configuration.
Definition: config.c:250
ABT_SCHED_CONFIG_DOUBLE
@ ABT_SCHED_CONFIG_DOUBLE
Definition: abt.h:1231
ABTU_calloc
static ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr)
Definition: abtu.h:244
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABT_SCHED_CONFIG_NULL
#define ABT_SCHED_CONFIG_NULL
Definition: abt.h:1058
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:155
sched_config_free
static void sched_config_free(ABTI_sched_config *p_config)
Definition: config.c:479
ABT_ERR_INV_ARG
#define ABT_ERR_INV_ARG
Error code: invalid user argument.
Definition: abt.h:250
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_sched_config_var_end
ABT_sched_config_var ABT_sched_config_var_end
Predefined ABT_sched_config_var to mark the last parameter.
Definition: config.c:26
ABT_SCHED_CONFIG_INT
@ ABT_SCHED_CONFIG_INT
Definition: abt.h:1229
sched_config_get
static ABTU_ret_err int sched_config_get(const ABTI_sched_config *p_config, int idx, ABT_sched_config_type *p_type, void *p_val)
Definition: config.c:384
ABT_sched_basic_freq
ABT_sched_config_var ABT_sched_basic_freq
Predefined ABT_sched_config_var to configure the frequency for checking events of the basic scheduler...
Definition: config.c:37
ABT_sched_config_var::idx
int idx
Definition: abt.h:1242
ABT_sched_config_get
int ABT_sched_config_get(ABT_sched_config config, int idx, ABT_sched_config_type *type, void *val)
Retrieve a value from a scheduler configuration.
Definition: config.c:358
ABT_sched_config_create
int ABT_sched_config_create(ABT_sched_config *config,...)
Create a new scheduler configuration.
Definition: config.c:105
ABT_sched_config_type
ABT_sched_config_type
A struct that sets and gets a scheduler configuration.
Definition: abt.h:1227