Skip to content

Commit 1772eeb

Browse files
Merge pull request #100 from shintaro-iwasaki/SupportUcontext
Support ucontext
2 parents db23634 + 5c387f1 commit 1772eeb

File tree

8 files changed

+204
-235
lines changed

8 files changed

+204
-235
lines changed

src/arch/abtd_thread.c

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ static inline void ABTD_thread_terminate_thread(ABTI_local *p_local,
1010
static inline void ABTD_thread_terminate_sched(ABTI_local *p_local,
1111
ABTI_thread *p_thread);
1212

13-
#if defined(ABT_CONFIG_USE_FCONTEXT)
1413
void ABTD_thread_func_wrapper_thread(void *p_arg)
1514
{
16-
ABTD_thread_context *p_fctx = (ABTD_thread_context *)p_arg;
17-
void (*thread_func)(void *) = p_fctx->f_thread;
15+
ABTD_thread_context *p_ctx = (ABTD_thread_context *)p_arg;
16+
void (*thread_func)(void *) = p_ctx->f_thread;
1817

19-
thread_func(p_fctx->p_arg);
18+
thread_func(p_ctx->p_arg);
2019

2120
/* NOTE: ctx is located in the beginning of ABTI_thread */
22-
ABTI_thread *p_thread = (ABTI_thread *)p_fctx;
21+
ABTI_thread *p_thread = (ABTI_thread *)p_ctx;
2322
#ifndef ABT_CONFIG_DISABLE_STACKABLE_SCHED
2423
ABTI_ASSERT(p_thread->is_sched == NULL);
2524
#endif
@@ -30,56 +29,20 @@ void ABTD_thread_func_wrapper_thread(void *p_arg)
3029

3130
void ABTD_thread_func_wrapper_sched(void *p_arg)
3231
{
33-
ABTD_thread_context *p_fctx = (ABTD_thread_context *)p_arg;
34-
void (*thread_func)(void *) = p_fctx->f_thread;
32+
ABTD_thread_context *p_ctx = (ABTD_thread_context *)p_arg;
33+
void (*thread_func)(void *) = p_ctx->f_thread;
3534

36-
thread_func(p_fctx->p_arg);
35+
thread_func(p_ctx->p_arg);
3736

3837
/* NOTE: ctx is located in the beginning of ABTI_thread */
39-
ABTI_thread *p_thread = (ABTI_thread *)p_fctx;
38+
ABTI_thread *p_thread = (ABTI_thread *)p_ctx;
4039
#ifndef ABT_CONFIG_DISABLE_STACKABLE_SCHED
4140
ABTI_ASSERT(p_thread->is_sched != NULL);
4241
#endif
4342

4443
ABTI_local *p_local = ABTI_local_get_local();
4544
ABTD_thread_terminate_sched(p_local, p_thread);
4645
}
47-
#else
48-
void ABTD_thread_func_wrapper(int func_upper, int func_lower,
49-
int arg_upper, int arg_lower)
50-
{
51-
ABTI_local *p_local = ABTI_local_get_local();
52-
void (*thread_func)(void *);
53-
void *p_arg;
54-
size_t ptr_size, int_size;
55-
56-
ptr_size = sizeof(void *);
57-
int_size = sizeof(int);
58-
if (ptr_size == int_size) {
59-
thread_func = (void (*)(void *))(uintptr_t)func_lower;
60-
p_arg = (void *)(uintptr_t)arg_lower;
61-
} else if (ptr_size == int_size * 2) {
62-
uintptr_t shift_bits = CHAR_BIT * int_size;
63-
uintptr_t mask = ((uintptr_t)1 << shift_bits) - 1;
64-
thread_func = (void (*)(void *))(
65-
((uintptr_t)func_upper << shift_bits) |
66-
((uintptr_t)func_lower & mask));
67-
p_arg = (void *)(
68-
((uintptr_t)arg_upper << shift_bits) |
69-
((uintptr_t)arg_lower & mask));
70-
} else {
71-
ABTI_ASSERT(0);
72-
}
73-
74-
thread_func(p_arg);
75-
76-
/* Now, the ULT has finished its job. Terminate the ULT.
77-
* We don't need to use the atomic operation here because the ULT will be
78-
* terminated regardless of other requests. */
79-
ABTI_thread *p_thread = p_local->p_thread;
80-
p_thread->request |= ABTI_THREAD_REQ_TERMINATE;
81-
}
82-
#endif
8346

8447
void ABTD_thread_exit(ABTI_local *p_local, ABTI_thread *p_thread)
8548
{
@@ -98,10 +61,9 @@ static inline void ABTDI_thread_terminate(ABTI_local *p_local,
9861
ABTI_thread *p_thread,
9962
ABT_bool is_sched)
10063
{
101-
#if defined(ABT_CONFIG_USE_FCONTEXT)
102-
ABTD_thread_context *p_fctx = &p_thread->ctx;
64+
ABTD_thread_context *p_ctx = &p_thread->ctx;
10365
ABTD_thread_context *p_link = (ABTD_thread_context *)
104-
ABTD_atomic_load_ptr((void **)&p_fctx->p_link);
66+
ABTD_atomic_load_ptr((void **)&p_ctx->p_link);
10567
if (p_link) {
10668
/* If p_link is set, it means that other ULT has called the join. */
10769
ABTI_thread *p_joiner = (ABTI_thread *)p_link;
@@ -150,15 +112,15 @@ static inline void ABTDI_thread_terminate(ABTI_local *p_local,
150112
* blocked. We have to wake up the joiner ULT. */
151113
do {
152114
p_link = (ABTD_thread_context *)
153-
ABTD_atomic_load_ptr((void **)&p_fctx->p_link);
115+
ABTD_atomic_load_ptr((void **)&p_ctx->p_link);
154116
} while (!p_link);
155117
ABTI_thread_set_ready(p_local, (ABTI_thread *)p_link);
156118
}
157119
}
158120

159-
/* No other ULT is waiting or blocked for this ULT. Since fcontext does
160-
* not switch to other fcontext when it finishes, we need to explicitly
161-
* switch to the scheduler. */
121+
/* No other ULT is waiting or blocked for this ULT. Since a context does not
122+
* switch to another context when it finishes, we need to explicitly switch
123+
* to the scheduler. */
162124
ABTI_sched *p_sched;
163125
#ifndef ABT_CONFIG_DISABLE_STACKABLE_SCHED
164126
if (p_thread->is_sched) {
@@ -180,9 +142,6 @@ static inline void ABTDI_thread_terminate(ABTI_local *p_local,
180142
#ifndef ABT_CONFIG_DISABLE_STACKABLE_SCHED
181143
}
182144
#endif
183-
#else
184-
#error "Not implemented yet"
185-
#endif
186145
}
187146

188147
static inline void ABTD_thread_terminate_thread(ABTI_local *p_local,
@@ -215,62 +174,33 @@ void ABTD_thread_cancel(ABTI_local *p_local, ABTI_thread *p_thread)
215174
* ULT has finished its execution and calls ABTD_thread_terminate/exit,
216175
* this function is called by the scheduler. Therefore, we should not
217176
* context switch to the joiner ULT and need to always wake it up. */
218-
#if defined(ABT_CONFIG_USE_FCONTEXT)
219-
ABTD_thread_context *p_fctx = &p_thread->ctx;
177+
ABTD_thread_context *p_ctx = &p_thread->ctx;
220178

221179
/* acquire load is not needed here. */
222-
if (p_fctx->p_link) {
180+
if (p_ctx->p_link) {
223181
/* If p_link is set, it means that other ULT has called the join. */
224-
ABTI_thread *p_joiner = (ABTI_thread *)p_fctx->p_link;
182+
ABTI_thread *p_joiner = (ABTI_thread *)p_ctx->p_link;
225183
ABTI_thread_set_ready(p_local, p_joiner);
226184
} else {
227185
uint32_t req = ABTD_atomic_fetch_or_uint32(&p_thread->request,
228186
ABTI_THREAD_REQ_JOIN | ABTI_THREAD_REQ_TERMINATE);
229187
if (req & ABTI_THREAD_REQ_JOIN) {
230188
/* This case means there has been a join request and the joiner has
231189
* blocked. We have to wake up the joiner ULT. */
232-
while (ABTD_atomic_load_ptr((void **)&p_fctx->p_link) == NULL);
233-
ABTI_thread *p_joiner = (ABTI_thread *)p_fctx->p_link;
190+
while (ABTD_atomic_load_ptr((void **)&p_ctx->p_link) == NULL);
191+
ABTI_thread *p_joiner = (ABTI_thread *)p_ctx->p_link;
234192
ABTI_thread_set_ready(p_local, p_joiner);
235193
}
236194
}
237-
#else
238-
#error "Not implemented yet"
239-
#endif
240195
}
241196

242-
#if !defined(ABT_CONFIG_USE_FCONTEXT)
243-
static inline
244-
void print_bytes(size_t size, void *p_val, FILE *p_os) {
245-
size_t i;
246-
for (i = 0; i < size; i++) {
247-
uint8_t val = ((uint8_t *)p_val)[i];
248-
fprintf(p_os, "%02" PRIx8, val);
249-
}
250-
}
251-
#endif
252-
253197
void ABTD_thread_print_context(ABTI_thread *p_thread, FILE *p_os, int indent)
254198
{
255199
char *prefix = ABTU_get_indent_str(indent);
256200
ABTD_thread_context *p_ctx = &p_thread->ctx;
257-
#if defined(ABT_CONFIG_USE_FCONTEXT)
258-
fprintf(p_os, "%sfctx : %p\n", prefix, (void *)p_ctx->fctx);
201+
fprintf(p_os, "%sp_ctx : %p\n", prefix, p_ctx->p_ctx);
259202
fprintf(p_os, "%sp_arg : %p\n", prefix, p_ctx->p_arg);
260203
fprintf(p_os, "%sp_link : %p\n", prefix, (void *)p_ctx->p_link);
261-
#else
262-
/* TODO: print information in more detail. */
263-
fprintf(p_os, "%suc_link : %p\n", prefix, p_ctx->uc_link);
264-
fprintf(p_os, "%suc_sigmask : ", prefix);
265-
print_bytes(sizeof(sigset_t), &p_ctx->uc_sigmask, p_os);
266-
fprintf(p_os, "\n");
267-
fprintf(p_os, "%suc_stack : ", prefix);
268-
print_bytes(sizeof(stack_t), &p_ctx->uc_stack, p_os);
269-
fprintf(p_os, "\n");
270-
fprintf(p_os, "%suc_mcontext : ", prefix);
271-
print_bytes(sizeof(mcontext_t), &p_ctx->uc_mcontext, p_os);
272-
fprintf(p_os, "\n");
273-
#endif
274204
fflush(p_os);
275205
ABTU_free(prefix);
276206
}

src/include/Makefile.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ noinst_HEADERS = \
99
include/abt_config.h \
1010
include/abtd.h \
1111
include/abtd_atomic.h \
12+
include/abtd_context.h \
13+
include/abtd_fcontext.h \
1214
include/abtd_thread.h \
1315
include/abtd_ucontext.h \
1416
include/abti.h \

src/include/abtd.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#define __USE_GNU
1010
#include <pthread.h>
11-
#include "abtd_ucontext.h"
11+
#include "abtd_context.h"
1212

1313
/* Atomic Functions */
1414
#include "abtd_atomic.h"
@@ -21,7 +21,6 @@ typedef pthread_barrier_t ABTD_xstream_barrier;
2121
#else
2222
typedef void * ABTD_xstream_barrier;
2323
#endif
24-
typedef abt_ucontext_t ABTD_thread_context;
2524

2625
/* ES Storage Qualifier */
2726
#define ABTD_XSTREAM_LOCAL __thread

src/include/abtd_context.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2+
/*
3+
* See COPYRIGHT in top-level directory.
4+
*/
5+
6+
#ifndef ABTD_CONTEXT_H_INCLUDED
7+
#define ABTD_CONTEXT_H_INCLUDED
8+
9+
#include "abt_config.h"
10+
11+
#ifndef ABT_CONFIG_USE_FCONTEXT
12+
#define _XOPEN_SOURCE
13+
#include <ucontext.h>
14+
#endif
15+
16+
typedef struct ABTD_thread_context {
17+
void * p_ctx; /* actual context of fcontext, or a
18+
* pointer to uctx */
19+
void (*f_thread)(void *); /* ULT function */
20+
void * p_arg; /* ULT function argument */
21+
struct ABTD_thread_context *p_link; /* pointer to scheduler context */
22+
#ifndef ABT_CONFIG_USE_FCONTEXT
23+
ucontext_t uctx; /* ucontext entity pointed by p_ctx */
24+
void (*f_uctx_thread)(void *); /* root function called by ucontext */
25+
void * p_uctx_arg; /* argument for root function */
26+
#endif
27+
} ABTD_thread_context;
28+
29+
static void ABTD_thread_context_make(ABTD_thread_context *p_ctx, void *sp,
30+
size_t size, void (*thread_func)(void *));
31+
static void ABTD_thread_context_jump(ABTD_thread_context *p_old,
32+
ABTD_thread_context *p_new, void *arg);
33+
static void ABTD_thread_context_take(ABTD_thread_context *p_old,
34+
ABTD_thread_context *p_new, void *arg);
35+
#if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
36+
static void ABTD_thread_context_init_and_call(ABTD_thread_context *p_ctx,
37+
void *sp,
38+
void (*thread_func)(void *),
39+
void *arg);
40+
#endif
41+
42+
void ABTD_thread_print_context(ABTI_thread *p_thread, FILE *p_os, int indent);
43+
44+
#ifdef ABT_CONFIG_USE_FCONTEXT
45+
#include "abtd_fcontext.h"
46+
#else
47+
#include "abtd_ucontext.h"
48+
#endif
49+
50+
#endif /* ABTD_CONTEXT_H_INCLUDED */

src/include/abtd_fcontext.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2+
/*
3+
* See COPYRIGHT in top-level directory.
4+
*/
5+
6+
#ifndef ABTD_FCONTEXT_H_INCLUDED
7+
#define ABTD_FCONTEXT_H_INCLUDED
8+
9+
typedef void *fcontext_t;
10+
11+
#if defined(ABT_C_HAVE_VISIBILITY)
12+
#define ABT_API_PRIVATE __attribute__((visibility ("hidden")))
13+
#else
14+
#define ABT_API_PRIVATE
15+
#endif
16+
17+
fcontext_t make_fcontext(void *sp, size_t size, void (*thread_func)(void *))
18+
ABT_API_PRIVATE;
19+
void *jump_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE;
20+
void *take_fcontext(fcontext_t *old, fcontext_t new, void *arg) ABT_API_PRIVATE;
21+
#if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
22+
void init_and_call_fcontext(void *p_arg, void (*f_thread)(void *),
23+
void *p_stacktop, fcontext_t *old);
24+
#endif
25+
26+
static inline
27+
void ABTD_thread_context_make(ABTD_thread_context *p_ctx, void *sp, size_t size,
28+
void (*thread_func)(void *))
29+
{
30+
p_ctx->p_ctx = make_fcontext(sp, size, thread_func);
31+
}
32+
33+
static inline
34+
void ABTD_thread_context_jump(ABTD_thread_context *p_old,
35+
ABTD_thread_context *p_new, void *arg)
36+
{
37+
jump_fcontext(&p_old->p_ctx, p_new->p_ctx, arg);
38+
}
39+
40+
static inline
41+
void ABTD_thread_context_take(ABTD_thread_context *p_old,
42+
ABTD_thread_context *p_new, void *arg)
43+
{
44+
take_fcontext(&p_old->p_ctx, p_new->p_ctx, arg);
45+
}
46+
47+
#if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
48+
static inline
49+
void ABTD_thread_context_init_and_call(ABTD_thread_context *p_ctx, void *sp,
50+
void (*thread_func)(void *), void *arg)
51+
{
52+
init_and_call_fcontext(arg, thread_func, sp, &p_ctx->p_ctx);
53+
}
54+
#endif
55+
56+
#endif /* ABTD_FCONTEXT_H_INCLUDED */

0 commit comments

Comments
 (0)