Hi,
I am experiencing dead-lock with the new futex based rwlock
implementation commited few days ago.
I showed the problem on both amd64 and i386.
I spotted it with the rust testsuite, as some tests are now hanging
whereas they were fine before.
As I am expecting to have more audience with C reproducer instead of
Rust reproducer, I ported to C a hanging test from lang/rust.
Just keep in mind I didn't go too deeply in Rust libstd to check all
aspects of underline code, but just enough to reproduce in C. If my C
code is wrong, Rust code could be right, and I will redo my porting
work.
The program is relatively simple.
It uses a rwlock (RWLock variable) to protect a char array.
The function `panic_set_hook()' replace the value inside the char array
(with wrlock/unlock), and the function `panic()' read the char array to
print it (rdlock/unlock).
The test function `c()' (a separate thread) will globally set the char array
(using `panic_set_hook()') and read it (using `panic()').
We are creating several threads calling `c()' simultaneously, and we do
it several times.
$ cat test.c
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOOP_MAIN 10
#define LOOP_THREAD 10
static pthread_rwlock_t RWLock = PTHREAD_RWLOCK_INITIALIZER;
static char msg[1024] = "default message";
void
panic_set_hook(char *new_msg)
{
if (pthread_rwlock_wrlock(&RWLock) != 0)
err(EXIT_FAILURE, "panic_set_hook: pthread_rwlock_wrlock");
strlcpy(msg, new_msg, 1024);
if (pthread_rwlock_unlock(&RWLock) != 0)
err(EXIT_FAILURE, "panic_set_hook: pthread_rwlock_unlock");
}
void
panic()
{
if (pthread_rwlock_rdlock(&RWLock) != 0)
err(EXIT_FAILURE, "panic: pthread_rwlock_rdlock");
printf("%s\n", msg);
if (pthread_rwlock_unlock(&RWLock) != 0)
err(EXIT_FAILURE, "panic: pthread_rwlock_unlock");
}
void *
c(void *_arg)
{
printf("c\n");
/* panic::set_hook() */
panic_set_hook("c handler");
/* panic!() */
panic();
return NULL;
}
int
main(int argc, char *argv[])
{
int i, j;
for (i=0; i < LOOP_MAIN; i++) {
pthread_t handlers[LOOP_THREAD];
printf("main: %d\n", i);
for (j=0; j < LOOP_THREAD; j++) {
if (pthread_create(&(handlers[j]), NULL,
&c, NULL) != 0)
err(EXIT_FAILURE, "main: pthread_create");
}
for (j=0; j < LOOP_THREAD; j++) {
if (pthread_join(handlers[j], NULL) != 0)
err(EXIT_FAILURE, "main: pthread_join");
}
}
return EXIT_SUCCESS;
}
$ cc -Wall -lpthread test.c
$ ./a.out
main: 0
c
c handler
c
c handler
c
c handler
c
c handler
c
c handler
c
c handler
c
c
c
c
c handler
c handler
[<--- HANG HERE]
If I am compiling libpthread with rthread_rwlock_compat.c instead
of rthread_rwlock.c (and no -DFUTEX), the program terminate without
hanging.
Thanks.
--
Sebastien Marie