Changeset adbedd1 in rtems


Ignore:
Timestamp:
Apr 15, 2016, 7:18:26 PM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
f05eeb2
Parents:
48b04fc3
git-author:
Sebastian Huber <sebastian.huber@…> (04/15/16 19:18:26)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/21/16 05:29:39)
Message:

score: Introduce _Thread_queue_Flush_critical()

Replace _Thread_queue_Flush() with _Thread_queue_Flush_critical() and
add a filter function for customization of the thread queue flush
operation.

Update #2555.

Location:
cpukit
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • cpukit/rtems/src/semdelete.c

    r48b04fc3 radbedd1  
    9393        _CORE_mutex_Flush(
    9494          &the_semaphore->Core_control.mutex,
    95           CORE_MUTEX_WAS_DELETED,
     95          _CORE_mutex_Was_deleted,
    9696          _Semaphore_MP_Send_object_was_deleted,
    9797          id
  • cpukit/rtems/src/semflush.c

    r48b04fc3 radbedd1  
    5454        _CORE_mutex_Flush(
    5555          &the_semaphore->Core_control.mutex,
    56           CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT,
     56          _CORE_mutex_Unsatisfied_nowait,
    5757          _Semaphore_MP_Send_object_was_deleted,
    5858          id
  • cpukit/score/include/rtems/score/corebarrierimpl.h

    r48b04fc3 radbedd1  
    194194#endif
    195195
     196Thread_Control *_CORE_barrier_Was_deleted(
     197  Thread_Control     *the_thread,
     198  Thread_queue_Queue *queue,
     199  ISR_lock_Context   *lock_context
     200);
     201
    196202/* Must be a macro due to the multiprocessing dependent parameters */
    197203#define _CORE_barrier_Flush( \
     
    200206  mp_id \
    201207) \
    202   _Thread_queue_Flush( \
    203     &( the_barrier )->Wait_queue, \
    204     CORE_BARRIER_TQ_OPERATIONS, \
    205     CORE_BARRIER_WAS_DELETED, \
    206     mp_callout, \
    207     mp_id \
    208   )
     208  do { \
     209    ISR_lock_Context _core_barrier_flush_lock_context; \
     210    _Thread_queue_Acquire( \
     211      &( the_barrier )->Wait_queue, \
     212      &_core_barrier_flush_lock_context \
     213    ); \
     214    _Thread_queue_Flush_critical( \
     215      &( the_barrier )->Wait_queue.Queue, \
     216      CORE_BARRIER_TQ_OPERATIONS, \
     217      _CORE_barrier_Was_deleted, \
     218      mp_callout, \
     219      mp_id, \
     220      &_core_barrier_flush_lock_context \
     221    ); \
     222  } while ( 0 )
    209223
    210224/**
  • cpukit/score/include/rtems/score/coremuteximpl.h

    r48b04fc3 radbedd1  
    339339#endif
    340340
     341Thread_Control *_CORE_mutex_Was_deleted(
     342  Thread_Control     *the_thread,
     343  Thread_queue_Queue *queue,
     344  ISR_lock_Context   *lock_context
     345);
     346
     347Thread_Control *_CORE_mutex_Unsatisfied_nowait(
     348  Thread_Control     *the_thread,
     349  Thread_queue_Queue *queue,
     350  ISR_lock_Context   *lock_context
     351);
     352
    341353/* Must be a macro due to the multiprocessing dependent parameters */
    342354#define _CORE_mutex_Flush( \
    343355  the_mutex, \
    344   status, \
     356  filter, \
    345357  mp_callout, \
    346358  mp_id \
    347359) \
    348   _Thread_queue_Flush( \
    349     &( the_mutex )->Wait_queue, \
    350     ( the_mutex )->operations, \
    351     status, \
    352     mp_callout, \
    353     mp_id \
    354   )
     360  do { \
     361    ISR_lock_Context _core_mutex_flush_lock_context; \
     362    _Thread_queue_Acquire( \
     363      &( the_mutex )->Wait_queue, \
     364      &_core_mutex_flush_lock_context \
     365    ); \
     366    _Thread_queue_Flush_critical( \
     367      &( the_mutex )->Wait_queue.Queue, \
     368      ( the_mutex )->operations, \
     369      filter, \
     370      mp_callout, \
     371      mp_id, \
     372      &_core_mutex_flush_lock_context \
     373    ); \
     374  } while ( 0 )
    355375
    356376/**
  • cpukit/score/include/rtems/score/coresemimpl.h

    r48b04fc3 radbedd1  
    8787);
    8888
     89Thread_Control *_CORE_semaphore_Was_deleted(
     90  Thread_Control     *the_thread,
     91  Thread_queue_Queue *queue,
     92  ISR_lock_Context   *lock_context
     93);
     94
     95Thread_Control *_CORE_semaphore_Unsatisfied_nowait(
     96  Thread_Control     *the_thread,
     97  Thread_queue_Queue *queue,
     98  ISR_lock_Context   *lock_context
     99);
     100
    89101#define _CORE_semaphore_Destroy( \
    90102  the_semaphore, \
     
    93105) \
    94106  do { \
    95     _Thread_queue_Flush( \
     107    ISR_lock_Context _core_semaphore_destroy_lock_context; \
     108    _Thread_queue_Acquire( \
    96109      &( the_semaphore )->Wait_queue, \
     110      &_core_semaphore_destroy_lock_context \
     111    ); \
     112    _Thread_queue_Flush_critical( \
     113      &( the_semaphore )->Wait_queue.Queue, \
    97114      ( the_semaphore )->operations, \
    98       CORE_SEMAPHORE_WAS_DELETED, \
     115      _CORE_semaphore_Was_deleted, \
    99116      mp_callout, \
    100       mp_id \
     117      mp_id, \
     118      &_core_semaphore_destroy_lock_context \
    101119    ); \
    102120    _Thread_queue_Destroy( &( the_semaphore )->Wait_queue ); \
     
    193211  mp_id \
    194212) \
    195   _Thread_queue_Flush( \
    196     &( the_semaphore )->Wait_queue, \
    197     ( the_semaphore )->operations, \
    198     CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \
    199     mp_callout, \
    200     mp_id \
    201   )
     213  do { \
     214    ISR_lock_Context _core_semaphore_flush_lock_context; \
     215    _Thread_queue_Acquire( \
     216      &( the_semaphore )->Wait_queue, \
     217      &_core_semaphore_flush_lock_context \
     218    ); \
     219    _Thread_queue_Flush_critical( \
     220      &( the_semaphore )->Wait_queue.Queue, \
     221      ( the_semaphore )->operations, \
     222      _CORE_semaphore_Unsatisfied_nowait, \
     223      mp_callout, \
     224      mp_id, \
     225      &_core_semaphore_flush_lock_context \
     226    ); \
     227  } while ( 0 )
    202228
    203229/**
  • cpukit/score/include/rtems/score/threadqimpl.h

    r48b04fc3 radbedd1  
    591591);
    592592
    593 void _Thread_queue_Do_flush(
    594   Thread_queue_Control          *the_thread_queue,
     593/**
     594 * @brief Thread queue flush filter function.
     595 *
     596 * Called under protection of the thread queue lock by
     597 * _Thread_queue_Flush_critical() to optionally alter the thread wait
     598 * information and control the iteration.
     599 *
     600 * @param the_thread The thread to extract.  This is the first parameter to
     601 *   optimize for architectures that use the same register for the first
     602 *   parameter and the return value.
     603 * @param queue The actual thread queue.
     604 * @param lock_context The lock context of the lock acquire.  May be used to
     605 *   pass additional data to the filter function via an overlay structure.  The
     606 *   filter function should not release or acquire the thread queue lock.
     607 *
     608 * @retval the_thread Extract this thread.
     609 * @retval NULL Do not extract this thread and stop the thread queue flush
     610 *   operation.  Threads that are already extracted will complete the flush
     611 *   operation.
     612 */
     613typedef Thread_Control *( *Thread_queue_Flush_filter )(
     614  Thread_Control     *the_thread,
     615  Thread_queue_Queue *queue,
     616  ISR_lock_Context   *lock_context
     617);
     618
     619size_t _Thread_queue_Do_flush_critical(
     620  Thread_queue_Queue            *queue,
    595621  const Thread_queue_Operations *operations,
    596   uint32_t                       status
    597 #if defined(RTEMS_MULTIPROCESSING)
    598   ,
     622  Thread_queue_Flush_filter      filter,
     623#if defined(RTEMS_MULTIPROCESSING)
    599624  Thread_queue_MP_callout        mp_callout,
    600   Objects_Id                     mp_id
    601 #endif
    602 );
    603 
    604 /**
    605  * @brief Unblocks all threads blocked on the thread queue.
    606  *
    607  * The thread timers of the threads are cancelled.
    608  *
    609  * @param the_thread_queue The thread queue.
     625  Objects_Id                     mp_id,
     626#endif
     627  ISR_lock_Context              *lock_context
     628);
     629
     630/**
     631 * @brief Unblocks all threads enqueued on the thread queue.
     632 *
     633 * This function iteratively extracts the first enqueued thread of the thread
     634 * queue until the thread queue is empty or the filter function indicates a
     635 * stop.  The thread timers of the extracted threads are cancelled.  The
     636 * extracted threads are unblocked.
     637 *
     638 * @param queue The actual thread queue.
    610639 * @param operations The thread queue operations.
    611  * @param status The return status for the threads.
     640 * @param filter The filter functions is called for each thread to extract from
     641 *   the thread queue.  It may be used to alter the thread under protection of
     642 *   the thread queue lock, for example to set the thread wait return code.
     643 *   The return value of the filter function controls if the thread queue flush
     644 *   operation should stop or continue.
    612645 * @param mp_callout Callout to extract the proxy of a remote thread.  This
    613646 *   parameter is only used on multiprocessing configurations.
    614647 * @param mp_id Object identifier of the object containing the thread queue.
    615648 *   This parameter is only used on multiprocessing configurations.
    616  */
    617 #if defined(RTEMS_MULTIPROCESSING)
    618   #define _Thread_queue_Flush( \
    619     the_thread_queue, \
     649 *
     650 * @return The count of extracted threads.
     651 */
     652#if defined(RTEMS_MULTIPROCESSING)
     653  #define _Thread_queue_Flush_critical( \
     654    queue, \
    620655    operations, \
    621     status, \
    622     mp_callout, \
    623     mp_id \
    624   ) \
    625     _Thread_queue_Do_flush( \
    626       the_thread_queue, \
     656    filter, \
     657    mp_callout, \
     658    mp_id, \
     659    lock_context \
     660  ) \
     661    _Thread_queue_Do_flush_critical( \
     662      queue, \
    627663      operations, \
    628       status, \
     664      filter, \
    629665      mp_callout, \
    630       mp_id \
    631     )
    632 #else
    633   #define _Thread_queue_Flush( \
    634     the_thread_queue, \
     666      mp_id, \
     667      lock_context \
     668    )
     669#else
     670  #define _Thread_queue_Flush_critical( \
     671    queue, \
    635672    operations, \
    636     status, \
    637     mp_callout, \
    638     mp_id \
    639   ) \
    640     _Thread_queue_Do_flush( \
    641       the_thread_queue, \
     673    filter, \
     674    mp_callout, \
     675    mp_id, \
     676    lock_context \
     677  ) \
     678    _Thread_queue_Do_flush_critical( \
     679      queue, \
    642680      operations, \
    643       status \
     681      filter, \
     682      lock_context \
    644683    )
    645684#endif
  • cpukit/score/src/corebarrier.c

    r48b04fc3 radbedd1  
    2020
    2121#include <rtems/score/corebarrierimpl.h>
    22 #include <rtems/score/threadqimpl.h>
    2322
    2423void _CORE_barrier_Initialize(
     
    3332  _Thread_queue_Initialize( &the_barrier->Wait_queue );
    3433}
     34
     35Thread_Control *_CORE_barrier_Was_deleted(
     36  Thread_Control     *the_thread,
     37  Thread_queue_Queue *queue,
     38  ISR_lock_Context   *lock_context
     39)
     40{
     41  the_thread->Wait.return_code = CORE_BARRIER_WAS_DELETED;
     42
     43  return the_thread;
     44}
  • cpukit/score/src/coremsgclose.c

    r48b04fc3 radbedd1  
    2222#include <rtems/score/wkspace.h>
    2323
     24static Thread_Control *_CORE_message_queue_Was_deleted(
     25  Thread_Control     *the_thread,
     26  Thread_queue_Queue *queue,
     27  ISR_lock_Context   *lock_context
     28)
     29{
     30  the_thread->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED;
     31
     32  return the_thread;
     33}
     34
    2435void _CORE_message_queue_Do_close(
    2536  CORE_message_queue_Control *the_message_queue
     
    3142)
    3243{
     44  ISR_lock_Context lock_context;
     45
    3346  /*
    3447   *  This will flush blocked threads whether they were blocked on
     
    3649   */
    3750
    38   _Thread_queue_Flush(
    39     &the_message_queue->Wait_queue,
     51  _CORE_message_queue_Acquire( the_message_queue, &lock_context );
     52  _Thread_queue_Flush_critical(
     53    &the_message_queue->Wait_queue.Queue,
    4054    the_message_queue->operations,
    41     CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED,
     55    _CORE_message_queue_Was_deleted,
    4256    mp_callout,
    43     mp_id
     57    mp_id,
     58    &lock_context
    4459  );
    4560
  • cpukit/score/src/coremsgflush.c

    r48b04fc3 radbedd1  
    4242   *  (1) The thread queue of pending senders is a logical extension
    4343   *  of the pending message queue.  In this case, it should be
    44    *  flushed using the _Thread_queue_Flush() service with a status
     44   *  flushed using the _Thread_queue_Flush_critical() service with a status
    4545   *  such as CORE_MESSAGE_QUEUE_SENDER_FLUSHED (which currently does
    4646   *  not exist).  This can be implemented without changing the "big-O"
  • cpukit/score/src/coremutex.c

    r48b04fc3 radbedd1  
    9797  return CORE_MUTEX_STATUS_SUCCESSFUL;
    9898}
     99
     100Thread_Control *_CORE_mutex_Was_deleted(
     101  Thread_Control     *the_thread,
     102  Thread_queue_Queue *queue,
     103  ISR_lock_Context   *lock_context
     104)
     105{
     106  the_thread->Wait.return_code = CORE_MUTEX_WAS_DELETED;
     107
     108  return the_thread;
     109}
     110
     111Thread_Control *_CORE_mutex_Unsatisfied_nowait(
     112  Thread_Control     *the_thread,
     113  Thread_queue_Queue *queue,
     114  ISR_lock_Context   *lock_context
     115)
     116{
     117  the_thread->Wait.return_code = CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
     118
     119  return the_thread;
     120}
  • cpukit/score/src/coresem.c

    r48b04fc3 radbedd1  
    3737  }
    3838}
     39
     40Thread_Control *_CORE_semaphore_Was_deleted(
     41  Thread_Control     *the_thread,
     42  Thread_queue_Queue *queue,
     43  ISR_lock_Context   *lock_context
     44)
     45{
     46  the_thread->Wait.return_code = CORE_SEMAPHORE_WAS_DELETED;
     47
     48  return the_thread;
     49}
     50
     51Thread_Control *_CORE_semaphore_Unsatisfied_nowait(
     52  Thread_Control     *the_thread,
     53  Thread_queue_Queue *queue,
     54  ISR_lock_Context   *lock_context
     55)
     56{
     57  the_thread->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
     58
     59  return the_thread;
     60}
  • cpukit/score/src/threadqflush.c

    r48b04fc3 radbedd1  
    1919#endif
    2020
    21 #include <rtems/score/threadqimpl.h>
    22 #include <rtems/score/objectimpl.h>
     21#include <rtems/score/threadimpl.h>
    2322
    24 void _Thread_queue_Do_flush(
    25   Thread_queue_Control          *the_thread_queue,
     23size_t _Thread_queue_Do_flush_critical(
     24  Thread_queue_Queue            *queue,
    2625  const Thread_queue_Operations *operations,
    27   uint32_t                       status
     26  Thread_queue_Flush_filter      filter,
    2827#if defined(RTEMS_MULTIPROCESSING)
    29   ,
    3028  Thread_queue_MP_callout        mp_callout,
    31   Objects_Id                     mp_id
     29  Objects_Id                     mp_id,
    3230#endif
     31  ISR_lock_Context              *lock_context
    3332)
    3433{
    35   ISR_lock_Context  lock_context;
    36   Thread_Control   *the_thread;
     34  size_t         flushed;
     35  Chain_Control  unblock;
     36  Chain_Node    *node;
     37  Chain_Node    *tail;
    3738
    38   _Thread_queue_Acquire( the_thread_queue, &lock_context );
     39  flushed = 0;
     40  _Chain_Initialize_empty( &unblock );
    3941
    40   while (
    41     (
    42       the_thread = _Thread_queue_First_locked(
    43         the_thread_queue,
    44         operations
    45       )
    46     )
    47   ) {
    48     the_thread->Wait.return_code = status;
     42  while ( true ) {
     43    Thread_queue_Heads *heads;
     44    Thread_Control     *first;
     45    bool                do_unblock;
    4946
    50     _Thread_queue_Extract_critical(
    51       &the_thread_queue->Queue,
     47    heads = queue->heads;
     48    if ( heads == NULL ) {
     49      break;
     50    }
     51
     52    first = ( *operations->first )( heads );
     53    first = ( *filter )( first, queue, lock_context );
     54    if ( first == NULL ) {
     55      break;
     56    }
     57
     58    do_unblock = _Thread_queue_Extract_locked(
     59      queue,
    5260      operations,
    53       the_thread,
     61      first,
    5462      mp_callout,
    55       mp_id,
    56       &lock_context
     63      mp_id
    5764    );
     65    if ( do_unblock ) {
     66      _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
     67    }
    5868
    59     _Thread_queue_Acquire( the_thread_queue, &lock_context );
     69    ++flushed;
    6070  }
    6171
    62   _Thread_queue_Release( the_thread_queue, &lock_context );
     72  node = _Chain_First( &unblock );
     73  tail = _Chain_Tail( &unblock );
     74
     75  if ( node != tail ) {
     76    Per_CPU_Control *cpu_self;
     77
     78    cpu_self = _Thread_Dispatch_disable_critical( lock_context );
     79    _Thread_queue_Queue_release( queue, lock_context );
     80
     81    do {
     82      Thread_Control *the_thread;
     83      Chain_Node     *next;
     84
     85      next = _Chain_Next( node );
     86      the_thread = THREAD_CHAIN_NODE_TO_THREAD( node );
     87      _Thread_Timer_remove( the_thread );
     88      _Thread_Unblock( the_thread );
     89
     90      node = next;
     91    } while ( node != tail );
     92
     93    _Thread_Dispatch_enable( cpu_self );
     94  } else {
     95    _Thread_queue_Queue_release( queue, lock_context );
     96  }
     97
     98  return flushed;
    6399}
Note: See TracChangeset for help on using the changeset viewer.