Skip to content

Commit df593cb

Browse files
context: support ucontext
This patch implements a ucontext wrapper. Most of the logic is the same as the previous (partial) ucontext implementation.
1 parent 974a0b9 commit df593cb

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

src/include/Makefile.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ noinst_HEADERS = \
1111
include/abtd_atomic.h \
1212
include/abtd_fcontext.h \
1313
include/abtd_thread.h \
14+
include/abtd_ucontext.h \
1415
include/abtd_context.h \
1516
include/abti.h \
1617
include/abti_barrier.h \

src/include/abtd_context.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,23 @@
88

99
#include "abt_config.h"
1010

11+
#ifndef ABT_CONFIG_USE_FCONTEXT
12+
#define _XOPEN_SOURCE
13+
#include <ucontext.h>
14+
#endif
15+
1116
typedef void * fcontext_t;
1217

1318
typedef struct ABTD_thread_context {
1419
fcontext_t fctx; /* actual context */
1520
void (*f_thread)(void *); /* ULT function */
1621
void * p_arg; /* ULT function argument */
1722
struct ABTD_thread_context *p_link; /* pointer to scheduler context */
23+
#ifndef ABT_CONFIG_USE_FCONTEXT
24+
ucontext_t uctx; /* ucontext entity pointed by fctx */
25+
void (*f_uctx_thread)(void *); /* root function called by ucontext */
26+
void * p_uctx_arg; /* argument for root function */
27+
#endif
1828
} ABTD_thread_context;
1929

2030
static void ABTD_thread_context_make(ABTD_thread_context *p_ctx, void *sp,
@@ -32,6 +42,10 @@ static void ABTD_thread_context_init_and_call(ABTD_thread_context *p_ctx,
3242

3343
void ABTD_thread_print_context(ABTI_thread *p_thread, FILE *p_os, int indent);
3444

45+
#ifdef ABT_CONFIG_USE_FCONTEXT
3546
#include "abtd_fcontext.h"
47+
#else
48+
#include "abtd_ucontext.h"
49+
#endif
3650

3751
#endif /* ABTD_CONTEXT_H_INCLUDED */

src/include/abtd_ucontext.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2+
/*
3+
* See COPYRIGHT in top-level directory.
4+
*/
5+
6+
#ifndef ABTD_UCONTEXT_H_INCLUDED
7+
#define ABTD_UCONTEXT_H_INCLUDED
8+
9+
static void ABTD_ucontext_wrapper(int arg1, int arg2)
10+
{
11+
ABTD_thread_context *p_self;
12+
if (sizeof(void *) == 8) {
13+
p_self = (ABTD_thread_context *)(((uintptr_t)((uint32_t)arg1) << 32) |
14+
((uintptr_t)((uint32_t)arg2)));
15+
} else if (sizeof(void *) == 4) {
16+
p_self = (ABTD_thread_context *)((uintptr_t)arg1);
17+
} else {
18+
ABTI_ASSERT(0);
19+
}
20+
p_self->f_uctx_thread(p_self->p_uctx_arg);
21+
/* ABTD_thread_context_jump or take must be called at the end of
22+
* f_uctx_thread, */
23+
ABTI_ASSERT(0);
24+
}
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+
getcontext(&p_ctx->uctx);
31+
p_ctx->fctx = &p_ctx->uctx;
32+
33+
/* uc_link is not used. */
34+
p_ctx->uctx.uc_link = NULL;
35+
p_ctx->uctx.uc_stack.ss_sp = (void *)(((char *)sp) - size);
36+
p_ctx->uctx.uc_stack.ss_size = size;
37+
p_ctx->f_uctx_thread = thread_func;
38+
39+
if (sizeof(void *) == 8) {
40+
int arg_upper = (int)(((uintptr_t)p_ctx) >> 32);
41+
int arg_lower = (int)(((uintptr_t)p_ctx) >> 0);
42+
makecontext(&p_ctx->uctx, (void (*)())ABTD_ucontext_wrapper, 2,
43+
arg_upper, arg_lower);
44+
} else if (sizeof(void *) == 4) {
45+
int arg = (int)((uintptr_t)p_ctx);
46+
makecontext(&p_ctx->uctx, (void (*)())ABTD_ucontext_wrapper, 1, arg);
47+
} else {
48+
ABTI_ASSERT(0);
49+
}
50+
}
51+
52+
static inline
53+
void ABTD_thread_context_jump(ABTD_thread_context *p_old,
54+
ABTD_thread_context *p_new, void *arg)
55+
{
56+
p_new->p_uctx_arg = arg;
57+
swapcontext(&p_old->uctx, &p_new->uctx);
58+
}
59+
60+
static inline
61+
void ABTD_thread_context_take(ABTD_thread_context *p_old,
62+
ABTD_thread_context *p_new, void *arg)
63+
{
64+
p_new->p_uctx_arg = arg;
65+
setcontext(&p_new->uctx);
66+
/* Unreachable. */
67+
}
68+
69+
#if ABT_CONFIG_THREAD_TYPE == ABT_THREAD_TYPE_DYNAMIC_PROMOTION
70+
#error "ABTD_thread_context_make_and_call is not implemented."
71+
#endif
72+
73+
#endif /* ABTD_UCONTEXT_H_INCLUDED */

0 commit comments

Comments
 (0)