1
我收到一个奇怪的错误。我实现了这两个功能:搞砸了使用do_futex?
int flag_and_sleep(volatile unsigned int *flag)
{
int res = 0;
(*flag) = 1;
res = syscall(__NR_futex, flag, FUTEX_WAIT, 1, NULL, NULL, 0);
if(0 == res && (0 != (*flag)))
die("0 == res && (0 != (*flag))");
return 0;
}
int wake_up_if_any(volatile unsigned int *flag)
{
if(1 == (*flag))
{
(*flag) = 0;
return syscall(__NR_futex, flag, FUTEX_WAKE, 1, NULL, NULL, 0);
}
return 0;
}
,并测试他们通过运行两个POSIX线程:
static void die(const char *msg)
{
fprintf(stderr, "%s %u %lu %lu\n", msg, thread1_waits, thread1_count, thread2_count);
_exit(1);
}
volatile unsigned int thread1_waits = 0;
void* threadf1(void *p)
{
int res = 0;
while(1)
{
res = flag_and_sleep(&thread1_waits);
thread1_count++;
}
return NULL;
}
void* threadf2(void *p)
{
int res = 0;
while(1)
{
res = wake_up_if_any(&thread1_waits);
thread2_count++;
}
return NULL;
}
线程2已经有一百万左右的迭代之后,我得到了我的断言火:
./a.out 0 == RES & &(0!=(*标记))1 261129 1094433
这意味着系统调用 - 从而do_futex() - 返回0.人说,它应该只这样做,如果由do_futex(WAKE)调用唤醒。但是在我进行WAKE调用之前,我将该标志设置为0.在此看来,标志仍然是1.
这是Intel,意思是强大的内存模型。因此,如果在thread1中看到thread2中系统调用的结果,我还必须在调用之前看到线程2中写入的结果。
标记和指向它的所有指针都是不稳定的,所以我看不到gcc可能无法读取正确的值。
我很困惑。
谢谢!
这可能值得在LKML上提出。 – caf 2010-09-01 00:46:13