Using PTHREAD_PRIO_INHERIT causes panic in kern_umtx.c
Justin Teller
justin.teller at gmail.com
Mon Mar 9 13:55:51 PDT 2009
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;
}
More information about the freebsd-current
mailing list