basically every time we try to acquire mutex there should be lock acquisition related executing thread.
Thanks, Saurabh Gadia On Thu, Jul 23, 2015 at 6:47 PM, Saurabh Gadia <ga...@usc.edu> wrote: > hi, > > > Scenario: > thread t1: current_priority = 5, mutex acquired = m1, m2 > thread t2: current_priority = 3, mutex_acquired = None > > flow: thread t1 tries to acquire mutex m3 and thread t2 tries to acquire > mutex m1 which is already acquired by thread t1 simultaneously on SMP. > > Action: > thred t1 finds that m3 ->holder==NULL, so following code snippet of > coremuteximpl.h executes on one processor: > > ///// > RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body( > CORE_mutex_Control *the_mutex, > Thread_Control *executing, > ISR_lock_Context *lock_context > ) > { > /* disabled when you get here */ > > executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL; > if ( !_CORE_mutex_Is_locked( the_mutex ) ) { > the_mutex->holder = executing; > the_mutex->nest_count = 1; > if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || > _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){ > > #ifdef __RTEMS_STRICT_ORDER_MUTEX__ > /* Doesn't this lead to data race. If the executing thread is holder os > some other mutex and its priority is promoted by other > thread > */ > _Chain_Prepend_unprotected( &executing->lock_mutex, > &the_mutex->queue.lock_queue ); > *the_mutex->queue.priority_before = executing->current_priority;* > #endif > > executing->resource_count++; > } > > if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { > _Thread_queue_Release( &the_mutex->Wait_queue, lock_context ); > return 0; > } > > > ////// > > And thread t2 tries to acquire m1 and following snippet of > threadchangepriority.c executes: > > /////// (the_thread is holder for mutex m1 and new_priority == priority > of thread t2 ==3) > lock = _Thread_Lock_acquire( the_thread, &lock_context ); > > /* > * For simplicity set the priority restore hint unconditionally since > this is > * an average case optimization. Otherwise complicated atomic operations > * would be necessary. Synchronize with a potential read of the resource > * count in the filter function. See also _CORE_mutex_Surrender(), > * _Thread_Set_priority_filter() and _Thread_Restore_priority_filter(). > */ > the_thread->priority_restore_hint = true; > _Atomic_Fence( ATOMIC_ORDER_ACQ_REL ); > > /* > * Do not bother recomputing all the priority related information if > * we are not REALLY changing priority. > */ > if ( ( *filter )( the_thread, &new_priority, arg ) ) { > uint32_t my_generation; > > my_generation = the_thread->priority_generation + 1; > * the_thread->current_priority = new_priority;* > the_thread->priority_generation = my_generation; > > ( *the_thread->Wait.operations->priority_change )( > the_thread, > new_priority, > the_thread->Wait.queue > ); > //// > > So can interleaving of highlighted code result in data race? From my > perspective and from JPF model experience this is a data race and we need > to have locking on executing thread and holder thread if it exists for > mutex while acquiring any mutex. > So for 2nd case when there is already holder we do acquire holder lock by > calling *lock = _Thread_Lock_acquire( the_thread, &lock_context ); *in > 2nd snippet but we should do the same on executing thread when holder==NULL > in 1st code snippet. > Am I right? or is there something I am missing? > > Thanks, > > Saurabh Gadia >
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel