This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Robust mutex problem on MIPS.


Earlier I wrote about a problem with robust mutexes. I'm running
glibc+ports 2.5, N32 ABI, SiByte 1480 quad core box.

I have a smaller test case which reproduces the problem. Condition
variables are not necessary, and neither is the process-shared
attribute.

I simply have two threads which do nothing but lock and unlock the same
robust-attributed mutex. Eventually, they deadlock. 

In the deadlock situation,  the futex has somehow taken on the value
0x80000000 (the FUTEX_WAITERS value). This is a strange value, since the
zero bits in the TID part of the bitfield show that nobody owns the
lock. When the FUTEX_WAITERS value is masked in, the thread ID bits are
expected to be nonzero. It wouldn't make sense to atomically swap the
lock from 0x0 to 0x80000000.  When a lock is released, it should just be
flipped to zero (and if the old-value indicates FUTEX_WAITERS, the futex
is also signaled).

And so, both threads wait on the futex.  If you wake them from the futex
wait (for instance by interrupting the program with gdb) and then resume
the program, they loop back, check the value of the futex and go back to
sleep on it.

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

void *task_a(void *arg)
{
    pthread_mutex_t *mutex = arg;
    int i;

    for (i = 0; i < 100000; i++) {
        pthread_mutex_lock(mutex);
        pthread_mutex_unlock(mutex);
        printf("a: %d\n", i);
    }

    return NULL;
}

void *task_b(void *arg)
{
    pthread_mutex_t *mutex = arg;
    int i;

    for (i = 0; i < 100000; i++) {
        pthread_mutex_lock(mutex);
        pthread_mutex_unlock(mutex);
        printf("b: %d\n", i);
    }

    return NULL;
}

int
main(int argc, char *argv[])
{
    pthread_mutexattr_t mutex_attr;
    static pthread_mutex_t mutex;
    pthread_t thr; 

    pthread_mutexattr_init(&mutex_attr);
    pthread_mutexattr_setrobust_np(&mutex_attr,
PTHREAD_MUTEX_ROBUST_NP);
    pthread_mutex_init(&mutex, &mutex_attr);

    if (pthread_create(&thr, NULL, task_a, &mutex) != 0) {
        fprintf(stderr, "pthread_create failed\n");
        return EXIT_FAILURE;
    }

    task_b(&mutex);
    pthread_exit(NULL);
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]