threads/151767: pthread_mutex_init returns success with bad attributes; SUBSEQUENT operations fail

David Xu davidxu at freebsd.org
Wed Oct 27 02:00:19 UTC 2010


The following reply was made to PR threads/151767; it has been noted by GNATS.

From: David Xu <davidxu at freebsd.org>
To: Mark Terribile <materribile at yahoo.com>
Cc: freebsd-gnats-submit at 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 at 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 <stdio.h>
 > #include <pthread.h>
 > 
 > 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.
 


More information about the freebsd-threads mailing list