ARGOBOTS  2d670346af9c36fec097ec5ab659205198ec061b
basic.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 static int sched_init(ABT_sched sched, ABT_sched_config config);
9 static void sched_run(ABT_sched sched);
10 static int sched_free(ABT_sched);
11 static void sched_sort_pools(int num_pools, ABT_pool *pools);
12 
15  .init = sched_init,
16  .run = sched_run,
17  .free = sched_free,
18  .get_migr_pool = NULL,
19 };
20 
21 typedef struct {
22  uint32_t event_freq;
23  int num_pools;
24  ABT_pool *pools;
25 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
26  struct timespec sleep_time;
27 #endif
28 } sched_data;
29 
30 ABT_sched_def *ABTI_sched_get_basic_def(void)
31 {
32  return &sched_basic_def;
33 }
34 
35 static inline sched_data *sched_data_get_ptr(void *data)
36 {
37  return (sched_data *)data;
38 }
39 
40 static int sched_init(ABT_sched sched, ABT_sched_config config)
41 {
42  int abt_errno;
43  int num_pools;
44  ABTI_global *p_global = ABTI_global_get_global();
45 
46  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
47  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
48  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
49 
50  /* Default settings */
51  sched_data *p_data;
52  abt_errno = ABTU_malloc(sizeof(sched_data), (void **)&p_data);
53  ABTI_CHECK_ERROR(abt_errno);
54 
55 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
56  p_data->sleep_time.tv_sec = 0;
57  p_data->sleep_time.tv_nsec = p_global->sched_sleep_nsec;
58 #endif
59 
60  /* Set the default value by default. */
61  p_data->event_freq = p_global->sched_event_freq;
62  if (p_config) {
63  int event_freq;
64  /* Set the variables from config */
65  abt_errno = ABTI_sched_config_read(p_config, ABT_sched_basic_freq.idx,
66  &event_freq);
67  if (abt_errno == ABT_SUCCESS) {
68  p_data->event_freq = event_freq;
69  }
70  }
71 
72  /* Save the list of pools */
73  num_pools = p_sched->num_pools;
74  p_data->num_pools = num_pools;
75  abt_errno =
76  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&p_data->pools);
77  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
78  ABTU_free(p_data);
79  ABTI_CHECK_ERROR(abt_errno);
80  }
81  memcpy(p_data->pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
82 
83  /* Sort pools according to their access mode so the scheduler can execute
84  work units from the private pools. */
85  if (num_pools > 1) {
86  sched_sort_pools(num_pools, p_data->pools);
87  }
88 
89  p_sched->data = p_data;
90  return ABT_SUCCESS;
91 }
92 
93 static void sched_run(ABT_sched sched)
94 {
95  ABTI_global *p_global = ABTI_global_get_global();
96  ABTI_xstream *p_local_xstream =
97  ABTI_local_get_xstream(ABTI_local_get_local());
98  ABT_unit unit = ABT_UNIT_NULL;
99  uint32_t pop_count = 0;
100  sched_data *p_data;
101  uint32_t event_freq;
102  int num_pools;
103  ABT_pool *pools;
104  int i;
105 
106  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
107  ABTI_ASSERT(p_sched);
108 
109  p_data = sched_data_get_ptr(p_sched->data);
110  event_freq = p_data->event_freq;
111  num_pools = p_data->num_pools;
112  pools = p_data->pools;
113 
114  while (1) {
115  for (i = 0; i < num_pools; i++) {
116  ABTI_pool *p_pool = ABTI_pool_get_ptr(pools[i]);
117  ++pop_count;
118  if ((unit =
119  ABTI_pool_pop(p_pool, ABT_POOL_CONTEXT_OP_POOL_OTHER)) !=
120  ABT_UNIT_NULL) {
121  ABTI_thread *p_thread = ABTI_unit_get_thread(p_global, unit);
122  ABTI_ythread_schedule(p_global, &p_local_xstream, p_thread);
123  break;
124  }
125  }
126  /* if we attempted event_freq pops, check for events */
127  if (pop_count >= event_freq) {
128  ABTI_xstream_check_events(p_local_xstream, p_sched);
129  if (ABTI_sched_has_to_stop(p_sched) == ABT_TRUE)
130  break;
131  SCHED_SLEEP(unit != ABT_UNIT_NULL, p_data->sleep_time);
132  pop_count = 0;
133  }
134  }
135 }
136 
137 static int sched_free(ABT_sched sched)
138 {
139  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
140  ABTI_ASSERT(p_sched);
141 
142  sched_data *p_data = sched_data_get_ptr(p_sched->data);
143  ABTU_free(p_data->pools);
144  ABTU_free(p_data);
145  return ABT_SUCCESS;
146 }
147 
148 static int pool_get_access_num(ABT_pool *p_pool)
149 {
150  ABT_pool_access access;
151  int num = 0;
152 
153  access = ABTI_pool_get_ptr(*p_pool)->access;
154  switch (access) {
156  num = 0;
157  break;
160  num = 1;
161  break;
164  num = 2;
165  break;
166  default:
167  ABTI_ASSERT(0);
169  }
170 
171  return num;
172 }
173 
174 static int sched_cmp_pools(const void *p1, const void *p2)
175 {
176  int p1_access, p2_access;
177 
178  p1_access = pool_get_access_num((ABT_pool *)p1);
179  p2_access = pool_get_access_num((ABT_pool *)p2);
180 
181  if (p1_access > p2_access) {
182  return 1;
183  } else if (p1_access < p2_access) {
184  return -1;
185  } else {
186  return 0;
187  }
188 }
189 
190 static void sched_sort_pools(int num_pools, ABT_pool *pools)
191 {
192  qsort(pools, num_pools, sizeof(ABT_pool), sched_cmp_pools);
193 }
ABT_sched_def::type
ABT_sched_type type
Unused value.
Definition: abt.h:1327
ABT_POOL_CONTEXT_OP_POOL_OTHER
#define ABT_POOL_CONTEXT_OP_POOL_OTHER
A flag that hints an unspecified pool operation.
Definition: abt.h:1569
ABT_POOL_ACCESS_MPMC
@ ABT_POOL_ACCESS_MPMC
Definition: abt.h:551
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:826
sched_init
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: basic.c:40
sched_sort_pools
static void sched_sort_pools(int num_pools, ABT_pool *pools)
Definition: basic.c:190
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:852
ABT_POOL_ACCESS_MPSC
@ ABT_POOL_ACCESS_MPSC
Definition: abt.h:545
ABTU_unreachable
#define ABTU_unreachable()
Definition: abtu.h:133
ABT_POOL_ACCESS_PRIV
@ ABT_POOL_ACCESS_PRIV
Definition: abt.h:536
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:819
ABT_SCHED_TYPE_ULT
@ ABT_SCHED_TYPE_ULT
Definition: abt.h:502
sched_basic_def
static ABT_sched_def sched_basic_def
Definition: basic.c:13
abti.h
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABT_unit
struct ABT_unit_opaque * ABT_unit
Work unit handle type for scheduling.
Definition: abt.h:885
sched_data_get_ptr
static sched_data * sched_data_get_ptr(void *data)
Definition: basic.c:35
sched_free
static int sched_free(ABT_sched)
Definition: basic.c:137
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
pool_get_access_num
static int pool_get_access_num(ABT_pool *p_pool)
Definition: basic.c:148
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:758
ABT_POOL_ACCESS_SPMC
@ ABT_POOL_ACCESS_SPMC
Definition: abt.h:549
sched_run
static void sched_run(ABT_sched sched)
Definition: basic.c:93
ABT_POOL_ACCESS_SPSC
@ ABT_POOL_ACCESS_SPSC
Definition: abt.h:541
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_sched_def
A struct that defines a scheduler.
Definition: abt.h:1320
SCHED_SLEEP
#define SCHED_SLEEP(c, t)
Definition: abti_sched.h:81
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: sched_config.c:51
ABT_UNIT_NULL
#define ABT_UNIT_NULL
Definition: abt.h:1078
sched_cmp_pools
static int sched_cmp_pools(const void *p1, const void *p2)
Definition: basic.c:174
ABT_sched_config_var::idx
int idx
Definition: abt.h:1260
ABT_pool_access
ABT_pool_access
Pool access type.
Definition: abt.h:532