From owner-freebsd-threads@FreeBSD.ORG Wed Oct 27 02:00:19 2010 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DA3B3106566C for ; Wed, 27 Oct 2010 02:00:19 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id C7F428FC19 for ; Wed, 27 Oct 2010 02:00:19 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o9R20Jcb043987 for ; Wed, 27 Oct 2010 02:00:19 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o9R20JaV043974; Wed, 27 Oct 2010 02:00:19 GMT (envelope-from gnats) Date: Wed, 27 Oct 2010 02:00:19 GMT Message-Id: <201010270200.o9R20JaV043974@freefall.freebsd.org> To: freebsd-threads@FreeBSD.org From: David Xu Cc: Subject: Re: threads/151767: pthread_mutex_init returns success with bad attributes; SUBSEQUENT operations fail X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: David Xu List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Oct 2010 02:00:19 -0000 The following reply was made to PR threads/151767; it has been noted by GNATS. From: David Xu To: Mark Terribile Cc: freebsd-gnats-submit@freebsd.org Subject: Re: threads/151767: pthread_mutex_init returns success with bad attributes; SUBSEQUENT operations fail Date: Wed, 27 Oct 2010 09:54:55 +0000 Mark Terribile wrote: >> Number: 151767 >> Category: threads >> Synopsis: pthread_mutex_init returns success with bad attributes; SUBSEQUENT operations fail >> Confidential: no >> Severity: non-critical >> Priority: medium >> Responsible: freebsd-threads >> State: open >> Quarter: >> Keywords: >> Date-Required: >> Class: sw-bug >> Submitter-Id: current-users >> Arrival-Date: Tue Oct 26 23:20:06 UTC 2010 >> Closed-Date: >> Last-Modified: >> Originator: Mark Terribile >> Release: 7.2 >> Organization: >> Environment: > FreeBSD gold.local 7.2-RELEASE FreeBSD 7.2-RELEASE #3: Mon Nov 16 12:48:52 EST 2009 toor@silver.local:/usr/obj/usr/src/sys/SMP-GONDOLIN i386 > >> Description: > 1) A pthread_mutexattr_t is initialized and then parameters are set. Some are unsupported or invalid, as shown below. All the operations return success. > > 2) The pthread_mutex_attr_t is used in the initialization of a pthread_mutex_t. The pthread_mutex_init returns success. > > 3) A subesequent operation (pthread_mutex_lock, pthread_mutex_destroy) on the mutex in question returns EINVAL. > > This delayed reporting makes finding an error very difficult, and is probably not correct. Can the pthread_mutex_init be said to succeed if the mutex cannot be used for anything without generating an EINVAL? > > I understand that 7.2 is not a supported release, but this problem does not seem to appear in the bug reports so it is likely also present in later releases. An upgrade at this site right now is not feasible; I need a very stable environment underneath me. > > >> How-To-Repeat: > Please refer to the code below. All operations up to the #if return 0. If the lock/unlock code is #if'd out, the pthread_mutex_destroy returns 22. If the lock/unlock code is #if'd in, the pthread_mutex_lock returns 22, the pthread_mutex_unlock returns 2 (probably correct, given the other errors) and the pthread_mutex_destroy still returns 22. > > > #include > #include > > int main() > { > pthread_mutexattr_t ma; > > int r = pthread_mutexattr_init( &ma ); > > printf( "mutexattr init %d\n", r ); > > r = pthread_mutexattr_setprotocol( &ma, PTHREAD_PRIO_PROTECT ); > > printf( "mutexattr setprotocol %d\n", r ); > > r = pthread_mutexattr_settype( &ma, PTHREAD_MUTEX_ERRORCHECK ); > > printf( "mutexattr settype %d\n", r ); > > r = pthread_mutexattr_setprioceiling( &ma, 2 ); > > printf( "mutexattr setprioceiling %d\n", r ); > > pthread_mutex_t mtx; > > r = pthread_mutex_init( &mtx, &ma ); > > printf( "mutex init %d\n", r ); > > #if 0 > r = pthread_mutex_lock( &mtx ); > > printf( "mutex lock %d\n", r ); > > r = pthread_mutex_unlock( &mtx ); > > printf( "mutex unlock %d\n", r ); > #endif > > r = pthread_mutex_destroy( &mtx ); > > printf( "mutex destroy %d\n", r ); > > return 0; > } > >> Fix: > > >> Release-Note: >> Audit-Trail: >> Unformatted: Long time ago, I had reported the priority issue in ULE scheduler, the scheduler incorrectly changed a time-sharing thread to real-time priority when it returns to userland if it thinks it is interactive. so you can not use prority protected mutex with ULE scheduler. see sched_ule.c: > /* > * If the score is interactive we place the thread in the realtime > * queue with a priority that is less than kernel and interrupt > * priorities. These threads are not subject to nice restrictions. > * > * Scores greater than this are placed on the normal timeshare queue > * where the priority is partially decided by the most recent cpu > * utilization and the rest is decided by nice value. > * > * The nice value of the process has a linear effect on the calculated > * score. Negative nice values make it easier for a thread to be > * considered interactive. > */ > score = imax(0, sched_interact_score(td) + td->td_proc->p_nice); > if (score < sched_interact) { > pri = PRI_MIN_REALTIME; > pri += ((PRI_MAX_REALTIME - PRI_MIN_REALTIME) / sched_interact) > * score; > KASSERT(pri >= PRI_MIN_REALTIME && pri <= PRI_MAX_REALTIME, > ("sched_priority: invalid interactive priority %d score %d", > pri, score)); > } else { > pri = SCHED_PRI_MIN; > if (td->td_sched->ts_ticks) > pri += SCHED_PRI_TICKS(td->td_sched); > pri += SCHED_PRI_NICE(td->td_proc->p_nice); > KASSERT(pri >= PRI_MIN_TIMESHARE && pri <= PRI_MAX_TIMESHARE, > ("sched_priority: invalid priority %d: nice %d, " > "ticks %d ftick %d ltick %d tick pri %d", > pri, td->td_proc->p_nice, td->td_sched->ts_ticks, > td->td_sched->ts_ftick, td->td_sched->ts_ltick, > SCHED_PRI_TICKS(td->td_sched))); > } > sched_user_prio(td, pri); > > return; > } However, I may remove trylock in pthread_mutex_destroy, because it does not help anything if there is a programming bug in application.