ARGOBOTS  1.1
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 void *fcontext_t;
10 
11 #if defined(ABT_C_HAVE_VISIBILITY)
12 #define ABT_API_PRIVATE __attribute__((visibility("hidden")))
13 #else
14 #define ABT_API_PRIVATE
15 #endif
16 
17 fcontext_t make_fcontext(void *sp, size_t size,
18  void (*thread_func)(void *)) ABT_API_PRIVATE;
19 void *jump_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE;
20 void *take_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE;
21 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
22 void init_and_call_fcontext(void *p_arg, void (*f_thread)(void *),
23  void *p_stacktop, fcontext_t *old);
24 #endif
25 
26 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && defined(__x86_64__)
27 /* We implement peek_fcontext only for x86-64. */
28 void peek_fcontext(fcontext_t new, void (*peek_func)(void *),
29  void *arg) ABT_API_PRIVATE;
30 #define ABTD_SUPPORT_PEEK_FCONTEXT 1
31 #endif /* defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && defined(__x86_64__) */
32 
34  void *p_ctx; /* actual context of fcontext, or a
35  * pointer to uctx */
36  ABTD_ythread_context_atomic_ptr p_link; /* pointer to scheduler context */
37 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
38  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
39  void (*thread_func)(void *);
40  void *arg;
41  void (*peek_func)(void *);
42  void *peek_arg;
43  void *p_peek_ctx;
44  ABT_bool is_peeked;
45 #endif
46 };
47 
48 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
49  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
50 static inline void ABTDI_fcontext_check_peeked(ABTD_ythread_context *p_self)
51 {
52  /* Check if this thread is called only for peeked */
53  while (ABTU_unlikely(p_self->is_peeked)) {
54  p_self->peek_func(p_self->peek_arg);
55  /* Reset the flag. */
56  p_self->is_peeked = ABT_FALSE;
57  jump_fcontext(&p_self->p_ctx, p_self->p_peek_ctx, NULL);
58  }
59 }
60 
61 static inline void ABTDI_fcontext_wrapper(void *arg)
62 {
64  ABTDI_fcontext_check_peeked(p_self);
65  p_self->thread_func(p_self->arg);
66 }
67 #endif
68 
70  void *sp, size_t size,
71  void (*thread_func)(void *))
72 {
73 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
74  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
75  p_ctx->thread_func = thread_func;
76  p_ctx->is_peeked = ABT_FALSE;
77  p_ctx->p_ctx = make_fcontext(sp, size, ABTDI_fcontext_wrapper);
78 #else
79  p_ctx->p_ctx = make_fcontext(sp, size, thread_func);
80 #endif
81 }
82 
84  ABTD_ythread_context *p_new,
85  void *arg)
86 {
87 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
88  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
89  p_new->arg = arg;
90  p_old->is_peeked = ABT_FALSE;
91  jump_fcontext(&p_old->p_ctx, p_new->p_ctx, p_new);
92  ABTDI_fcontext_check_peeked(p_old);
93 #else
94  jump_fcontext(&p_old->p_ctx, p_new->p_ctx, arg);
95 #endif
96 }
97 
98 ABTU_noreturn static inline void
100  ABTD_ythread_context *p_new, void *arg)
101 {
102 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
103  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
104  p_new->arg = arg;
105  take_fcontext(&p_old->p_ctx, p_new->p_ctx, p_new);
106 #else
107  take_fcontext(&p_old->p_ctx, p_new->p_ctx, arg);
108 #endif
110 }
111 
112 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
113 static inline void
115  void (*thread_func)(void *), void *arg)
116 {
117 #if defined(ABT_CONFIG_ENABLE_PEEK_CONTEXT) && \
118  !defined(ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT)
119  p_ctx->is_peeked = ABT_FALSE;
120  init_and_call_fcontext(arg, thread_func, sp, &p_ctx->p_ctx);
121  ABTDI_fcontext_check_peeked(p_ctx);
122 #else
123  init_and_call_fcontext(arg, thread_func, sp, &p_ctx->p_ctx);
124 #endif
125 }
126 #endif
127 
128 #ifdef ABT_CONFIG_ENABLE_PEEK_CONTEXT
129 static inline void ABTD_ythread_context_peek(ABTD_ythread_context *p_ctx,
130  void (*peek_func)(void *),
131  void *arg)
132 {
133 #ifdef ABTD_CONTEXT_SUPPORT_PEEK_FCONTEXT
134  peek_fcontext(p_ctx->p_ctx, peek_func, *arg);
135 #else
136  p_ctx->peek_arg = arg;
137  p_ctx->peek_func = peek_func;
138  p_ctx->is_peeked = ABT_TRUE;
139  jump_fcontext(&p_ctx->p_peek_ctx, p_ctx->p_ctx, p_ctx);
140 #endif
141 }
142 #endif
144 #endif /* ABTD_FCONTEXT_H_INCLUDED */
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1001
ABTD_ythread_context_take
static ABTU_noreturn void ABTD_ythread_context_take(ABTD_ythread_context *p_old, ABTD_ythread_context *p_new, void *arg)
Definition: abtd_fcontext.h:99
fcontext_t
void * fcontext_t
Definition: abtd_fcontext.h:9
ABTU_noreturn
#define ABTU_noreturn
Definition: abtu.h:118
make_fcontext
fcontext_t make_fcontext(void *sp, size_t size, void(*thread_func)(void *)) ABT_API_PRIVATE
ABTD_ythread_context::p_link
ABTD_ythread_context_atomic_ptr p_link
Definition: abtd_fcontext.h:36
ABTD_ythread_context
Definition: abtd_fcontext.h:33
init_and_call_fcontext
void init_and_call_fcontext(void *p_arg, void(*f_thread)(void *), void *p_stacktop, fcontext_t *old)
jump_fcontext
void * jump_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE
ABTD_ythread_context_init_and_call
static void ABTD_ythread_context_init_and_call(ABTD_ythread_context *p_ctx, void *sp, void(*thread_func)(void *), void *arg)
Definition: abtd_fcontext.h:114
ABTD_ythread_context_make
static void ABTD_ythread_context_make(ABTD_ythread_context *p_ctx, void *sp, size_t size, void(*thread_func)(void *))
Definition: abtd_fcontext.h:69
ABTD_ythread_context::p_ctx
void * p_ctx
Definition: abtd_fcontext.h:34
ABTD_ythread_context_atomic_ptr
Definition: abtd_context.h:25
ABTU_unlikely
#define ABTU_unlikely(cond)
Definition: abtu.h:112
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:748
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:750
take_fcontext
void * take_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE
ABTD_ythread_context_jump
static void ABTD_ythread_context_jump(ABTD_ythread_context *p_old, ABTD_ythread_context *p_new, void *arg)
Definition: abtd_fcontext.h:83
ABTU_unreachable
static ABTU_noreturn void ABTU_unreachable(void)
Definition: abtu.h:126
ABT_API_PRIVATE
#define ABT_API_PRIVATE
Definition: abtd_fcontext.h:14