ARGOBOTS
randws.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 /* Random Work-stealing Scheduler Implementation */
9 
10 static int sched_init(ABT_sched sched, ABT_sched_config config);
11 static void sched_run(ABT_sched sched);
12 static int sched_free(ABT_sched);
13 
16  .init = sched_init,
17  .run = sched_run,
18  .free = sched_free,
19  .get_migr_pool = NULL,
20 };
21 
22 typedef struct {
23  uint32_t event_freq;
24 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
25  struct timespec sleep_time;
26 #endif
27 } sched_data;
28 
29 ABT_sched_def *ABTI_sched_get_randws_def(void)
30 {
31  return &sched_randws_def;
32 }
33 
34 static int sched_init(ABT_sched sched, ABT_sched_config config)
35 {
36  int abt_errno = ABT_SUCCESS;
37 
38  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
39  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
40 
41  /* Default settings */
42  sched_data *p_data = (sched_data *)ABTU_malloc(sizeof(sched_data));
43  p_data->event_freq = ABTI_global_get_sched_event_freq();
44 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
45  p_data->sleep_time.tv_sec = 0;
46  p_data->sleep_time.tv_nsec = ABTI_global_get_sched_sleep_nsec();
47 #endif
48 
49  /* Set the variables from the config */
50  void *p_event_freq = &p_data->event_freq;
51  ABTI_sched_config_read(config, 1, 1, &p_event_freq);
52 
53  p_sched->data = p_data;
54 
55 fn_exit:
56  return abt_errno;
57 
58 fn_fail:
59  HANDLE_ERROR_WITH_CODE("randws: sched_init", abt_errno);
60  goto fn_exit;
61 }
62 
63 static void sched_run(ABT_sched sched)
64 {
65  ABTI_local *p_local = ABTI_local_get_local();
66  uint32_t work_count = 0;
67  sched_data *p_data;
68  int num_pools;
69  ABT_pool *p_pools;
70  ABT_unit unit;
71  int target;
72  unsigned seed = time(NULL);
73  CNT_DECL(run_cnt);
74 
75  ABTI_xstream *p_xstream = p_local->p_xstream;
76  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
77  ABTI_ASSERT(p_sched);
78 
79  p_data = (sched_data *)p_sched->data;
80  num_pools = p_sched->num_pools;
81  p_pools = (ABT_pool *)ABTU_malloc(num_pools * sizeof(ABT_pool));
82  memcpy(p_pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
83 
84  while (1) {
85  CNT_INIT(run_cnt, 0);
86 
87  /* Execute one work unit from the scheduler's pool */
88  ABT_pool pool = p_pools[0];
89  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
90  unit = ABTI_pool_pop(p_pool);
91  if (unit != ABT_UNIT_NULL) {
92  ABTI_xstream_run_unit(&p_local, p_xstream, unit, p_pool);
93  CNT_INC(run_cnt);
94  } else if (num_pools > 1) {
95  /* Steal a work unit from other pools */
96  target =
97  (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools - 1) + 1);
98  pool = p_pools[target];
99  p_pool = ABTI_pool_get_ptr(pool);
100  unit = ABTI_pool_pop(p_pool);
101  LOG_EVENT_POOL_POP(p_pool, unit);
102  if (unit != ABT_UNIT_NULL) {
103  ABTI_unit_set_associated_pool(unit, p_pool);
104  ABTI_xstream_run_unit(&p_local, p_xstream, unit, p_pool);
105  CNT_INC(run_cnt);
106  }
107  }
108 
109  if (++work_count >= p_data->event_freq) {
110  ABT_bool stop =
111  ABTI_sched_has_to_stop(&p_local, p_sched, p_xstream);
112  if (stop == ABT_TRUE)
113  break;
114  work_count = 0;
115  ABTI_xstream_check_events(p_xstream, sched);
116  SCHED_SLEEP(run_cnt, p_data->sleep_time);
117  }
118  }
119 
120  ABTU_free(p_pools);
121 }
122 
123 static int sched_free(ABT_sched sched)
124 {
125  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
126  ABTI_ASSERT(p_sched);
127 
128  sched_data *p_data = (sched_data *)p_sched->data;
129  ABTU_free(p_data);
130 
131  return ABT_SUCCESS;
132 }
struct ABT_unit_opaque * ABT_unit
Definition: abt.h:275
struct ABT_sched_opaque * ABT_sched
Definition: abt.h:257
#define ABT_UNIT_NULL
Definition: abt.h:343
static void sched_run(ABT_sched sched)
Definition: randws.c:63
static void * ABTU_malloc(size_t size)
Definition: abtu.h:39
int ABT_bool
Definition: abt.h:309
#define LOG_EVENT_POOL_POP(p_pool, unit)
Definition: abti_log.h:65
struct ABT_pool_opaque * ABT_pool
Definition: abt.h:267
#define CNT_INIT(c, v)
Definition: abti_sched.h:89
static int sched_free(ABT_sched)
Definition: randws.c:123
#define HANDLE_ERROR_WITH_CODE(msg, n)
Definition: abti_error.h:234
#define ABT_SUCCESS
Definition: abt.h:64
#define ABT_TRUE
Definition: abt.h:223
ABT_sched_type type
Definition: abt.h:387
#define CNT_DECL(c)
Definition: abti_sched.h:88
#define CNT_INC(c)
Definition: abti_sched.h:90
#define SCHED_SLEEP(c, t)
Definition: abti_sched.h:91
struct ABT_sched_config_opaque * ABT_sched_config
Definition: abt.h:259
static ABT_sched_def sched_randws_def
Definition: randws.c:14
static void ABTU_free(void *ptr)
Definition: abtu.h:32
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: randws.c:34