Changeset 91e7b0c in rtems


Ignore:
Timestamp:
Mar 27, 2014, 8:04:47 AM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
25a97835
Parents:
8118b670
git-author:
Sebastian Huber <sebastian.huber@…> (03/27/14 08:04:47)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/01/14 12:10:22)
Message:

score: PR2172: _Thread_queue_Extract()

Add _Thread_queue_Extract_with_return_code(). On SMP this sequence in
_Thread_queue_Process_timeout() was broken:

[...]

/*

  • After we enable interrupts here, a lot may happen in the
  • meantime, e.g. nested interrupts may release the resource that
  • times out here. So we enter _Thread_queue_Extract()
  • speculatively. Inside this function we check the actual status
  • under ISR disable protection. This ensures that exactly one
  • executing context performs the extract operation (other parties
  • may call _Thread_queue_Dequeue()). If this context won, then
  • we have a timeout. *
  • We can use the_thread_queue pointer here even if
  • the_thread->Wait.queue is already set to NULL since the extract
  • operation will only use the thread queue discipline to select
  • the right extract operation. The timeout status is set during
  • thread queue initialization. */

we_did_it = _Thread_queue_Extract( the_thread_queue, the_thread );
if ( we_did_it ) {

the_thread->Wait.return_code = the_thread_queue->timeout_status;

}

[...]

In case _Thread_queue_Extract() successfully extracted a thread, then
this thread may start execution on a remote processor immediately and
read the the_thread->Wait.return_code before we update it here with the
timeout status. Thus it observes a successful operation even if it
timed out.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/include/rtems/score/threadqimpl.h

    r8118b670 r91e7b0c  
    136136 *  @param[in] the_thread_queue is the pointer to the ThreadQ header
    137137 *  @param[in] the_thread is the pointer to a thread control block that is to be removed
    138  *
    139  *  @retval true The extract operation was performed by the executing context.
    140  *  @retval false Otherwise.
    141  */
    142 bool _Thread_queue_Extract(
     138 */
     139void _Thread_queue_Extract(
    143140  Thread_queue_Control *the_thread_queue,
    144141  Thread_Control       *the_thread
     142);
     143
     144void _Thread_queue_Extract_with_return_code(
     145  Thread_queue_Control *the_thread_queue,
     146  Thread_Control       *the_thread,
     147  uint32_t              return_code
    145148);
    146149
     
    266269 *  @retval false Otherwise.
    267270 */
    268 bool _Thread_queue_Extract_priority_helper(
     271void _Thread_queue_Extract_priority_helper(
    269272  Thread_Control       *the_thread,
     273  uint32_t              return_code,
    270274  bool                  requeuing
    271275);
     
    277281 */
    278282
    279 #define _Thread_queue_Extract_priority( _the_thread ) \
    280   _Thread_queue_Extract_priority_helper( _the_thread, false )
     283#define _Thread_queue_Extract_priority( _the_thread, _return_code ) \
     284  _Thread_queue_Extract_priority_helper( _the_thread, _return_code, false )
    281285/**
    282286 *  @brief Get highest priority thread on the_thread_queue.
     
    338342 *  and cancels any timeouts associated with this blocking.
    339343 */
    340 bool _Thread_queue_Extract_fifo(
    341   Thread_Control       *the_thread
     344void _Thread_queue_Extract_fifo(
     345  Thread_Control       *the_thread,
     346  uint32_t              return_code
    342347);
    343348
  • cpukit/score/src/threadqextract.c

    r8118b670 r91e7b0c  
    2222#include <rtems/score/threadqimpl.h>
    2323
    24 bool _Thread_queue_Extract(
     24void _Thread_queue_Extract_with_return_code(
    2525  Thread_queue_Control *the_thread_queue,
    26   Thread_Control       *the_thread
     26  Thread_Control       *the_thread,
     27  uint32_t              return_code
    2728)
    2829{
     
    3233   */
    3334  if  ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
    34     return _Thread_queue_Extract_priority( the_thread );
     35    return _Thread_queue_Extract_priority( the_thread, return_code );
    3536  else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
    36     return _Thread_queue_Extract_fifo( the_thread );
     37    return _Thread_queue_Extract_fifo( the_thread, return_code );
    3738
    3839}
     40
     41void _Thread_queue_Extract(
     42  Thread_queue_Control *the_thread_queue,
     43  Thread_Control       *the_thread
     44)
     45{
     46  _Thread_queue_Extract_with_return_code(
     47    the_thread_queue,
     48    the_thread,
     49    the_thread->Wait.return_code
     50  );
     51}
  • cpukit/score/src/threadqextractfifo.c

    r8118b670 r91e7b0c  
    2626#include <rtems/score/watchdogimpl.h>
    2727
    28 bool _Thread_queue_Extract_fifo(
    29   Thread_Control       *the_thread
     28void _Thread_queue_Extract_fifo(
     29  Thread_Control       *the_thread,
     30  uint32_t              return_code
    3031)
    3132{
     
    3637  if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
    3738    _ISR_Enable( level );
    38     return false;
     39    return;
    3940  }
    4041
     
    4243
    4344  the_thread->Wait.queue = NULL;
     45  the_thread->Wait.return_code = return_code;
    4446
    4547  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
     
    5759    _Thread_MP_Free_proxy( the_thread );
    5860#endif
    59 
    60   return true;
    6161}
  • cpukit/score/src/threadqextractpriority.c

    r8118b670 r91e7b0c  
    2525#include <rtems/score/watchdogimpl.h>
    2626
    27 bool _Thread_queue_Extract_priority_helper(
     27void _Thread_queue_Extract_priority_helper(
    2828  Thread_Control       *the_thread,
     29  uint32_t              return_code,
    2930  bool                  requeuing
    3031)
     
    4546  if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
    4647    _ISR_Enable( level );
    47     return false;
     48    return;
    4849  }
    4950
     
    8788  if ( requeuing ) {
    8889    _ISR_Enable( level );
    89     return true;
     90    return;
    9091  }
     92
     93  the_thread->Wait.queue = NULL;
     94  the_thread->Wait.return_code = return_code;
    9195
    9296  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
     
    103107    _Thread_MP_Free_proxy( the_thread );
    104108#endif
    105 
    106   return true;
    107109}
  • cpukit/score/src/threadqprocesstimeout.c

    r8118b670 r91e7b0c  
    5252      _ISR_Enable( level );
    5353    } else {
    54       bool we_did_it;
    55 
    5654      _ISR_Enable( level );
    5755
     
    7169       * queue initialization.
    7270       */
    73       we_did_it = _Thread_queue_Extract( the_thread_queue, the_thread );
    74       if ( we_did_it ) {
    75         the_thread->Wait.return_code = the_thread_queue->timeout_status;
    76       }
     71      _Thread_queue_Extract_with_return_code(
     72        the_thread_queue,
     73        the_thread,
     74        the_thread_queue->timeout_status
     75      );
    7776    }
    7877  } else {
  • cpukit/score/src/threadqrequeue.c

    r8118b670 r91e7b0c  
    4646    if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
    4747      _Thread_queue_Enter_critical_section( tq );
    48       _Thread_queue_Extract_priority_helper( the_thread, true );
     48      _Thread_queue_Extract_priority_helper(
     49        the_thread,
     50        the_thread->Wait.return_code,
     51        true
     52      );
    4953      (void) _Thread_queue_Enqueue_priority( tq, the_thread, &level_ignored );
    5054    }
  • testsuites/sptests/spthreadq01/init.c

    r8118b670 r91e7b0c  
    3232{
    3333  Thread_queue_Control tq;
    34   bool we_did_it;
    3534
    3635  printf( "Init - initialize thread queue for %s\n", discipline_string );
     
    3938  puts( "Init - _Thread_queue_Extract - thread not blocked on a thread queue" );
    4039  _Thread_Disable_dispatch();
    41   we_did_it = _Thread_queue_Extract( &tq, _Thread_Executing );
     40  _Thread_queue_Extract( &tq, _Thread_Executing );
    4241  _Thread_Enable_dispatch();
    43   rtems_test_assert( !we_did_it );
    4442  /* is there more to check? */
    4543}
Note: See TracChangeset for help on using the changeset viewer.