ARGOBOTS  dce6e727ffc4ca5b3ffc04cb9517c6689be51ec5
log.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 <stdio.h>
7 #include <stdarg.h>
8 #include "abti.h"
9 
10 #ifdef ABT_CONFIG_USE_DEBUG_LOG
11 
12 void ABTI_log_debug(const char *format, ...)
13 {
14  ABTI_global *p_global = ABTI_global_get_global_or_null();
15  if (!p_global || p_global->use_logging == ABT_FALSE)
16  return;
17  ABTI_local *p_local = ABTI_local_get_local_uninlined();
18 
19  const char *prefix_fmt = NULL, *prefix = NULL;
20  char static_buffer[256], *newfmt;
21  uint64_t tid;
22  int rank;
23  size_t newfmt_len;
24 
25  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(p_local);
26  if (p_local_xstream) {
27  ABTI_ythread *p_ythread =
28  ABTI_thread_get_ythread(p_local_xstream->p_thread);
29  if (p_ythread == NULL) {
30  if (p_local_xstream->type != ABTI_XSTREAM_TYPE_PRIMARY) {
31  prefix_fmt = "<U%" PRIu64 ":E%d> %s";
32  rank = p_local_xstream->rank;
33  tid = 0;
34  } else {
35  prefix = "<U0:E0> ";
36  prefix_fmt = "%s%s";
37  }
38  } else {
39  rank = p_local_xstream->rank;
40  prefix_fmt = "<U%" PRIu64 ":E%d> %s";
41  tid = ABTI_thread_get_id(&p_ythread->thread);
42  }
43  } else {
44  prefix = "<EXT> ";
45  prefix_fmt = "%s%s";
46  }
47 
48  if (prefix == NULL) {
49  /* Both tid and rank are less than 42 characters in total. */
50  const int len_tid_rank = 50;
51  newfmt_len = 6 + len_tid_rank + strlen(format);
52  if (sizeof(static_buffer) >= newfmt_len + 1) {
53  newfmt = static_buffer;
54  } else {
55  int abt_errno = ABTU_malloc(newfmt_len + 1, (void **)&newfmt);
56  if (abt_errno != ABT_SUCCESS)
57  return;
58  }
59  sprintf(newfmt, prefix_fmt, tid, rank, format);
60  } else {
61  newfmt_len = strlen(prefix) + strlen(format);
62  if (sizeof(static_buffer) >= newfmt_len + 1) {
63  newfmt = static_buffer;
64  } else {
65  int abt_errno = ABTU_malloc(newfmt_len + 1, (void **)&newfmt);
66  if (abt_errno != ABT_SUCCESS)
67  return;
68  }
69  sprintf(newfmt, prefix_fmt, prefix, format);
70  }
71 
72 #ifndef ABT_CONFIG_USE_DEBUG_LOG_DISCARD
73  va_list list;
74  va_start(list, format);
75  vfprintf(stderr, newfmt, list);
76  va_end(list);
77  fflush(stderr);
78 #else
79  /* Discard the log message. This option is used to check if the logging
80  * function works correct (i.e., without any SEGV) but a tester does not
81  * need an actual log since the output can be extremely large. */
82 #endif
83  if (newfmt != static_buffer) {
84  ABTU_free(newfmt);
85  }
86 }
87 
88 void ABTI_log_debug_thread(const char *msg, ABTI_thread *p_thread)
89 {
90  if (!p_thread) {
91  /* Unknown thread. */
92  ABTI_log_debug("%s [unknown ULT]\n", msg);
93  } else if (p_thread->type & ABTI_THREAD_TYPE_ROOT) {
94  /* This should not appear in a log. */
95  } else if (p_thread->type & ABTI_THREAD_TYPE_PRIMARY) {
96  /* Primary ULT. */
97  ABTI_log_debug("%s U%" PRIu64 " (primary)\n", msg,
98  ABTI_thread_get_id(p_thread));
99  } else if (p_thread->type & ABTI_THREAD_TYPE_MAIN_SCHED) {
100  /* Main scheduler ULT. */
101  ABTI_log_debug("%s U%" PRIu64 " (main sched)\n", msg,
102  ABTI_thread_get_id(p_thread));
103  } else if (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) {
104  /* Normal yieldable ULT. */
105  ABTI_log_debug("%s U%" PRIu64 "\n", msg, ABTI_thread_get_id(p_thread));
106  } else {
107  /* Not yieldable. */
108  ABTI_log_debug("%s T%" PRIu64 "\n", msg, ABTI_thread_get_id(p_thread));
109  }
110 }
111 
112 void ABTI_log_pool_push(ABTI_pool *p_pool, ABT_unit unit)
113 {
114  ABTI_global *p_global = ABTI_global_get_global_or_null();
115  if (!p_global || p_global->use_logging == ABT_FALSE)
116  return;
117  if (unit == ABT_UNIT_NULL)
118  return;
119 
120  ABTI_thread *p_thread = ABTI_unit_get_thread(p_global, unit);
121  char unit_type = (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) ? 'U' : 'T';
122  if (p_thread->p_last_xstream) {
123  ABTI_log_debug("[%c%" PRIu64 ":E%d] pushed to P%" PRIu64 "\n",
124  unit_type, ABTI_thread_get_id(p_thread),
125  p_thread->p_last_xstream->rank, p_pool->id);
126  } else {
127  ABTI_log_debug("[%c%" PRIu64 "] pushed to P%" PRIu64 "\n", unit_type,
128  ABTI_thread_get_id(p_thread), p_pool->id);
129  }
130 }
131 
132 void ABTI_log_pool_remove(ABTI_pool *p_pool, ABT_unit unit)
133 {
134  ABTI_global *p_global = ABTI_global_get_global_or_null();
135  if (!p_global || p_global->use_logging == ABT_FALSE)
136  return;
137  if (unit == ABT_UNIT_NULL)
138  return;
139 
140  ABTI_thread *p_thread = ABTI_unit_get_thread(p_global, unit);
141  char unit_type = (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) ? 'U' : 'T';
142  if (p_thread->p_last_xstream) {
143  ABTI_log_debug("[%c%" PRIu64 ":E%d] removed from P%" PRIu64 "\n",
144  unit_type, ABTI_thread_get_id(p_thread),
145  p_thread->p_last_xstream->rank, p_pool->id);
146  } else {
147  ABTI_log_debug("[%c%" PRIu64 "] removed from P%" PRIu64 "\n", unit_type,
148  ABTI_thread_get_id(p_thread), p_pool->id);
149  }
150 }
151 
152 void ABTI_log_pool_pop(ABTI_pool *p_pool, ABT_thread thread)
153 {
154  ABTI_global *p_global = ABTI_global_get_global_or_null();
155  if (!p_global || p_global->use_logging == ABT_FALSE)
156  return;
157  if (thread == ABT_THREAD_NULL)
158  return;
159 
160  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
161  char unit_type = (p_thread->type & ABTI_THREAD_TYPE_YIELDABLE) ? 'U' : 'T';
162  if (p_thread->p_last_xstream) {
163  ABTI_log_debug("[%c%" PRIu64 ":E%d] popped from P%" PRIu64 "\n",
164  unit_type, ABTI_thread_get_id(p_thread),
165  p_thread->p_last_xstream->rank, p_pool->id);
166  } else {
167  ABTI_log_debug("[%c%" PRIu64 "] popped from P%" PRIu64 "\n", unit_type,
168  ABTI_thread_get_id(p_thread), p_pool->id);
169  }
170 }
171 
172 void ABTI_log_pool_pop_many(ABTI_pool *p_pool, const ABT_thread *threads,
173  size_t num)
174 {
175  size_t i;
176  for (i = 0; i < num; i++) {
177  ABTI_log_pool_pop(p_pool, threads[i]);
178  }
179 }
180 
181 void ABTI_log_pool_push_many(ABTI_pool *p_pool, const ABT_unit *units,
182  size_t num)
183 {
184  size_t i;
185  for (i = 0; i < num; i++) {
186  ABTI_log_pool_push(p_pool, units[i]);
187  }
188 }
189 
190 #endif /* ABT_CONFIG_USE_DEBUG_LOG */
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:932
ABT_THREAD_NULL
#define ABT_THREAD_NULL
Definition: abt.h:1105
abti.h
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
ABT_unit
struct ABT_unit_opaque * ABT_unit
Work unit handle type for scheduling.
Definition: abt.h:911
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_UNIT_NULL
#define ABT_UNIT_NULL
Definition: abt.h:1104