ARGOBOTS  c6511494322293e01714f56f341b8d2b22c1e3c1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
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 void ABTI_ythread_set_blocked(ABTI_ythread *p_ythread)
9 {
10  /* The root thread cannot be blocked */
11  ABTI_ASSERT(!(p_ythread->thread.type & ABTI_THREAD_TYPE_ROOT));
12 
13  /* To prevent the scheduler from adding the ULT to the pool */
14  ABTI_thread_set_request(&p_ythread->thread, ABTI_THREAD_REQ_BLOCK);
15 
16  /* Change the ULT's state to BLOCKED */
17  ABTD_atomic_release_store_int(&p_ythread->thread.state,
19 
20  /* Increase the number of blocked ULTs */
21  ABTI_pool *p_pool = p_ythread->thread.p_pool;
22  ABTI_pool_inc_num_blocked(p_pool);
23 
24  LOG_DEBUG("[U%" PRIu64 ":E%d] blocked\n",
25  ABTI_thread_get_id(&p_ythread->thread),
26  p_ythread->thread.p_last_xstream->rank);
27 }
28 
29 /* NOTE: This routine should be called after ABTI_ythread_set_blocked. */
30 void ABTI_ythread_suspend(ABTI_xstream **pp_local_xstream,
31  ABTI_ythread *p_ythread,
32  ABT_sync_event_type sync_event_type, void *p_sync)
33 {
34  ABTI_xstream *p_local_xstream = *pp_local_xstream;
35  ABTI_ASSERT(&p_ythread->thread == p_local_xstream->p_thread);
36  ABTI_ASSERT(p_ythread->thread.p_last_xstream == p_local_xstream);
37 
38  /* Switch to the scheduler, i.e., suspend p_ythread */
39  LOG_DEBUG("[U%" PRIu64 ":E%d] suspended\n",
40  ABTI_thread_get_id(&p_ythread->thread), p_local_xstream->rank);
41  ABTI_ythread_context_switch_to_parent(pp_local_xstream, p_ythread,
42  sync_event_type, p_sync);
43 
44  /* The suspended ULT resumes its execution from here. */
45  LOG_DEBUG("[U%" PRIu64 ":E%d] resumed\n",
46  ABTI_thread_get_id(&p_ythread->thread),
47  p_ythread->thread.p_last_xstream->rank);
48 }
49 
50 void ABTI_ythread_set_ready(ABTI_local *p_local, ABTI_ythread *p_ythread)
51 {
52  /* The ULT must be in BLOCKED state. */
53  ABTI_ASSERT(ABTD_atomic_acquire_load_int(&p_ythread->thread.state) ==
55 
56  /* We should wait until the scheduler of the blocked ULT resets the BLOCK
57  * request. Otherwise, the ULT can be pushed to a pool here and be
58  * scheduled by another scheduler if it is pushed to a shared pool. */
59  while (ABTD_atomic_acquire_load_uint32(&p_ythread->thread.request) &
60  ABTI_THREAD_REQ_BLOCK)
61  ABTD_atomic_pause();
62 
63  LOG_DEBUG("[U%" PRIu64 ":E%d] set ready\n",
64  ABTI_thread_get_id(&p_ythread->thread),
65  p_ythread->thread.p_last_xstream->rank);
66 
67  ABTI_tool_event_ythread_resume(p_local, p_ythread,
68  ABTI_local_get_xstream_or_null(p_local)
69  ? ABTI_local_get_xstream(p_local)
70  ->p_thread
71  : NULL);
72  /* p_ythread->thread.p_pool is loaded before ABTI_POOL_ADD_THREAD to keep
73  * num_blocked consistent. Otherwise, other threads might pop p_ythread
74  * that has been pushed in ABTI_POOL_ADD_THREAD and change
75  * p_ythread->thread.p_pool by ABT_unit_set_associated_pool. */
76  ABTI_pool *p_pool = p_ythread->thread.p_pool;
77 
78  /* Add the ULT to its associated pool */
79  ABTI_pool_add_thread(&p_ythread->thread);
80 
81  /* Decrease the number of blocked threads */
82  ABTI_pool_dec_num_blocked(p_pool);
83 }
84 
85 ABTU_no_sanitize_address void ABTI_ythread_print_stack(ABTI_ythread *p_ythread,
86  FILE *p_os)
87 {
88  void *p_stack = p_ythread->p_stack;
89  size_t i, j, stacksize = p_ythread->stacksize;
90  if (stacksize == 0 || p_stack == NULL) {
91  /* Some threads do not have p_stack (e.g., the main thread) */
92  return;
93  }
94 
95  char buffer[32];
96  const size_t value_width = 8;
97  const int num_bytes = sizeof(buffer);
98 
99  for (i = 0; i < stacksize; i += num_bytes) {
100  if (stacksize >= i + num_bytes) {
101  memcpy(buffer, &((uint8_t *)p_stack)[i], num_bytes);
102  } else {
103  memset(buffer, 0, num_bytes);
104  memcpy(buffer, &((uint8_t *)p_stack)[i], stacksize - i);
105  }
106  /* Print the stack address */
107 #if SIZEOF_VOID_P == 8
108  fprintf(p_os, "%016" PRIxPTR ":",
109  (uintptr_t)(&((uint8_t *)p_stack)[i]));
110 #elif SIZEOF_VOID_P == 4
111  fprintf(p_os, "%08" PRIxPTR ":", (uintptr_t)(&((uint8_t *)p_stack)[i]));
112 #else
113 #error "unknown pointer size"
114 #endif
115  /* Print the raw stack data */
116  for (j = 0; j < num_bytes / value_width; j++) {
117  if (value_width == 8) {
118  uint64_t val = ((uint64_t *)buffer)[j];
119  fprintf(p_os, " %016" PRIx64, val);
120  } else if (value_width == 4) {
121  uint32_t val = ((uint32_t *)buffer)[j];
122  fprintf(p_os, " %08" PRIx32, val);
123  } else if (value_width == 2) {
124  uint16_t val = ((uint16_t *)buffer)[j];
125  fprintf(p_os, " %04" PRIx16, val);
126  } else {
127  uint8_t val = ((uint8_t *)buffer)[j];
128  fprintf(p_os, " %02" PRIx8, val);
129  }
130  if (j == (num_bytes / value_width) - 1)
131  fprintf(p_os, "\n");
132  }
133  }
134 }
#define ABTU_no_sanitize_address
Definition: abtu.h:105
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
ABT_sync_event_type
Definition: abt.h:244