と併用しucontext
ていpthread
ます。以下のプログラムは Linux では正常に動作しますが、Mac ではアサーションに失敗しました。
問題は、別のスレッドからコンテキストを再開した後、スレッド ローカル変数が正しくアクセスされていないようです。
プログラムは 2 つのスレッド A と B を作成します。適切に同期されているため、A は、B がコンテキストを再開する前にコンテキストを準備完了に設定します。
誰かが Mac でのこの動作に光を当てることができれば、非常にありがたいです。
環境:
clang version 3.7.0 (http://llvm.org/git/llvm.git 8d70064a4ac2ae09b8003173e751cfad9dc15400)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
プログラム:
#define _XOPEN_SOURCE 800
#include <ucontext.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
static int flag = 0;
void swap(ucontext_t *old, ucontext_t *new)
{
int ret = swapcontext(old, new);
assert(ret == 0);
}
#define SSIZE MINSIGSTKSZ
static char stack[SSIZE];
static ucontext_t a_ctx[2];
static ucontext_t b_ctx[2];
volatile static __thread int bug = 0;
static void func(int b) { }
static void f1 (void)
{
assert(bug == 0);
func(bug);
swap(&a_ctx[1], &a_ctx[0]);
assert(bug == 1);
}
void *thread_a(void *arg)
{
printf("A is %lu\n", pthread_self());
bug = 0;
ucontext_t ctx = a_ctx[1];
getcontext(&ctx);
ctx.uc_stack.ss_sp = stack;
ctx.uc_stack.ss_size = sizeof stack;
makecontext(&ctx, f1, 0);
swap(&a_ctx[0], &ctx);
__atomic_store_n(&flag, 1, __ATOMIC_RELAXED);
sleep(1);
return NULL;
}
void *thread_b(void *arg)
{
printf("B is %lu\n", pthread_self());
bug = 1;
while(__atomic_load_n(&flag, __ATOMIC_RELAXED) == 0) ;
swap(&b_ctx[0], &a_ctx[1]);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t a, b;
pthread_create(&b, NULL, &thread_b, NULL);
pthread_create(&a, NULL, &thread_a, NULL);
pthread_exit(NULL);
}