<div dir="ltr"><div>#if defined(RTEMS_SMP)<br>RTEMS_INLINE_ROUTINE void _Thread_Lock_restore_default(<br>  Thread_Control *the_thread<br>)<br>{<br>  _Atomic_Fence( ATOMIC_ORDER_RELEASE );<br><br>  _Thread_Lock_set_unprotected( the_thread, &the_thread->Lock.Default );<br>}<br><br></div>what does this atomic fence does when we set Lock.current=Default in threadimpl.h?<br></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div>
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 7:38 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Yes. I guess I was right about the data race problem we are facing in our model. It is also present in rtems:<br>    _Thread_queue_Extract_locked( &the_mutex->Wait_queue, the_thread ); line 188 in _CORE_mutex_Surrender() in coremutexsurrender.c where it sets holder.Lock->current = holder.Lock->Default. If you get time please have a look at it.<br></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div><div><div class="h5">
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 7:26 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Actually there might exists the same data race problem now in rtems. i.e when holder!=NULL we acquire holder.Lock->current in 2nd code snippet: lock = _Thread_Lock_acquire( the_thread, &lock_context );<br></div>but if mutex on which holder is waiting gets assigned to holder then current value of holder changes to default lock!! Lets check that.<br></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div><div><div>
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 7:21 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>So based on this structure:<br>typedef struct {<br>  /**<br>   * @brief The current thread lock.<br>   */<br>  ISR_lock_Control *current;<br><br>  /**<br>   * @brief The default thread lock in case the thread is not blocked on a<br>   * resource.<br>   */<br>  ISR_lock_Control Default;<br><br>  /**<br>   * @brief Generation number to invalidate stale locks.<br>   */<br>  Atomic_Uint generation;<br>} Thread_Lock_control;<br><br></div>present in TCB is same as having holder.trylock corresponding to <b>current </b>in above structure when holder is waiting. So need to check what rtems does to avoid data race for this <b>current member</b> when it becomes Default after holder gets access to waiting resource.<br></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div><div><div>
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 7:16 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">As per thread initialization in threadinitialize.c we should acquire default lock i.e the_thread->Lock.Default. Am I right?<br></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div><div><div>
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 6:58 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">basically every time we try to acquire mutex there should be lock acquisition related executing thread.<br></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div><div><div>
<br><div class="gmail_quote">On Thu, Jul 23, 2015 at 6:47 PM, Saurabh Gadia <span dir="ltr"><<a href="mailto:gadia@usc.edu" target="_blank">gadia@usc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>hi,<br><br><br></div><div>Scenario: <br></div><div>thread t1: current_priority = 5, mutex acquired = m1, m2<br></div><div>thread t2: current_priority = 3, mutex_acquired = None<br><br></div><div>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.<br></div><div><br>Action:<br></div><div>thred t1 finds that m3 ->holder==NULL, so following code snippet of coremuteximpl.h executes on one processor:<br><br>/////<br>RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(<br>  CORE_mutex_Control  *the_mutex,<br>  Thread_Control      *executing,<br>  ISR_lock_Context    *lock_context<br>)<br>{<br>  /* disabled when you get here */<br><br>  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;<br>  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {<br>    the_mutex->holder     = executing;<br>    the_mutex->nest_count = 1;<br>    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||<br>         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){<br><br>#ifdef __RTEMS_STRICT_ORDER_MUTEX__<br>/* Doesn't this lead to data race. If the executing thread is holder os some other mutex and its priority is promoted by other<br>thread<br>*/<br>       _Chain_Prepend_unprotected( &executing->lock_mutex,<br>                                   &the_mutex->queue.lock_queue );<br>       <b>the_mutex->queue.priority_before = executing->current_priority;</b><br>#endif<br><br>      executing->resource_count++;<br>    }<br><br>    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {<br>      _Thread_queue_Release( &the_mutex->Wait_queue, lock_context );<br>      return 0;<br>    }<br><br><br>//////<br><br></div><div>And thread t2 tries to acquire m1 and following snippet of threadchangepriority.c executes:<br></div><div><br>///////  (the_thread is holder for mutex m1 and new_priority == priority of thread t2 ==3)<br></div><div> lock = _Thread_Lock_acquire( the_thread, &lock_context );<br><br>  /*<br>   * For simplicity set the priority restore hint unconditionally since this is<br>   * an average case optimization.  Otherwise complicated atomic operations<br>   * would be necessary.  Synchronize with a potential read of the resource<br>   * count in the filter function.  See also _CORE_mutex_Surrender(),<br>   * _Thread_Set_priority_filter() and _Thread_Restore_priority_filter().<br>   */<br>  the_thread->priority_restore_hint = true;<br>  _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );<br><br>  /*<br>   *  Do not bother recomputing all the priority related information if<br>   *  we are not REALLY changing priority.<br>   */<br>  if ( ( *filter )( the_thread, &new_priority, arg ) ) {<br>    uint32_t my_generation;<br><br>    my_generation = the_thread->priority_generation + 1;<br>   <b> the_thread->current_priority = new_priority;</b><br>    the_thread->priority_generation = my_generation;<br><br>    ( *the_thread->Wait.operations->priority_change )(<br>      the_thread,<br>      new_priority,<br>      the_thread->Wait.queue<br>    );<br>////<br></div><div><br></div><div>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.<br></div><div>So for 2nd case when there is already holder we do acquire holder lock by calling <b>lock = _Thread_Lock_acquire( the_thread, &lock_context ); </b>in 2nd snippet but we should do the same on executing thread when holder==NULL in 1st code snippet.<br></div><div>Am I right? or is there something I am missing?<br></div><div><br><b></b></div><div><div><div><div><div dir="ltr">Thanks,<div><br></div><div>Saurabh Gadia</div></div></div></div>
</div></div></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div></div></div>
</blockquote></div><br></div>