ARGOBOTS  1059a7c2eb7e3f99f736a9c3a4f6ea476ac1b804
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
abtd_ythread.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 inline void ythread_terminate(ABTI_xstream *p_local_xstream,
9  ABTI_ythread *p_ythread);
10 
11 void ABTD_ythread_func_wrapper(void *p_arg)
12 {
15  ABTI_xstream *p_local_xstream = p_ythread->thread.p_last_xstream;
16  ABTI_tool_event_thread_run(p_local_xstream, &p_ythread->thread,
17  p_local_xstream->p_thread,
18  p_ythread->thread.p_parent);
19  p_local_xstream->p_thread = &p_ythread->thread;
20 
21  p_ythread->thread.f_thread(p_ythread->thread.p_arg);
22 
23  /* This ABTI_local_get_xstream() is controversial since it is called after
24  * the context-switchable function (i.e., thread_func()). We assume that
25  * the compiler does not load TLS offset etc before thread_func(). */
26  p_local_xstream = ABTI_local_get_xstream(ABTI_local_get_local());
27  ythread_terminate(p_local_xstream, p_ythread);
28 }
29 
30 void ABTD_ythread_exit(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
31 {
32  ythread_terminate(p_local_xstream, p_ythread);
33 }
34 
35 static inline void ythread_terminate(ABTI_xstream *p_local_xstream,
36  ABTI_ythread *p_ythread)
37 {
38  ABTD_ythread_context *p_ctx = &p_ythread->ctx;
39  ABTD_ythread_context *p_link =
41  if (p_link) {
42  /* If p_link is set, it means that other ULT has called the join. */
44  if (p_ythread->thread.p_last_xstream ==
45  p_joiner->thread.p_last_xstream &&
46  !(p_ythread->thread.type & ABTI_THREAD_TYPE_MAIN_SCHED)) {
47  /* Only when the current ULT is on the same ES as p_joiner's,
48  * we can jump to the joiner ULT. */
51  LOG_DEBUG("[U%" PRIu64 ":E%d] terminated\n",
52  ABTI_thread_get_id(&p_ythread->thread),
53  p_ythread->thread.p_last_xstream->rank);
54 
55  /* Note that a parent ULT cannot be a joiner. */
57  p_local_xstream),
58  p_joiner, &p_ythread->thread);
59  ABTI_ythread_finish_context_to_sibling(p_local_xstream, p_ythread,
60  p_joiner);
61  return;
62  } else {
63  /* If the current ULT's associated ES is different from p_joiner's,
64  * we can't directly jump to p_joiner. Instead, we wake up
65  * p_joiner here so that p_joiner's scheduler can resume it.
66  * Note that the main scheduler needs to jump back to the root
67  * scheduler, so the main scheduler needs to take this path. */
69  p_joiner);
70 
71  /* We don't need to use the atomic OR operation here because the ULT
72  * will be terminated regardless of other requests. */
75  }
76  } else {
77  uint32_t req =
81  if (req & ABTI_THREAD_REQ_JOIN) {
82  /* This case means there has been a join request and the joiner has
83  * blocked. We have to wake up the joiner ULT. */
84  do {
86  &p_ctx->p_link);
87  } while (!p_link);
90  }
91  }
92 
93  /* No other ULT is waiting or blocked for this ULT. Since a context does not
94  * switch to another context when it finishes, we need to explicitly switch
95  * to the parent. */
96  ABTI_ythread_finish_context_to_parent(p_local_xstream, p_ythread);
97 }
98 
99 #if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
101 {
102  ABTI_local *p_local = ABTI_local_get_local();
103  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream(p_local);
104  /* This function is called by `return` in
105  * ABTD_ythread_context_make_and_call, so it cannot take the argument. We
106  * get the thread descriptor from TLS. */
107  ABTI_thread *p_thread = p_local_xstream->p_thread;
109  ythread_terminate(p_local_xstream, ABTI_thread_get_ythread(p_thread));
110 }
111 #endif
112 
113 void ABTD_ythread_cancel(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
114 {
115  /* When we cancel a ULT, if other ULT is blocked to join the canceled ULT,
116  * we have to wake up the joiner ULT. However, unlike the case when the
117  * ULT has finished its execution and calls ythread_terminate/exit,
118  * this function is called by the scheduler. Therefore, we should not
119  * context switch to the joiner ULT and need to always wake it up. */
120  ABTD_ythread_context *p_ctx = &p_ythread->ctx;
121 
123  /* If p_link is set, it means that other ULT has called the join. */
127  p_joiner);
128  } else {
129  uint32_t req =
133  if (req & ABTI_THREAD_REQ_JOIN) {
134  /* This case means there has been a join request and the joiner has
135  * blocked. We have to wake up the joiner ULT. */
137  &p_ctx->p_link) == NULL)
138  ;
142  p_joiner);
143  }
144  }
145  ABTI_tool_event_thread_cancel(p_local_xstream, &p_ythread->thread);
146 }
147 
148 void ABTD_ythread_print_context(ABTI_ythread *p_ythread, FILE *p_os, int indent)
149 {
150  ABTD_ythread_context *p_ctx = &p_ythread->ctx;
151  fprintf(p_os, "%*sp_ctx : %p\n", indent, "", p_ctx->p_ctx);
152  fprintf(p_os, "%*sp_link : %p\n", indent, "",
154  &p_ctx->p_link));
155  fflush(p_os);
156 }
ABTD_ythread_context_atomic_ptr p_link
Definition: abtd_context.h:53
ABTD_atomic_uint32 request
Definition: abti.h:323
static ABTD_ythread_context * ABTD_atomic_relaxed_load_ythread_context_ptr(const ABTD_ythread_context_atomic_ptr *ptr)
Definition: abtd_context.h:25
struct ABTI_local ABTI_local
Definition: abti.h:101
void ABTD_ythread_print_context(ABTI_ythread *p_ythread, FILE *p_os, int indent)
Definition: abtd_ythread.c:148
void ABTD_ythread_terminate_no_arg(void)
Definition: abtd_ythread.c:100
static void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:924
void(* f_thread)(void *)
Definition: abti.h:320
ABTI_thread_type type
Definition: abti.h:316
ABTI_thread * p_thread
Definition: abti.h:251
void ABTD_ythread_exit(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
Definition: abtd_ythread.c:30
static void ABTD_atomic_release_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:947
void ABTD_ythread_func_wrapper(void *p_arg)
Definition: abtd_ythread.c:11
#define ABTI_THREAD_REQ_JOIN
Definition: abti.h:41
static uint32_t ABTD_atomic_fetch_or_uint32(ABTD_atomic_uint32 *ptr, uint32_t v)
Definition: abtd_atomic.h:538
ABT_unit_id ABTI_thread_get_id(ABTI_thread *p_thread)
Definition: thread.c:1600
static ABTI_ythread * ABTI_ythread_context_get_ythread(ABTD_ythread_context *p_ctx)
Definition: abti_ythread.h:42
ABTI_xstream * p_last_xstream
Definition: abti.h:318
static void ythread_terminate(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
Definition: abtd_ythread.c:35
int rank
Definition: abti.h:239
ABTD_atomic_int state
Definition: abti.h:322
#define ABTI_tool_event_ythread_resume(p_local, p_ythread, p_caller)
Definition: abti_tool.h:383
void * p_arg
Definition: abti.h:321
ABTI_thread thread
Definition: abti.h:348
#define ABTI_THREAD_REQ_TERMINATE
Definition: abti.h:42
#define ABTI_THREAD_TYPE_YIELDABLE
Definition: abti.h:77
static ABTU_noreturn void ABTI_ythread_finish_context_to_parent(ABTI_xstream *p_local_xstream, ABTI_ythread *p_old)
Definition: abti_ythread.h:340
void ABTD_ythread_cancel(ABTI_xstream *p_local_xstream, ABTI_ythread *p_ythread)
Definition: abtd_ythread.c:113
static ABTU_noreturn void ABTI_ythread_finish_context_to_sibling(ABTI_xstream *p_local_xstream, ABTI_ythread *p_old, ABTI_ythread *p_new)
Definition: abti_ythread.h:331
ABTD_ythread_context ctx
Definition: abti.h:349
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
#define ABTI_tool_event_thread_cancel(p_local_xstream, p_thread)
Definition: abti_tool.h:356
static ABTI_xstream * ABTI_local_get_xstream(ABTI_local *p_local)
Definition: abti_local.h:86
static ABTI_ythread * ABTI_thread_get_ythread(ABTI_thread *p_thread)
Definition: abti_thread.h:52
void ABTI_ythread_set_ready(ABTI_local *p_local, ABTI_ythread *p_ythread)
Definition: ythread.c:50
#define ABTI_tool_event_thread_run(p_local_xstream, p_thread, p_prev,p_parent)
Definition: abti_tool.h:339
static ABTI_local * ABTI_xstream_get_local(ABTI_xstream *p_xstream)
Definition: abti_stream.h:67
static ABTI_local * ABTI_local_get_local(void)
Definition: abti_local.h:41
static ABTD_ythread_context * ABTD_atomic_acquire_load_ythread_context_ptr(const ABTD_ythread_context_atomic_ptr *ptr)
Definition: abtd_context.h:32
#define ABTI_THREAD_TYPE_MAIN_SCHED
Definition: abti.h:76
ABTI_thread * p_parent
Definition: abti.h:319