ARGOBOTS  1.1
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_add(ABTI_sched_config *p_config, int idx,
15  const void *p_val);
16 static void sched_config_free(ABTI_sched_config *p_config);
17 
22 /* Global configurable parameters */
24  .type =
26 
28  .type = ABT_SCHED_CONFIG_INT };
29 
31  .type =
33 
35  .type = ABT_SCHED_CONFIG_INT };
36 
103 {
104  int abt_errno;
105  int i = 0;
106  ABTI_sched_config *p_config;
107 
108  abt_errno = ABTU_calloc(1, sizeof(ABTI_sched_config), (void **)&p_config);
109  ABTI_CHECK_ERROR(abt_errno);
110  /* Initialize index. */
111 
112  for (i = 0; i < ABTI_SCHED_CONFIG_HTABLE_SIZE; i++) {
113  p_config->elements[i].idx = ABTI_SCHED_CONFIG_UNUSED_INDEX;
114  }
115 
116  va_list varg_list;
117  va_start(varg_list, config);
118 
119  /* We read (var, value) until we find ABT_sched_config_var_end */
120  while (1) {
121  ABT_sched_config_var var = va_arg(varg_list, ABT_sched_config_var);
122  int idx = var.idx;
123  if (idx == ABT_sched_config_var_end.idx)
124  break;
125  /* Add the argument */
126  switch (var.type) {
127  case ABT_SCHED_CONFIG_INT: {
128  int int_val = va_arg(varg_list, int);
129  abt_errno = sched_config_add(p_config, idx,
130  ABT_SCHED_CONFIG_INT, &int_val);
131  break;
132  }
134  double double_val = va_arg(varg_list, double);
135  abt_errno =
137  &double_val);
138  break;
139  }
140  case ABT_SCHED_CONFIG_PTR: {
141  void *ptr_val = va_arg(varg_list, void *);
142  abt_errno = sched_config_add(p_config, idx,
143  ABT_SCHED_CONFIG_PTR, &ptr_val);
144  break;
145  }
146  default:
147  abt_errno = ABT_ERR_SCHED_CONFIG;
148  }
149  if (abt_errno != ABT_SUCCESS) {
150  sched_config_free(p_config);
151  va_end(varg_list);
152  ABTI_HANDLE_ERROR(abt_errno);
153  }
154  }
155  va_end(varg_list);
156 
157  *config = ABTI_sched_config_get_handle(p_config);
158  return ABT_SUCCESS;
159 }
160 
200 int ABT_sched_config_read(ABT_sched_config config, int num_vars, ...)
201 {
202  int idx;
203  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
205 
206  va_list varg_list;
207  va_start(varg_list, num_vars);
208  for (idx = 0; idx < num_vars; idx++) {
209  void *ptr = va_arg(varg_list, void *);
210  if (ptr) {
211  int abt_errno = ABTI_sched_config_read(p_config, idx, ptr);
212  /* It's okay even if there's no associated value. */
213  (void)abt_errno;
214  }
215  }
216  va_end(varg_list);
217  return ABT_SUCCESS;
218 }
219 
244 {
245  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(*config);
247 
248  ABTU_free(p_config);
249 
250  *config = ABT_SCHED_CONFIG_NULL;
251 
252  return ABT_SUCCESS;
253 }
254 
255 /*****************************************************************************/
256 /* Private APIs */
257 /*****************************************************************************/
258 
260  int idx, void *p_val)
261 {
262  int table_index = ((idx % ABTI_SCHED_CONFIG_HTABLE_SIZE) +
265  if (p_config->elements[table_index].idx == ABTI_SCHED_CONFIG_UNUSED_INDEX) {
266  return ABT_ERR_OTHER;
267  } else {
268  const ABTI_sched_config_element *p_element =
269  &p_config->elements[table_index];
270  while (p_element) {
271  if (p_element->idx == idx) {
272  memcpy(p_val, p_element->val,
273  sched_config_type_size(p_element->type));
274  return ABT_SUCCESS;
275  } else {
276  p_element = p_element->p_next;
277  }
278  }
279  return ABT_ERR_OTHER;
280  }
281 }
282 
283 /*****************************************************************************/
284 /* Internal static functions */
285 /*****************************************************************************/
286 
287 ABTU_ret_err static int sched_config_add(ABTI_sched_config *p_config, int idx,
289  const void *p_val)
290 {
291  int table_index = ((idx % ABTI_SCHED_CONFIG_HTABLE_SIZE) +
294  if (p_config->elements[table_index].idx == ABTI_SCHED_CONFIG_UNUSED_INDEX) {
295  p_config->elements[table_index].idx = idx;
296  p_config->elements[table_index].type = type;
297  memcpy(p_config->elements[table_index].val, p_val,
298  sched_config_type_size(type));
299  } else {
300  ABTI_sched_config_element *p_element = &p_config->elements[table_index];
301  while (p_element) {
302  if (p_element->idx == idx) {
303  /* Update. */
304  p_element->type = type;
305  memcpy(p_element->val, p_val, sched_config_type_size(type));
306  break;
307  } else if (!p_element->p_next) {
308  ABTI_sched_config_element *p_new_element;
309  int abt_errno =
311  (void **)&p_new_element);
312  ABTI_CHECK_ERROR(abt_errno);
313  p_new_element->idx = idx;
314  p_new_element->type = type;
315  memcpy(p_new_element->val, p_val, sched_config_type_size(type));
316  p_element->p_next = p_new_element;
317  break;
318  } else {
319  p_element = p_element->p_next;
320  }
321  }
322  }
323  return ABT_SUCCESS;
324 }
325 
326 static void sched_config_free(ABTI_sched_config *p_config)
327 {
328  /* Check elements. */
329  int i;
330  for (i = 0; i < ABTI_SCHED_CONFIG_HTABLE_SIZE; i++) {
331  ABTI_sched_config_element *p_element = p_config->elements[i].p_next;
332  while (p_element) {
333  ABTI_sched_config_element *p_next = p_element->p_next;
334  ABTU_free(p_element);
335  p_element = p_next;
336  }
337  }
338  ABTU_free(p_config);
339 }
340 
342 {
343  switch (type) {
345  return sizeof(int);
347  return sizeof(double);
349  return sizeof(void *);
350  default:
351  ABTI_ASSERT(0);
353  }
354 }
ABT_sched_config_var
A struct that sets and gets a scheduler configuration.
Definition: abt.h:1240
ABTI_SCHED_CONFIG_HTABLE_SIZE
#define ABTI_SCHED_CONFIG_HTABLE_SIZE
Definition: abti.h:61
ABTI_sched_config_element::val
char val[sizeof(double) > sizeof(void *) ? sizeof(double) :sizeof(void *)]
Definition: abti.h:319
ABTI_sched_config::elements
ABTI_sched_config_element elements[ABTI_SCHED_CONFIG_HTABLE_SIZE]
Definition: abti.h:324
ABT_ERR_SCHED_CONFIG
#define ABT_ERR_SCHED_CONFIG
Error code: error related to a scheduler configuration.
Definition: abt.h:277
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:120
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:815
ABTI_sched_config
Definition: abti.h:323
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:30
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:200
ABTI_sched_config_get_handle
static ABT_sched_config ABTI_sched_config_get_handle(ABTI_sched_config *p_config)
Definition: abti_config.h:28
abti.h
ABT_sched_config_access
ABT_sched_config_var ABT_sched_config_access
Unused predefined ABT_sched_config_var.
Definition: config.c:27
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:114
sched_config_type_size
static size_t sched_config_type_size(ABT_sched_config_type type)
Definition: config.c:341
sched_config_add
static ABTU_ret_err int sched_config_add(ABTI_sched_config *p_config, int idx, ABT_sched_config_type type, const void *p_val)
Definition: config.c:287
ABTI_sched_config_element::type
ABT_sched_config_type type
Definition: abti.h:316
ABT_SCHED_CONFIG_PTR
@ ABT_SCHED_CONFIG_PTR
Definition: abt.h:1233
ABTI_sched_config_element::idx
int idx
Definition: abti.h:315
ABT_sched_config_var::type
ABT_sched_config_type type
Definition: abt.h:1244
ABTI_ASSERT
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
ABT_sched_config_free
int ABT_sched_config_free(ABT_sched_config *config)
Free a scheduler configuration.
Definition: config.c:243
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:272
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:146
ABTI_sched_config_element::p_next
ABTI_sched_config_element * p_next
Definition: abti.h:320
sched_config_free
static void sched_config_free(ABTI_sched_config *p_config)
Definition: config.c:326
ABTI_sched_config_read
ABTU_ret_err int ABTI_sched_config_read(const ABTI_sched_config *p_config, int idx, void *p_val)
Definition: config.c:259
ABTI_SCHED_CONFIG_UNUSED_INDEX
#define ABTI_SCHED_CONFIG_UNUSED_INDEX
Definition: abti.h:62
ABTI_sched_config_element
Definition: abti.h:314
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:217
ABT_ERR_OTHER
#define ABT_ERR_OTHER
Error code: other error.
Definition: abt.h:109
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:23
ABT_SCHED_CONFIG_INT
@ ABT_SCHED_CONFIG_INT
Definition: abt.h:1229
ABTI_sched_config_get_ptr
static ABTI_sched_config * ABTI_sched_config_get_ptr(ABT_sched_config config)
Definition: abti_config.h:12
ABTI_CHECK_NULL_SCHED_CONFIG_PTR
#define ABTI_CHECK_NULL_SCHED_CONFIG_PTR(p)
Definition: abti_error.h:186
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:34
ABTU_unreachable
static ABTU_noreturn void ABTU_unreachable(void)
Definition: abtu.h:126
ABT_sched_config_var::idx
int idx
Definition: abt.h:1242
ABT_sched_config_create
int ABT_sched_config_create(ABT_sched_config *config,...)
Create a new scheduler configuration.
Definition: config.c:102
ABT_sched_config_type
ABT_sched_config_type
A struct that sets and gets a scheduler configuration.
Definition: abt.h:1227