mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
[LibOS/regression] Multiple fixes for the futex test
- Loop on futex(WAKE) when no thread is awaken. - Use pthread instead of raw clone() because clone() does not initialize Glibc TCB, thus any function call to Glibc results in SIGBUS.
This commit is contained in:
committed by
Dmitrii Kuvaiskii
parent
5be9fbb689
commit
dafdb1d47b
@@ -23,6 +23,7 @@ CFLAGS-multi_pthread = -pthread
|
||||
CFLAGS-exit_group = -pthread
|
||||
CFLAGS-abort_multithread = -pthread
|
||||
CFLAGS-eventfd = -pthread
|
||||
CFLAGS-futex = -pthread
|
||||
CFLAGS-spinlock += -I$(PALDIR)/../lib -pthread
|
||||
|
||||
%: %.c
|
||||
|
||||
@@ -10,90 +10,73 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
// 64kB stack
|
||||
#define FIBER_STACK (1024 * 64)
|
||||
#define THREADS 2
|
||||
static int myfutex = 0;
|
||||
struct atomic_int {
|
||||
volatile int counter;
|
||||
};
|
||||
static struct atomic_int my_counter;
|
||||
|
||||
static inline void atomic_inc(struct atomic_int* v) {
|
||||
asm volatile("lock; incl %0" : "+m"(v->counter));
|
||||
}
|
||||
|
||||
static int futex(int* uaddr, int futex_op, int val, const struct timespec* timeout, int* uaddr2,
|
||||
int val3) {
|
||||
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr, val3);
|
||||
}
|
||||
|
||||
int thread_function(void* argument) {
|
||||
void* thread_function(void* argument) {
|
||||
int* ptr = (int*)argument;
|
||||
int rv;
|
||||
atomic_inc(&my_counter);
|
||||
|
||||
// Sleep on the futex
|
||||
rv = futex(&myfutex, FUTEX_WAIT_BITSET, 0, NULL, NULL, *ptr);
|
||||
assert(rv == 0);
|
||||
// printf("child thread %d awakened\n", getpid());
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
void* stacks[THREADS];
|
||||
pid_t pids[THREADS];
|
||||
int varx[THREADS];
|
||||
my_counter.counter = 0;
|
||||
pthread_t thread[THREADS];
|
||||
static int varx[THREADS];
|
||||
|
||||
for (int i = 0; i < THREADS; i++) {
|
||||
varx[i] = (1 << i);
|
||||
|
||||
// Allocate the stack
|
||||
stacks[i] = malloc(FIBER_STACK);
|
||||
if (stacks[i] == 0) {
|
||||
perror("malloc: could not allocate stack");
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
// Call the clone system call to create the child thread
|
||||
pids[i] = clone(&thread_function, (void*)stacks[i] + FIBER_STACK,
|
||||
CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM | CLONE_THREAD, &varx[i]);
|
||||
|
||||
// printf("clone() creates new thread %d\n", pids[i]);
|
||||
|
||||
if (pids[i] == -1) {
|
||||
perror("clone");
|
||||
int ret = pthread_create(&thread[i], NULL, &thread_function, &varx[i]);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
perror("pthread_create");
|
||||
_exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the threads are sleeping
|
||||
do {
|
||||
sleep(1);
|
||||
} while (my_counter.counter != THREADS);
|
||||
|
||||
printf("Waking up kiddos\n");
|
||||
/* Wake in reverse order */
|
||||
for (int i = THREADS - 1; i >= 0; i--) {
|
||||
pid_t pid;
|
||||
int rv;
|
||||
int var = (1 << i);
|
||||
|
||||
// Wake up the thread
|
||||
rv = futex(&myfutex, FUTEX_WAKE_BITSET, 1, NULL, NULL, var);
|
||||
do {
|
||||
rv = futex(&myfutex, FUTEX_WAKE_BITSET, 1, NULL, NULL, var);
|
||||
if (rv == 0) {
|
||||
// the thread of thread_function() may not reach
|
||||
// futex(FUTEX_WAIT_BITSET) yet.
|
||||
// Wait for the thread to sleep and try again.
|
||||
// Since synchronization primitive, futex, is being tested,
|
||||
// futex can't be used here. resort to use sleep.
|
||||
sleep(1);
|
||||
}
|
||||
} while (rv == 0);
|
||||
printf("FUTEX_WAKE_BITSET i = %d rv = %d\n", i, rv);
|
||||
assert(rv == 1);
|
||||
|
||||
// Wait for the child thread to exit
|
||||
pid = waitpid(pids[i], NULL, __WALL);
|
||||
if (pid == -1) {
|
||||
perror("waitpid");
|
||||
int ret = pthread_join(thread[i], NULL);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
perror("pthread_join");
|
||||
_exit(3);
|
||||
}
|
||||
|
||||
// Free the stack
|
||||
free(stacks[i]);
|
||||
}
|
||||
|
||||
printf("Woke all kiddos\n");
|
||||
|
||||
@@ -18,4 +18,5 @@ net.rules.2 = 0.0.0.0:0-65535:127.0.0.1:8000
|
||||
|
||||
sgx.trusted_files.ld = file:../../../../Runtime/ld-linux-x86-64.so.2
|
||||
sgx.trusted_files.libc = file:../../../../Runtime/libc.so.6
|
||||
sgx.trusted_files.libpthread = file:../../../../Runtime/libpthread.so.0
|
||||
sgx.thread_num = 4
|
||||
|
||||
Reference in New Issue
Block a user