ARGOBOTS  4dc37e16e1b227a480715ab67dae1dcfb4d2d4e0
abtd_fcontext.h
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 #ifndef ABTD_FCONTEXT_H_INCLUDED
7 #define ABTD_FCONTEXT_H_INCLUDED
8 
9 typedef struct {
10  void *dummy;
11 } fcontext_t;
12 
13 static inline int ABTDI_fcontext_is_created(const fcontext_t *p_ftx)
14 {
15  /* Return 0 if p_ftx->dummy is NULL. */
16  return !!p_ftx->dummy;
17 }
18 
19 static inline void ABTDI_fcontext_init(fcontext_t *p_ftx)
20 {
21  p_ftx->dummy = NULL;
22 }
23 
24 #if defined(ABT_C_HAVE_VISIBILITY)
25 #define ABT_API_PRIVATE __attribute__((visibility("hidden")))
26 #else
27 #define ABT_API_PRIVATE
28 #endif
29 
30 void switch_fcontext(fcontext_t *p_new_ctx,
31  fcontext_t *p_old_ctx) ABT_API_PRIVATE;
33 void init_and_switch_fcontext(fcontext_t *p_new_ctx,
34  void (*f_thread)(fcontext_t *), void *p_stacktop,
35  fcontext_t *p_old_ctx) ABT_API_PRIVATE;
36 void init_and_jump_fcontext(fcontext_t *p_new_ctx,
37  void (*f_thread)(fcontext_t *),
38  void *p_stacktop) ABT_API_PRIVATE;
39 void switch_with_call_fcontext(void *cb_arg, void (*f_cb)(void *),
40  fcontext_t *p_new_ctx,
41  fcontext_t *p_old_ctx) ABT_API_PRIVATE;
42 void jump_with_call_fcontext(void *cb_arg, void (*f_cb)(void *),
43  fcontext_t *p_new_ctx) ABT_API_PRIVATE;
44 void init_and_switch_with_call_fcontext(void *cb_arg, void (*f_cb)(void *),
45  fcontext_t *p_new_ctx,
46  void (*f_thread)(fcontext_t *),
47  void *p_stacktop,
48  fcontext_t *p_old_ctx) ABT_API_PRIVATE;
49 void init_and_jump_with_call_fcontext(void *cb_arg, void (*f_cb)(void *),
50  fcontext_t *p_new_ctx,
51  void (*f_thread)(fcontext_t *),
52  void *p_stacktop) ABT_API_PRIVATE;
53 void peek_fcontext(void *arg, void (*f_peek)(void *),
54  fcontext_t *p_target_ctx) ABT_API_PRIVATE;
55 
56 struct ABTD_ythread_context {
57  fcontext_t ctx; /* actual context of fcontext */
58  void *p_stacktop;
59  size_t stacksize;
60  ABTD_ythread_context_atomic_ptr
61  p_link; /* pointer to the waiter's context */
62 };
63 
64 static inline ABTD_ythread_context *
66 {
67  return (ABTD_ythread_context *)(((char *)p_fctx) -
68  offsetof(ABTD_ythread_context, ctx));
69 }
70 
71 static void ABTD_ythread_context_func_wrapper(fcontext_t *p_fctx)
72 {
73  ABTD_ythread_context *p_ctx = ABTDI_ythread_context_get_context(p_fctx);
74  ABTD_ythread_func_wrapper(p_ctx);
75  /* ABTD_ythread_func_wrapper() must context-switch to another before it
76  * finishes. */
78 }
79 
80 static inline void ABTD_ythread_context_init(ABTD_ythread_context *p_ctx,
81  void *p_stacktop, size_t stacksize)
82 {
83  ABTDI_fcontext_init(&p_ctx->ctx);
84  p_ctx->p_stacktop = p_stacktop;
85  p_ctx->stacksize = stacksize;
86  ABTD_atomic_relaxed_store_ythread_context_ptr(&p_ctx->p_link, NULL);
87 }
88 
89 static inline void ABTD_ythread_context_init_lazy(ABTD_ythread_context *p_ctx,
90  size_t stacksize)
91 {
92  ABTDI_fcontext_init(&p_ctx->ctx);
93  p_ctx->p_stacktop = NULL;
94  p_ctx->stacksize = stacksize;
95  ABTD_atomic_relaxed_store_ythread_context_ptr(&p_ctx->p_link, NULL);
96 }
97 
98 static inline void
99 ABTD_ythread_context_lazy_set_stack(ABTD_ythread_context *p_ctx,
100  void *p_stacktop)
101 {
102  p_ctx->p_stacktop = p_stacktop;
103 }
104 
105 static inline void
106 ABTD_ythread_context_lazy_unset_stack(ABTD_ythread_context *p_ctx)
107 {
108  p_ctx->p_stacktop = NULL;
109 }
110 
111 static inline void ABTD_ythread_context_reinit(ABTD_ythread_context *p_ctx)
112 {
113  ABTDI_fcontext_init(&p_ctx->ctx);
114  ABTD_atomic_relaxed_store_ythread_context_ptr(&p_ctx->p_link, NULL);
115 }
116 
117 static inline void *
118 ABTD_ythread_context_get_stacktop(ABTD_ythread_context *p_ctx)
119 {
120  return p_ctx->p_stacktop;
121 }
122 
123 static inline ABT_bool
124 ABTD_ythread_context_has_stack(const ABTD_ythread_context *p_ctx)
125 {
126  return p_ctx->p_stacktop ? ABT_TRUE : ABT_FALSE;
127 }
128 
129 static inline size_t
130 ABTD_ythread_context_get_stacksize(ABTD_ythread_context *p_ctx)
131 {
132  return p_ctx->stacksize;
133 }
134 
135 static inline ABT_bool
136 ABTD_ythread_context_is_started(const ABTD_ythread_context *p_ctx)
137 {
138  return ABTDI_fcontext_is_created(&p_ctx->ctx) ? ABT_TRUE : ABT_FALSE;
139 }
140 
141 static inline void ABTD_ythread_context_switch(ABTD_ythread_context *p_old,
142  ABTD_ythread_context *p_new)
143 {
144  ABTI_UB_ASSERT(ABTDI_fcontext_is_created(&p_new->ctx));
145  /* The context is already initialized. */
146  switch_fcontext(&p_new->ctx, &p_old->ctx);
147 }
148 
149 static inline void
150 ABTD_ythread_context_start_and_switch(ABTD_ythread_context *p_old,
151  ABTD_ythread_context *p_new)
152 {
153  ABTI_UB_ASSERT(!ABTDI_fcontext_is_created(&p_new->ctx));
154  /* First time. */
155  init_and_switch_fcontext(&p_new->ctx, ABTD_ythread_context_func_wrapper,
156  p_new->p_stacktop, &p_old->ctx);
157 }
158 
159 ABTU_noreturn static inline void
160 ABTD_ythread_context_jump(ABTD_ythread_context *p_new)
161 {
162  ABTI_UB_ASSERT(ABTDI_fcontext_is_created(&p_new->ctx));
163  /* The context is already initialized. */
164  jump_fcontext(&p_new->ctx);
166 }
167 
168 ABTU_noreturn static inline void
169 ABTD_ythread_context_start_and_jump(ABTD_ythread_context *p_new)
170 {
171  ABTI_UB_ASSERT(!ABTDI_fcontext_is_created(&p_new->ctx));
172  /* First time. */
173  init_and_jump_fcontext(&p_new->ctx, ABTD_ythread_context_func_wrapper,
174  p_new->p_stacktop);
176 }
177 
178 static inline void
179 ABTD_ythread_context_switch_with_call(ABTD_ythread_context *p_old,
180  ABTD_ythread_context *p_new,
181  void (*f_cb)(void *), void *cb_arg)
182 {
183  ABTI_UB_ASSERT(ABTDI_fcontext_is_created(&p_new->ctx));
184  /* The context is already initialized. */
185 
186  switch_with_call_fcontext(cb_arg, f_cb, &p_new->ctx, &p_old->ctx);
187 }
188 
189 static inline void ABTD_ythread_context_start_and_switch_with_call(
190  ABTD_ythread_context *p_old, ABTD_ythread_context *p_new,
191  void (*f_cb)(void *), void *cb_arg)
192 {
193  ABTI_UB_ASSERT(!ABTDI_fcontext_is_created(&p_new->ctx));
194  /* First time. */
195  init_and_switch_with_call_fcontext(cb_arg, f_cb, &p_new->ctx,
196  ABTD_ythread_context_func_wrapper,
197  p_new->p_stacktop, &p_old->ctx);
198 }
199 
200 ABTU_noreturn static inline void
201 ABTD_ythread_context_jump_with_call(ABTD_ythread_context *p_new,
202  void (*f_cb)(void *), void *cb_arg)
203 {
204  ABTI_UB_ASSERT(ABTDI_fcontext_is_created(&p_new->ctx));
205  /* The context is already initialized. */
206  jump_with_call_fcontext(cb_arg, f_cb, &p_new->ctx);
208 }
209 
210 ABTU_noreturn static inline void ABTD_ythread_context_start_and_jump_with_call(
211  ABTD_ythread_context *p_new, void (*f_cb)(void *), void *cb_arg)
212 {
213  ABTI_UB_ASSERT(!ABTDI_fcontext_is_created(&p_new->ctx));
214  /* First time. */
215  init_and_jump_with_call_fcontext(cb_arg, f_cb, &p_new->ctx,
216  ABTD_ythread_context_func_wrapper,
217  p_new->p_stacktop);
219 }
220 
221 static inline ABT_bool
222 ABTD_ythread_context_peek(ABTD_ythread_context *p_target_ctx,
223  void (*f_peek)(void *), void *arg)
224 {
225  if (ABTDI_fcontext_is_created(&p_target_ctx->ctx)) {
226  peek_fcontext(arg, f_peek, &p_target_ctx->ctx);
227  return ABT_TRUE;
228  } else {
229  return ABT_FALSE;
230  }
231 }
232 
233 #endif /* ABTD_FCONTEXT_H_INCLUDED */
jump_fcontext
void jump_fcontext(fcontext_t *p_new_ctx) ABT_API_PRIVATE
init_and_switch_with_call_fcontext
void init_and_switch_with_call_fcontext(void *cb_arg, void(*f_cb)(void *), fcontext_t *p_new_ctx, void(*f_thread)(fcontext_t *), void *p_stacktop, fcontext_t *p_old_ctx) ABT_API_PRIVATE
switch_with_call_fcontext
void switch_with_call_fcontext(void *cb_arg, void(*f_cb)(void *), fcontext_t *p_new_ctx, fcontext_t *p_old_ctx) ABT_API_PRIVATE
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
init_and_switch_fcontext
void init_and_switch_fcontext(fcontext_t *p_new_ctx, void(*f_thread)(fcontext_t *), void *p_stacktop, fcontext_t *p_old_ctx) ABT_API_PRIVATE
jump_with_call_fcontext
void jump_with_call_fcontext(void *cb_arg, void(*f_cb)(void *), fcontext_t *p_new_ctx) ABT_API_PRIVATE
ABTU_noreturn
#define ABTU_noreturn
Definition: abtu.h:127
ABTU_unreachable
#define ABTU_unreachable()
Definition: abtu.h:133
switch_fcontext
void switch_fcontext(fcontext_t *p_new_ctx, fcontext_t *p_old_ctx) ABT_API_PRIVATE
init_and_jump_fcontext
void init_and_jump_fcontext(fcontext_t *p_new_ctx, void(*f_thread)(fcontext_t *), void *p_stacktop) ABT_API_PRIVATE
fcontext_t
Definition: abtd_fcontext.h:9
ABTDI_fcontext_is_created
static int ABTDI_fcontext_is_created(const fcontext_t *p_ftx)
Definition: abtd_fcontext.h:13
fcontext_t::dummy
void * dummy
Definition: abtd_fcontext.h:10
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
peek_fcontext
void peek_fcontext(void *arg, void(*f_peek)(void *), fcontext_t *p_target_ctx) ABT_API_PRIVATE
init_and_jump_with_call_fcontext
void init_and_jump_with_call_fcontext(void *cb_arg, void(*f_cb)(void *), fcontext_t *p_new_ctx, void(*f_thread)(fcontext_t *), void *p_stacktop) ABT_API_PRIVATE
ABTDI_fcontext_init
static void ABTDI_fcontext_init(fcontext_t *p_ftx)
Definition: abtd_fcontext.h:19
ABTDI_ythread_context_get_context
static ABTD_ythread_context * ABTDI_ythread_context_get_context(fcontext_t *p_fctx)
Definition: abtd_fcontext.h:65
ABT_API_PRIVATE
#define ABT_API_PRIVATE
Definition: abtd_fcontext.h:27