ARGOBOTS
abtd_thread.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_THREAD_H_INCLUDED
7 #define ABTD_THREAD_H_INCLUDED
8 
9 #if defined(ABT_C_HAVE_VISIBILITY)
10 #define ABT_API_PRIVATE __attribute__((visibility("hidden")))
11 #else
12 #define ABT_API_PRIVATE
13 #endif
14 
15 void ABTD_thread_func_wrapper_thread(void *p_arg);
16 void ABTD_thread_func_wrapper_sched(void *p_arg);
17 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
18 void ABTD_thread_terminate_thread_no_arg();
19 #endif
20 
21 static inline int ABTDI_thread_context_create(ABTD_thread_context *p_link,
22  void (*f_wrapper)(void *),
23  void (*f_thread)(void *),
24  void *p_arg, size_t stacksize,
25  void *p_stack,
26  ABTD_thread_context *p_newctx)
27 {
28  int abt_errno = ABT_SUCCESS;
29  void *p_stacktop;
30 
31  /* ABTD_thread_context_make uses the top address of stack.
32  Note that the parameter, p_stack, points to the bottom of stack. */
33  p_stacktop = (void *)(((char *)p_stack) + stacksize);
34 
35  ABTD_thread_context_make(p_newctx, p_stacktop, stacksize, f_wrapper);
36  p_newctx->f_thread = f_thread;
37  p_newctx->p_arg = p_arg;
38  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, p_link);
39 
40  return abt_errno;
41 }
42 
43 static inline int ABTD_thread_context_create_thread(
44  ABTD_thread_context *p_link, void (*f_thread)(void *), void *p_arg,
45  size_t stacksize, void *p_stack, ABTD_thread_context *p_newctx)
46 {
47  return ABTDI_thread_context_create(p_link, ABTD_thread_func_wrapper_thread,
48  f_thread, p_arg, stacksize, p_stack,
49  p_newctx);
50 }
51 
52 static inline int ABTD_thread_context_create_sched(
53  ABTD_thread_context *p_link, void (*f_thread)(void *), void *p_arg,
54  size_t stacksize, void *p_stack, ABTD_thread_context *p_newctx)
55 {
56  return ABTDI_thread_context_create(p_link, ABTD_thread_func_wrapper_sched,
57  f_thread, p_arg, stacksize, p_stack,
58  p_newctx);
59 }
60 
61 static inline int ABTD_thread_context_invalidate(ABTD_thread_context *p_newctx)
62 {
63  int abt_errno = ABT_SUCCESS;
64 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
65  /* p_ctx is used to check whether the context requires dynamic promotion is
66  * necessary or not, so this value must not be NULL. */
67  p_newctx->p_ctx = (void *)((intptr_t)0x1);
68 #else
69  p_newctx->p_ctx = NULL;
70 #endif
71  p_newctx->f_thread = NULL;
72  p_newctx->p_arg = NULL;
73  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, NULL);
74  return abt_errno;
75 }
76 
77 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
78 static inline int ABTD_thread_context_init(ABTD_thread_context *p_link,
79  void (*f_thread)(void *),
80  void *p_arg,
81  ABTD_thread_context *p_newctx)
82 {
83  int abt_errno = ABT_SUCCESS;
84  p_newctx->p_ctx = NULL;
85  p_newctx->f_thread = f_thread;
86  p_newctx->p_arg = p_arg;
87  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, p_link);
88  return abt_errno;
89 }
90 
91 static inline int ABTD_thread_context_arm_thread(size_t stacksize,
92  void *p_stack,
93  ABTD_thread_context *p_newctx)
94 {
95  /* This function *arms* the dynamic promotion thread (initialized by
96  * ABTD_thread_context_init) as if it were created by
97  * ABTD_thread_context_create; this function fully creates the context
98  * so that the thread can be run by ABTD_thread_context_jump. */
99  int abt_errno = ABT_SUCCESS;
100  /* ABTD_thread_context_make uses the top address of stack.
101  Note that the parameter, p_stack, points to the bottom of stack. */
102  void *p_stacktop = (void *)(((char *)p_stack) + stacksize);
103  ABTD_thread_context_make(p_newctx, p_stacktop, stacksize,
104  ABTD_thread_func_wrapper_thread);
105  return abt_errno;
106 }
107 #endif
108 
109 /* Currently, nothing to do */
110 #define ABTD_thread_context_free(p_ctx)
111 
112 static inline void ABTD_thread_context_switch(ABTD_thread_context *p_old,
113  ABTD_thread_context *p_new)
114 {
115  ABTD_thread_context_jump(p_old, p_new, p_new);
116 }
117 
118 static inline void ABTD_thread_finish_context(ABTD_thread_context *p_old,
119  ABTD_thread_context *p_new)
120 {
121  ABTD_thread_context_take(p_old, p_new, p_new);
122 }
123 
124 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
125 static inline void ABTD_thread_context_make_and_call(ABTD_thread_context *p_old,
126  void (*f_thread)(void *),
127  void *p_arg,
128  void *p_stacktop)
129 {
130  ABTD_thread_context_init_and_call(p_old, p_stacktop, f_thread, p_arg);
131 }
132 
133 static inline ABT_bool
134 ABTD_thread_context_is_dynamic_promoted(ABTD_thread_context *p_ctx)
135 {
136  /* Check if the ULT has been dynamically promoted; internally, it checks if
137  * the context is NULL. */
138  return p_ctx->p_ctx ? ABT_TRUE : ABT_FALSE;
139 }
140 
141 static inline void ABTDI_thread_context_dynamic_promote(void *p_stacktop,
142  void *jump_f)
143 {
144  /* Perform dynamic promotion */
145  void **p_return_address = (void **)(((char *)p_stacktop) - 0x10);
146  void ***p_stack_pointer = (void ***)(((char *)p_stacktop) - 0x08);
147  *p_stack_pointer = p_return_address;
148  *p_return_address = jump_f;
149 }
150 
151 static inline void ABTD_thread_context_dynamic_promote_thread(void *p_stacktop)
152 {
153  union fp_conv {
154  void (*f)(void *);
155  void *ptr;
156  } conv;
157  conv.f = ABTD_thread_terminate_thread_no_arg;
158  void *jump_f = conv.ptr;
159  ABTDI_thread_context_dynamic_promote(p_stacktop, jump_f);
160 }
161 #endif
162 
163 static inline void ABTD_thread_context_set_arg(ABTD_thread_context *p_ctx,
164  void *arg)
165 {
166  p_ctx->p_arg = arg;
167 }
168 
169 static inline void *ABTD_thread_context_get_arg(ABTD_thread_context *p_ctx)
170 {
171  return p_ctx->p_arg;
172 }
173 
174 #endif /* ABTD_THREAD_H_INCLUDED */
static int ABTDI_thread_context_create(ABTD_thread_context *p_link, void(*f_wrapper)(void *), void(*f_thread)(void *), void *p_arg, size_t stacksize, void *p_stack, ABTD_thread_context *p_newctx)
Definition: abtd_thread.h:21
int ABT_bool
Definition: abt.h:309
static void ABTDI_thread_context_dynamic_promote(void *p_stacktop, void *jump_f)
Definition: abtd_thread.h:141
#define ABT_FALSE
Definition: abt.h:224
#define ABT_SUCCESS
Definition: abt.h:64
#define ABT_TRUE
Definition: abt.h:223