ARGOBOTS  23067fa015f4b179569e2d52278c1072e674eb1e
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
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(void *p_arg);
16 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
17 void ABTD_thread_terminate_no_arg();
18 #endif
19 
20 static inline int ABTD_thread_context_create(ABTD_thread_context *p_link,
21  size_t stacksize, void *p_stack,
22  ABTD_thread_context *p_newctx)
23 {
24  int abt_errno = ABT_SUCCESS;
25  void *p_stacktop;
26 
27  /* ABTD_thread_context_make uses the top address of stack.
28  Note that the parameter, p_stack, points to the bottom of stack. */
29  p_stacktop = (void *)(((char *)p_stack) + stacksize);
30 
31  ABTD_thread_context_make(p_newctx, p_stacktop, stacksize,
32  ABTD_thread_func_wrapper);
33  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, p_link);
34 
35  return abt_errno;
36 }
37 
38 static inline int ABTD_thread_context_invalidate(ABTD_thread_context *p_newctx)
39 {
40  int abt_errno = ABT_SUCCESS;
41 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
42  /* p_ctx is used to check whether the context requires dynamic promotion is
43  * necessary or not, so this value must not be NULL. */
44  p_newctx->p_ctx = (void *)((intptr_t)0x1);
45 #else
46  p_newctx->p_ctx = NULL;
47 #endif
48  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, NULL);
49  return abt_errno;
50 }
51 
52 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
53 static inline int ABTD_thread_context_init(ABTD_thread_context *p_link,
54  ABTD_thread_context *p_newctx)
55 {
56  int abt_errno = ABT_SUCCESS;
57  p_newctx->p_ctx = NULL;
58  ABTD_atomic_relaxed_store_thread_context_ptr(&p_newctx->p_link, p_link);
59  return abt_errno;
60 }
61 
62 static inline int ABTD_thread_context_arm_thread(size_t stacksize,
63  void *p_stack,
64  ABTD_thread_context *p_newctx)
65 {
66  /* This function *arms* the dynamic promotion thread (initialized by
67  * ABTD_thread_context_init) as if it were created by
68  * ABTD_thread_context_create; this function fully creates the context
69  * so that the thread can be run by ABTD_thread_context_jump. */
70  int abt_errno = ABT_SUCCESS;
71  /* ABTD_thread_context_make uses the top address of stack.
72  Note that the parameter, p_stack, points to the bottom of stack. */
73  void *p_stacktop = (void *)(((char *)p_stack) + stacksize);
74  ABTD_thread_context_make(p_newctx, p_stacktop, stacksize,
75  ABTD_thread_func_wrapper);
76  return abt_errno;
77 }
78 #endif
79 
80 /* Currently, nothing to do */
81 #define ABTD_thread_context_free(p_ctx)
82 
83 static inline void ABTD_thread_context_switch(ABTD_thread_context *p_old,
84  ABTD_thread_context *p_new)
85 {
86  ABTD_thread_context_jump(p_old, p_new, p_new);
87 }
88 
89 ABTU_noreturn static inline void
90 ABTD_thread_finish_context(ABTD_thread_context *p_old,
91  ABTD_thread_context *p_new)
92 {
93  ABTD_thread_context_take(p_old, p_new, p_new);
94 }
95 
96 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
97 static inline void ABTD_thread_context_make_and_call(ABTD_thread_context *p_old,
98  void (*f_thread)(void *),
99  void *p_arg,
100  void *p_stacktop)
101 {
102  ABTD_thread_context_init_and_call(p_old, p_stacktop, f_thread, p_arg);
103 }
104 
105 static inline ABT_bool
106 ABTD_thread_context_is_dynamic_promoted(ABTD_thread_context *p_ctx)
107 {
108  /* Check if the ULT has been dynamically promoted; internally, it checks if
109  * the context is NULL. */
110  return p_ctx->p_ctx ? ABT_TRUE : ABT_FALSE;
111 }
112 
113 static inline void ABTDI_thread_context_dynamic_promote(void *p_stacktop,
114  void *jump_f)
115 {
116  /* Perform dynamic promotion */
117  void **p_return_address = (void **)(((char *)p_stacktop) - 0x10);
118  void ***p_stack_pointer = (void ***)(((char *)p_stacktop) - 0x08);
119  *p_stack_pointer = p_return_address;
120  *p_return_address = jump_f;
121 }
122 
123 static inline void ABTD_thread_context_dynamic_promote_thread(void *p_stacktop)
124 {
125  union fp_conv {
126  void (*f)(void *);
127  void *ptr;
128  } conv;
129  conv.f = ABTD_thread_terminate_no_arg;
130  void *jump_f = conv.ptr;
131  ABTDI_thread_context_dynamic_promote(p_stacktop, jump_f);
132 }
133 #endif
134 
135 #endif /* ABTD_THREAD_H_INCLUDED */
int ABT_bool
Definition: abt.h:375
static void ABTDI_thread_context_dynamic_promote(void *p_stacktop, void *jump_f)
Definition: abtd_thread.h:113
#define ABT_FALSE
Definition: abt.h:287
#define ABT_SUCCESS
Definition: abt.h:64
#define ABT_TRUE
Definition: abt.h:286
#define ABTU_noreturn
Definition: abtu.h:31