Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Nov 2000 01:23:10 +0100
From:      Bradley T.Hughes <bhughes@trolltech.com>
To:        freebsd-stable@freebsd.org
Subject:   pthreads implementation on 4.2-RELEASE
Message-ID:  <00112501231000.63250@reticent.troll.no>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Recursive mutexes on 4.2-RELEASE are completely broken.  see the attached 
program (gcc -pthread -o blah blah.c)

-- 
--
Bradley T. Hughes <bhughes@trolltech.com>
Trolltech AS - Waldemar Thranes gt. 98B N-0175 Oslo, Norway
Office: +47 21604892
Mobile: +47 92019781

[-- Attachment #2 --]
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

pthread_cond_t cond;

void *thread1(void *arg) {
    pthread_mutex_t *mutex = (pthread_mutex_t *) arg;

    // lock/unlock once works fine
    printf("thread 1 locking mutex (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    
    // make sure thread1 is first
    pthread_cond_wait(&cond, mutex);
    pthread_cond_signal(&cond);
    
    printf("thread 1 unlocking mutex (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    sleep(1);
    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    sleep(1);

    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    sleep(1);

    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    sleep(1);

    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    sleep(1);

    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

     sleep(1);

    
    // lock 6 times and then unlock 6 times
    printf("thread 1 locking mutex 1 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 1 locking mutex 2 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 1 locking mutex 3 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 1 locking mutex 4 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 1 locking mutex 5 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 1 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));

    printf("thread 1 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 1 unlocking mutex 5 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 1 unlocking mutex 4 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 1 unlocking mutex 3 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 1 unlocking mutex 2 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    
    printf("!!! should still be locked, but the other thread will be able to run now\n");
    sleep(1);
    printf("thread 1 unlocking mutex 1 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("!!! notice the errors\n");
    
    return NULL;
}


void *thread2(void *arg) {
    pthread_mutex_t *mutex = (pthread_mutex_t *) arg;
    
    printf("thread 2 locking mutex (%s)\n",
           strerror(pthread_mutex_lock(mutex)));

    pthread_cond_signal(&cond);
    pthread_cond_wait(&cond, mutex);

    printf("thread 2 unlocking mutex (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    printf("thread 2 locking mutex 1 (%s)\n",
	   strerror(pthread_mutex_lock(mutex)));
    printf("thread 2 locking mutex 2 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 2 locking mutex 3 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 2 locking mutex 4 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 2 locking mutex 5 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));
    printf("thread 2 locking mutex 6 (%s)\n",
           strerror(pthread_mutex_lock(mutex)));

    printf("thread 2 unlocking mutex 6 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 2 unlocking mutex 5 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 2 unlocking mutex 4 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 2 unlocking mutex 3 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));
    printf("thread 2 unlocking mutex 2 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    // should be locked, but it is not
    printf("thread 2 unlocking mutex 1 (%s)\n",
           strerror(pthread_mutex_unlock(mutex)));

    return NULL;
}


int main() {
    pthread_t thr1, thr2;
    pthread_mutex_t mutex;
    void *junk;

    pthread_mutexattr_t mattr;
    pthread_mutexattr_init(&mattr);
    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&mutex, &mattr);

    pthread_cond_init(&cond, NULL);

    pthread_create( &thr1, NULL, thread1, (void *) &mutex );
    pthread_create( &thr2, NULL, thread2, (void *) &mutex );

    pthread_join(thr1, &junk);
    pthread_join(thr2, &junk);

    return 0;
}

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?00112501231000.63250>