Changeset 3250664 in rtems


Ignore:
Timestamp:
07/15/14 17:37:36 (9 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, 5, master
Children:
0ea6d07
Parents:
ed7a028
git-author:
Joel Sherrill <joel.sherrill@…> (07/15/14 17:37:36)
git-committer:
Joel Sherrill <joel.sherrill@…> (07/15/14 18:42:30)
Message:

Thread Queue: Merge discipline subroutines into main methods

There was a lot of duplication between the discipline subroutines.
With the transition to RBTrees for priority discipline, there were
only a few lines of source code manipulating the data structure
for FIFO and priority. Thus is made sense to fold these back
into the main methods.

As part of doing this all of the tests for discipline were changed
to be in the same order.

Location:
cpukit/score
Files:
1 added
8 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/Makefile.am

    red7a028 r3250664  
    299299## THREADQ_C_FILES
    300300libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \
    301     src/threadqdequeuefifo.c src/threadqdequeuepriority.c \
    302     src/threadqenqueue.c src/threadqenqueuefifo.c \
    303     src/threadqenqueuepriority.c src/threadqextract.c \
    304     src/threadqextractfifo.c src/threadqextractpriority.c \
    305     src/threadqextractwithproxy.c src/threadqfirst.c src/threadqfirstfifo.c \
    306     src/threadqfirstpriority.c src/threadqflush.c \
    307     src/threadqprocesstimeout.c src/threadqtimeout.c
     301    src/threadqenqueue.c src/threadqextract.c src/threadqrequeue.c \
     302    src/threadqextractwithproxy.c src/threadqfirst.c \
     303    src/threadqflush.c src/threadqprocesstimeout.c src/threadqtimeout.c
    308304
    309305## TIMESPEC_C_FILES
  • cpukit/score/include/rtems/score/threadq.h

    red7a028 r3250664  
    3434 *  @ingroup Score
    3535 *
    36  *  This handler defines the data shared between the thread and thread
    37  *  queue handlers.  Having this handler define these data structure
    38  *  avoids potentially circular references.
     36 *  This handler provides the capability to have threads block in
     37 *  ordered sets. The sets may be ordered using the FIFO or priority
     38 *  discipline.
    3939 */
    4040/**@{*/
  • cpukit/score/include/rtems/score/threadqimpl.h

    red7a028 r3250664  
    6161 *  the discipline of the_thread_queue.  If no threads are waiting
    6262 *  on the_thread_queue, then NULL is returned.
     63 *
     64 *  - INTERRUPT LATENCY:
     65 *    + single case
    6366 */
    6467Thread_Control *_Thread_queue_Dequeue(
     
    124127 *      is to be removed
    125128 *  @param[in] return_code specifies the status to be returned.
     129 *
     130 *  - INTERRUPT LATENCY:
     131 *    + single case
    126132 */
    127133void _Thread_queue_Extract_with_return_code(
     
    214220
    215221/**
    216  *  @brief Enqueues the currently executing thread on the_thread_queue.
    217  *
    218  *  This routine enqueues the currently executing thread on
    219  *  the_thread_queue with an optional timeout using the
    220  *  priority discipline.
    221  *
    222  *  @param[in] the_thread_queue is the pointer to threadq
    223  *  @param[in] the_thread is the thread to insert
    224  *  @param[in] level_p is a pointer to an interrupt level to be returned
    225  *
    226  *  @retval This methods returns an indication of the blocking state as
    227  *          well as filling in *@ level_p with the previous interrupt level.
    228  *
    229  *  - INTERRUPT LATENCY:
    230  *    + single case
    231  */
    232 Thread_blocking_operation_States _Thread_queue_Enqueue_priority (
    233   Thread_queue_Control *the_thread_queue,
    234   Thread_Control       *the_thread,
    235   ISR_Level            *level_p
    236 );
    237 
    238 /**
    239  *  @brief Removes the_thread and cancels related timeouts.
    240  *
    241  *  This routine removes the_thread from the_thread_queue
    242  *  and cancels any timeouts associated with this blocking.
    243  *  @param[in] the_thread_queue pointer to a threadq header
    244  *  @param[in] the_thread pointer to a thread control block
    245  *  @param[in] requeuing true if requeuing and should not alter
    246  *         timeout or state
    247  *
    248  *  - INTERRUPT LATENCY:
    249  *    + single case
    250  *
    251  *  @retval true The extract operation was performed by the executing context.
    252  *  @retval false Otherwise.
    253  */
    254 void _Thread_queue_Extract_priority_helper(
    255   Thread_Control       *the_thread,
    256   uint32_t              return_code,
    257   bool                  requeuing
    258 );
    259 
    260 /**
    261  *  @brief Wraps the underlying call and hides the requeuing argument.
    262  *
    263  * This macro wraps the underlying call and hides the requeuing argument.
    264  */
    265 #define _Thread_queue_Extract_priority( _the_thread, _return_code ) \
    266   _Thread_queue_Extract_priority_helper( _the_thread, _return_code, false )
    267 
    268 /**
    269  *  @brief Get highest priority thread on the_thread_queue.
    270  *
    271  *  This function returns a pointer to the "first" thread
    272  *  on @a the_thread_queue.  The "first" thread is the highest
    273  *  priority thread waiting on @a the_thread_queue.
    274  *
    275  *  @param[in] the_thread_queue is the pointer to the thread queue
    276  *  @retval first thread or NULL
    277  */
    278 Thread_Control *_Thread_queue_First_priority(
    279   Thread_queue_Control *the_thread_queue
    280 );
    281 
    282 /**
    283  *  @brief Gets a pointer to the thread which has been waiting the longest.
    284  *
    285  *  This function returns a pointer to the thread which has
    286  *  been waiting the longest on  the_thread_queue.  If no
    287  *  threads are waiting on the_thread_queue, then NULL is returned.
    288  *
    289  *  @param[in] the_thread_queue is the pointer to threadq
    290  *
    291  *  @retval thread dequeued or NULL
    292  *
    293  *  - INTERRUPT LATENCY:
    294  *    + check sync
    295  *    + FIFO
    296  */
    297 Thread_Control *_Thread_queue_Dequeue_fifo(
    298   Thread_queue_Control *the_thread_queue
    299 );
    300 
    301 /**
    302  *  @brief Enqueues the currently executing thread on the_thread_queue.
    303  *
    304  *  This routine enqueues the currently executing thread on
    305  *  the_thread_queue with an optional timeout using the
    306  *  FIFO discipline.
    307  *
    308  *    @param[in] the_thread_queue pointer to threadq
    309  *    @param[in] the_thread pointer to the thread to block
    310  *    @param[in] level_p interrupt level in case the operation blocks actually
    311  *
    312  *  - INTERRUPT LATENCY:
    313  *    + single case
    314  */
    315 Thread_blocking_operation_States _Thread_queue_Enqueue_fifo (
    316   Thread_queue_Control *the_thread_queue,
    317   Thread_Control       *the_thread,
    318   ISR_Level            *level_p
    319 );
    320 
    321 /**
    322  *  @brief Removes the_thread from the_thread_queue and cancels any timeouts.
    323  *
    324  *  This routine removes the_thread from the_thread_queue
    325  *  and cancels any timeouts associated with this blocking.
    326  */
    327 void _Thread_queue_Extract_fifo(
    328   Thread_Control       *the_thread,
    329   uint32_t              return_code
    330 );
    331 
    332 /**
    333  *  @brief Gets a pointer to the "first" thread on the_thread_queue.
    334  *
    335  *  This function returns a pointer to the "first" thread
    336  *  on the_thread_queue.  The first thread is the thread
    337  *  which has been waiting longest on the_thread_queue.
    338  *
    339  *  @param[in] the_thread_queue is the pointer to threadq
    340  *
    341  *  @retval first thread or NULL
    342  */
    343 Thread_Control *_Thread_queue_First_fifo(
    344   Thread_queue_Control *the_thread_queue
    345 );
    346 
    347 /**
    348222 *  @brief Thread queue timeout.
    349223 *
     
    356230 *  @param[in] id thread id
    357231 */
    358 void _Thread_queue_Timeout (
     232void _Thread_queue_Timeout(
    359233  Objects_Id  id,
    360234  void       *ignored
     
    390264  const RBTree_Node *left,
    391265  const RBTree_Node *right
     266);
     267
     268/**
     269 *  @brief Invoked when a thread changes priority and is blocked.
     270 *
     271 *  This routine is invoked when a thread changes priority and is
     272 *  blocked on a thread queue.  If the queue is priority ordered,
     273 *  the_thread is removed from the_thread_queue and reinserted using
     274 *  its new priority.  This method has no impact on the state of the_thread
     275 *  or of any timeouts associated with this blocking.
     276 *
     277 *  @param[in] the_thread_queue pointer to a threadq header
     278 *  @param[in] the_thread pointer to a thread control block
     279 */
     280void _Thread_queue_Requeue(
     281  Thread_queue_Control *the_thread_queue,
     282  Thread_Control       *the_thread
    392283);
    393284
  • cpukit/score/src/threadchangepriority.c

    red7a028 r3250664  
    88
    99/*
    10  *  COPYRIGHT (c) 1989-2011.
     10 *  COPYRIGHT (c) 1989-2014.
    1111 *  On-Line Applications Research Corporation (OAR).
    1212 *
     
    2323#include <rtems/score/schedulerimpl.h>
    2424#include <rtems/score/threadqimpl.h>
    25 
    26 /**
    27  *  @brief Invoked when a thread changes priority and is blocked.
    28  *
    29  *  This routine is invoked when a thread changes priority and is
    30  *  blocked on a thread queue.  If the queue is priority ordered,
    31  *  the_thread is removed from the_thread_queue and reinserted using
    32  *  its new priority.  This method has no impact on the state of the_thread
    33  *  or of any timeouts associated with this blocking.
    34  *
    35  *  @param[in] the_thread_queue pointer to a threadq header
    36  *  @param[in] the_thread pointer to a thread control block
    37  */
    38 static void _Thread_queue_Requeue(
    39   Thread_queue_Control *the_thread_queue,
    40   Thread_Control       *the_thread
    41 )
    42 {
    43   /*
    44    * Just in case the thread really wasn't blocked on a thread queue
    45    * when we get here.
    46    */
    47   if ( !the_thread_queue )
    48     return;
    49 
    50   /*
    51    * If queueing by FIFO, there is nothing to do. This only applies to
    52    * priority blocking discipline.
    53    */
    54   if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
    55     Thread_queue_Control *tq = the_thread_queue;
    56     ISR_Level             level;
    57     ISR_Level             level_ignored;
    58 
    59     _ISR_Disable( level );
    60     if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
    61       _Thread_queue_Enter_critical_section( tq );
    62       _Thread_queue_Extract_priority_helper(
    63         the_thread,
    64         the_thread->Wait.return_code,
    65         true
    66       );
    67       (void) _Thread_queue_Enqueue_priority( tq, the_thread, &level_ignored );
    68     }
    69     _ISR_Enable( level );
    70   }
    71 }
    7225
    7326void _Thread_Change_priority(
  • cpukit/score/src/threadqdequeue.c

    red7a028 r3250664  
    88
    99/*
    10  *  COPYRIGHT (c) 1989-2008.
     10 *  COPYRIGHT (c) 1989-2014.
    1111 *  On-Line Applications Research Corporation (OAR).
    1212 *
     
    2020#endif
    2121
     22#include <rtems/score/chainimpl.h>
     23#include <rtems/score/threadimpl.h>
    2224#include <rtems/score/threadqimpl.h>
    2325#include <rtems/score/isrlevel.h>
     26#include <rtems/score/rbtreeimpl.h>
     27#include <rtems/score/watchdogimpl.h>
    2428
    2529Thread_Control *_Thread_queue_Dequeue(
     
    2731)
    2832{
    29   Thread_Control *(*dequeue_p)( Thread_queue_Control * );
    3033  Thread_Control *the_thread;
    3134  ISR_Level       level;
    3235  Thread_blocking_operation_States  sync_state;
    3336
    34   if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
    35     dequeue_p = _Thread_queue_Dequeue_priority;
    36   else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
    37     dequeue_p = _Thread_queue_Dequeue_fifo;
     37  the_thread = NULL;
     38  _ISR_Disable( level );
    3839
    39   the_thread = (*dequeue_p)( the_thread_queue );
    40   _ISR_Disable( level );
    41     if ( !the_thread ) {
    42       sync_state = the_thread_queue->sync_state;
    43       if ( (sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) ||
    44            (sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ) {
    45         the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
    46         the_thread = _Thread_Executing;
    47       }
     40  /*
     41   * Invoke the discipline specific dequeue method.
     42   */
     43  if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
     44    if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) {
     45      the_thread = (Thread_Control *)
     46       _Chain_Get_first_unprotected( &the_thread_queue->Queues.Fifo );
    4847    }
    49   _ISR_Enable( level );
     48  } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
     49    RBTree_Node    *first;
     50
     51    first = _RBTree_Get( &the_thread_queue->Queues.Priority, RBT_LEFT );
     52    if ( first ) {
     53      the_thread = _RBTree_Container_of( first, Thread_Control, RBNode );
     54    }
     55  }
     56
     57  /*
     58   * We did not find a thread to unblock.
     59   */
     60  if ( !the_thread ) {
     61    sync_state = the_thread_queue->sync_state;
     62    if ( (sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) ||
     63         (sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) ) {
     64      the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
     65      the_thread = _Thread_Executing;
     66    }
     67    _ISR_Enable( level );
     68    return NULL;
     69  }
     70
     71  /*
     72   * We found a thread to unblock.
     73   */
     74  the_thread->Wait.queue = NULL;
     75  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
     76    _ISR_Enable( level );
     77  } else {
     78    _Watchdog_Deactivate( &the_thread->Timer );
     79    _ISR_Enable( level );
     80    (void) _Watchdog_Remove( &the_thread->Timer );
     81  }
     82
     83  _Thread_Unblock( the_thread );
     84
     85#if defined(RTEMS_MULTIPROCESSING)
     86  if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     87    _Thread_MP_Free_proxy( the_thread );
     88#endif
     89
    5090  return the_thread;
    5191}
  • cpukit/score/src/threadqenqueue.c

    red7a028 r3250664  
    3333  ISR_Level                         level;
    3434  Thread_blocking_operation_States  sync_state;
    35   Thread_blocking_operation_States (*enqueue_p)(
    36     Thread_queue_Control *,
    37     Thread_Control *,
    38     ISR_Level *
    39   );
    4035
    4136#if defined(RTEMS_MULTIPROCESSING)
     
    6459
    6560  /*
    66    *  Now enqueue the thread per the discipline for this thread queue.
     61   * Now initiate the enqueuing and checking if the blocking operation
     62   * should be completed or the thread has had its blocking condition
     63   * satisfied before we got here.
    6764   */
    68   if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
    69     enqueue_p = _Thread_queue_Enqueue_priority;
    70   else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
    71     enqueue_p = _Thread_queue_Enqueue_fifo;
     65  _ISR_Disable( level );
    7266
    73   sync_state = (*enqueue_p)( the_thread_queue, the_thread, &level );
    74   if ( sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
     67  sync_state = the_thread_queue->sync_state;
     68  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
     69
     70  if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
     71    /*
     72     * Invoke the discipline specific enqueue method.
     73     */
     74    if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
     75      _Chain_Append_unprotected(
     76        &the_thread_queue->Queues.Fifo,
     77        &the_thread->Object.Node
     78      );
     79    } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
     80      _RBTree_Insert(
     81        &the_thread_queue->Queues.Priority,
     82        &the_thread->RBNode,
     83        _Thread_queue_Compare_priority,
     84        false
     85      );
     86    }
     87
     88    the_thread->Wait.queue = the_thread_queue;
     89    the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
     90    _ISR_Enable( level );
     91    return;
     92  } else { /* sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) */
    7593    _Thread_blocking_operation_Cancel( sync_state, the_thread, level );
     94  }
    7695}
  • cpukit/score/src/threadqextract.c

    red7a028 r3250664  
    88
    99/*
    10  *  COPYRIGHT (c) 1989-2008.
     10 *  COPYRIGHT (c) 1989-2014.
    1111 *  On-Line Applications Research Corporation (OAR).
    1212 *
     
    2020#endif
    2121
     22#include <rtems/score/chainimpl.h>
     23#include <rtems/score/threadimpl.h>
    2224#include <rtems/score/threadqimpl.h>
     25#include <rtems/score/watchdogimpl.h>
    2326
    2427void _Thread_queue_Extract_with_return_code(
     
    2831)
    2932{
    30   /*
    31    * Can not use indirect function pointer here since Extract priority
    32    * is a macro and the underlying methods do not have the same signature.
    33    */
    34   if  ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
    35     return _Thread_queue_Extract_priority( the_thread, return_code );
    36   else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
    37     return _Thread_queue_Extract_fifo( the_thread, return_code );
     33  ISR_Level level;
     34
     35  _ISR_Disable( level );
     36
     37  if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
     38    _ISR_Enable( level );
     39    return;
     40  }
     41
     42  if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
     43    _Chain_Extract_unprotected( &the_thread->Object.Node );
     44  } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
     45    _RBTree_Extract(
     46      &the_thread->Wait.queue->Queues.Priority,
     47      &the_thread->RBNode
     48    );
     49  }
     50
     51  the_thread->Wait.queue = NULL;
     52  the_thread->Wait.return_code = return_code;
     53
     54  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
     55    _ISR_Enable( level );
     56  } else {
     57    _Watchdog_Deactivate( &the_thread->Timer );
     58    _ISR_Enable( level );
     59    (void) _Watchdog_Remove( &the_thread->Timer );
     60  }
     61
     62  _Thread_Unblock( the_thread );
     63
     64#if defined(RTEMS_MULTIPROCESSING)
     65  if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     66    _Thread_MP_Free_proxy( the_thread );
     67#endif
    3868
    3969}
  • cpukit/score/src/threadqfirst.c

    red7a028 r3250664  
    77
    88/*
    9  *  COPYRIGHT (c) 1989-2008.
     9 *  COPYRIGHT (c) 1989-2014.
    1010 *  On-Line Applications Research Corporation (OAR).
    1111 *
     
    1919#endif
    2020
     21#include <rtems/score/chainimpl.h>
     22#include <rtems/score/isrlevel.h>
    2123#include <rtems/score/threadqimpl.h>
    2224
     
    2527)
    2628{
    27   Thread_Control * (*first_p)(Thread_queue_Control *);
     29  ISR_Level       level;
     30  Thread_Control *thread;
    2831
    29   if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY )
    30       first_p = _Thread_queue_First_priority;
    31   else /* must be THREAD_QUEUE_DISCIPLINE_FIFO */
    32       first_p = _Thread_queue_First_fifo;
     32  thread = NULL;
    3333
    34   return (*first_p)( the_thread_queue );
     34  _ISR_Disable( level );
     35
     36  if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
     37    if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) )
     38      thread = (Thread_Control *) _Chain_First(&the_thread_queue->Queues.Fifo);
     39  } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
     40    RBTree_Node *first;
     41
     42    first = _RBTree_First( &the_thread_queue->Queues.Priority, RBT_LEFT );
     43    if ( first )
     44      thread = _RBTree_Container_of( first, Thread_Control, RBNode );
     45  }
     46
     47  _ISR_Enable( level );
     48
     49  return thread;
    3550}
Note: See TracChangeset for help on using the changeset viewer.