Re: Using PTHREAD_PRIO_INHERIT causes panic in kern_umtx.c

From: Justin Teller <justin.teller_at_gmail.com>
Date: Mon, 9 Mar 2009 13:55:49 -0700
On Mon, Mar 9, 2009 at 12:02 PM, Justin Teller <justin.teller_at_gmail.com>wrote:

> When I compile and run the attached program, it panics my system, (FreeBSD
> CURRENT as of 2-20-09) with the following message:
>
> panic: Assertion pi != NULL failed at /usr/src/sys/kern/kern_umtx: 1464
>
> With the backtrace being:
> Tracing pid 1079 tid 100045 td 0xffffff00037c8000
> kdb_enter() at kdb_enter+0x40
> panic() at panic+0x1ec
> umtx_pi_adjust() at umtx_pi_adjust+0xfc8
> umtx_pi_adjust() at umtx_pi_adjust+0x19bd
> _umtx_unlock() at _umtx_unlock+0x2c41
> _umtx_op() at _umtx_op+0x22
> syscall() at syscall+0x1f4
> Xfast_syscall() at Xfast_syscall+0xaa
> --- syscall (454, FreeBSD ELF64, _umtx_op), rip = 0x4056ac, rsp =
> 0x7fffffbfef38, rbp = 0x80060b150 ---
>
> This problem only shows up when I use PTHREAD_PRIO_INHERIT -- if I change
> the line for pthread_mutexattr_setprotocol to PTHREAD_PRIO_NONE, then it
> works fine.  I've been trying to trace thru the code to figure out where
> uq_pi_blocked should be setup, but I'm not too familiar with the code so I
> haven't found where the problem originates.  How can I get
> PTHREAD_PRIO_INHERIT to work?  And even if the change is in user-space, it
> probably shouldn't be this easy to panic the kernel :-)
>
> -Justin
>
>
> PS I'm reasonably certain that the most recent checkins (between now and
> Feb 20th) wouldn't fix this, but if I'm wrong, just let me know!
>
>
>
>
It looks like the list stripped out the .cpp file ... here it is below.  To
compile, run c++ -lthr mutex_prio_example.cpp -o mutex_prio_example

mutex_prio_example:

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

#define NRUNS   1000000
#define NCONSUMERS   4

volatile int g_num_items;
pthread_mutex_t g_mutex;


void* producer_proc ( void* ) {
    for ( int i = 0; i < NRUNS * NCONSUMERS; ++i ) {
        pthread_mutex_lock( &g_mutex );
        ++g_num_items;
        pthread_mutex_unlock( &g_mutex );
    }
    return NULL;
}

void* consumer_proc ( void* ) {
    for ( int i = 0; i < NRUNS; ++i ) {
        pthread_mutex_lock( &g_mutex );
        --g_num_items;
        pthread_mutex_unlock( &g_mutex );
    }
    return NULL;
}

int main() {
    g_num_items = 0;

    pthread_mutexattr_t mattr;
    pthread_mutexattr_init( &mattr );
    pthread_mutexattr_setprotocol( &mattr, PTHREAD_PRIO_INHERIT );
    pthread_mutex_init( &g_mutex, &mattr );
    pthread_mutexattr_destroy( &mattr );

    const int num_workers = NCONSUMERS;
    pthread_t threads[num_workers];
    for ( int i = 0; i < num_workers; ++i )
        pthread_create( threads + i, NULL, consumer_proc, NULL);
    producer_proc(NULL);
    for ( int i = 0; i < num_workers; ++i )
        pthread_join( threads[i], NULL );

    printf("done\n");
    return 0;
}
Received on Mon Mar 09 2009 - 19:55:50 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:43 UTC