lkml.org 
[lkml]   [2007]   [Oct]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC][PATCH] Fix hang in posix_locks_deadlock()
    On Wed, Oct 17, 2007 at 02:51:57PM -0400, George G. Davis wrote:
    > Not sure if this is the correct fix but it does resolve the hangs we're
    > observing in posix_locks_deadlock(). Comments greatly appreciated...

    Attached is a test case which exhibits the hang on an F7 host with all
    updates applied. Also occurs on linux-2.6.git latest.

    --
    Regards,
    George
    // gcc -o fcntltest -pthread posix_locks_deadlock-hang.c

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

    #define __USE_GNU 1
    #include <fcntl.h>
    #include <pthread.h>
    #include <sys/types.h>
    #include <unistd.h>

    #define NUM_THREADS 100
    #define NUM_PROCS 5
    #define NUM_FILES 64

    pthread_mutex_t locks[NUM_FILES];
    pthread_mutex_t gross_lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;

    static void *thread_routine(int number)
    {
    const char *fname = NULL;
    int f, rc;
    struct flock lock_it;
    pthread_mutex_t *lock = NULL;

    // get the gross lock
    pthread_mutex_lock(&gross_lock);

    lock_it.l_whence = SEEK_SET; /* from current point */
    lock_it.l_start = 0; /* -"- */
    lock_it.l_len = 0; /* until end of file */
    lock_it.l_type = F_WRLCK; /* set exclusive/write lock */
    lock_it.l_pid = 0; /* pid not actually interesting */

    fname = calloc(1, 500);

    snprintf(fname, 499, "%i.txt", number);
    lock = &locks[number];

    if (pthread_mutex_trylock(lock) != 0) {
    pthread_mutex_unlock(&gross_lock);
    pthread_mutex_lock(lock);
    pthread_mutex_unlock(&gross_lock);
    }

    int randm = (rand() % 32768) * 10;
    printf("Opening %s...\n", fname);
    f = open(fname, O_TRUNC | O_CREAT | O_WRONLY, 0644);
    if (f < 0) {
    perror(fname);
    exit(1);
    }
    printf("Locking %s...\n", fname);
    // release the gross lock before attempting the fcntl
    pthread_mutex_unlock(&gross_lock);
    rc = fcntl(f, F_SETLKW, &lock_it);
    sleep(5);
    // gain the gross lock again
    pthread_mutex_lock(&gross_lock);
    if (rc < 0) {
    perror(fname);
    usleep(randm);
    pthread_mutex_unlock(lock);
    pthread_mutex_unlock(&gross_lock);
    exit(1);
    }

    usleep(randm);
    // unlocks the file
    close(rc);
    pthread_mutex_unlock(lock);
    pthread_mutex_unlock(&gross_lock);
    return NULL;
    }

    int main(int argc, char **argv)
    {
    int i, rc;
    pthread_t tids[NUM_THREADS];
    memset(tids, 0, sizeof(tids));
    memset(locks, 0, sizeof(locks));

    for (i = 0; i < NUM_PROCS; i++) {
    pid_t mypid = fork();
    if (mypid == 0)
    break;
    }

    for (i = 0; i < NUM_THREADS; i++) {
    rc = pthread_create(&tids[i], NULL, thread_routine,
    (rand() % NUM_FILES));
    if (rc != 0) {
    tids[i] = 0;
    }
    }

    for (i = 0; i < 500; i++) {
    if (tids[i] != 0) {
    pthread_join(tids[i], NULL);
    }
    }

    return 0;
    }
    \
     
     \ /
      Last update: 2007-10-18 01:43    [W:0.022 / U:0.476 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site