Changeset ab0da63e in rtems


Ignore:
Timestamp:
Aug 23, 2013, 10:19:13 AM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.10
Children:
7c709c05
Parents:
2077ae4c
git-author:
Sebastian Huber <sebastian.huber@…> (08/23/13 10:19:13)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/26/13 08:22:36)
Message:

score: PR2140: Fix _Thread_queue_Process_timeout()

The _Thread_queue_Process_timeout() operation had several race
conditions in the event of nested interrupts. Protect the critical
sections via disabled interrupts.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/src/threadqprocesstimeout.c

    r2077ae4c rab0da63e  
    3030)
    3131{
    32   Thread_queue_Control *the_thread_queue = the_thread->Wait.queue;
     32  Thread_queue_Control *the_thread_queue;
     33  ISR_Level             level;
    3334
    3435  /*
     
    4445   */
    4546
    46   if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SYNCHRONIZED &&
    47        _Thread_Is_executing( the_thread ) ) {
    48     if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SATISFIED ) {
    49       the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
    50       the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
     47  _ISR_Disable( level );
     48  the_thread_queue = the_thread->Wait.queue;
     49  if ( the_thread_queue != NULL ) {
     50    if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SYNCHRONIZED &&
     51         _Thread_Is_executing( the_thread ) ) {
     52      if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_SATISFIED ) {
     53        the_thread->Wait.return_code = the_thread_queue->timeout_status;
     54        the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
     55      }
     56      _ISR_Enable( level );
     57    } else {
     58      bool we_did_it;
     59
     60      _ISR_Enable( level );
     61
     62      /*
     63       * After we enable interrupts here, a lot may happen in the meantime,
     64       * e.g. nested interrupts may release the resource that times out here.
     65       * So we enter _Thread_queue_Extract() speculatively.  Inside this
     66       * function we check the actual status under ISR disable protection.
     67       * This ensures that exactly one executing context performs the extract
     68       * operation (other parties may call _Thread_queue_Dequeue()).  If this
     69       * context won, then we have a timeout.
     70       *
     71       * We can use the_thread_queue pointer here even if
     72       * the_thread->Wait.queue is already set to NULL since the extract
     73       * operation will only use the thread queue discipline to select the
     74       * right extract operation.  The timeout status is set during thread
     75       * queue initialization.
     76       */
     77      we_did_it = _Thread_queue_Extract( the_thread_queue, the_thread );
     78      if ( we_did_it ) {
     79        the_thread->Wait.return_code = the_thread_queue->timeout_status;
     80      }
    5181    }
    5282  } else {
    53     the_thread->Wait.return_code = the_thread->Wait.queue->timeout_status;
    54     _Thread_queue_Extract( the_thread->Wait.queue, the_thread );
     83    _ISR_Enable( level );
    5584  }
    5685}
Note: See TracChangeset for help on using the changeset viewer.