File indexing completed on 2025-05-11 08:24:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifdef HAVE_CONFIG_H
0042 #include "config.h"
0043 #endif
0044
0045 #include <rtems/score/threadimpl.h>
0046 #include <rtems/score/schedulerimpl.h>
0047 #include <rtems/score/status.h>
0048
0049 Thread_Control *_Thread_queue_Flush_default_filter(
0050 Thread_Control *the_thread,
0051 Thread_queue_Queue *queue,
0052 Thread_queue_Context *queue_context
0053 )
0054 {
0055 (void) queue;
0056 (void) queue_context;
0057 return the_thread;
0058 }
0059
0060 Thread_Control *_Thread_queue_Flush_status_object_was_deleted(
0061 Thread_Control *the_thread,
0062 Thread_queue_Queue *queue,
0063 Thread_queue_Context *queue_context
0064 )
0065 {
0066 the_thread->Wait.return_code = STATUS_OBJECT_WAS_DELETED;
0067
0068 (void) queue;
0069 (void) queue_context;
0070 return the_thread;
0071 }
0072
0073 Thread_Control *_Thread_queue_Flush_status_unavailable(
0074 Thread_Control *the_thread,
0075 Thread_queue_Queue *queue,
0076 Thread_queue_Context *queue_context
0077 )
0078 {
0079 the_thread->Wait.return_code = STATUS_UNAVAILABLE;
0080
0081 (void) queue;
0082 (void) queue_context;
0083 return the_thread;
0084 }
0085
0086 size_t _Thread_queue_Flush_critical(
0087 Thread_queue_Queue *queue,
0088 const Thread_queue_Operations *operations,
0089 Thread_queue_Flush_filter filter,
0090 Thread_queue_Context *queue_context
0091 )
0092 {
0093 size_t flushed;
0094 size_t priority_updates;
0095 Chain_Control unblock;
0096 Chain_Node *node;
0097 Chain_Node *tail;
0098
0099 flushed = 0;
0100 priority_updates = 0;
0101 _Chain_Initialize_empty( &unblock );
0102
0103 while ( true ) {
0104 Thread_queue_Heads *heads;
0105 Thread_Control *first;
0106 bool do_unblock;
0107
0108 heads = queue->heads;
0109 if ( heads == NULL ) {
0110 break;
0111 }
0112
0113 first = ( *operations->first )( heads );
0114 first = ( *filter )( first, queue, queue_context );
0115 if ( first == NULL ) {
0116 break;
0117 }
0118
0119
0120
0121
0122
0123 _Thread_queue_Context_clear_priority_updates( queue_context );
0124
0125 do_unblock = _Thread_queue_Extract_locked(
0126 queue,
0127 operations,
0128 first,
0129 queue_context
0130 );
0131 if ( do_unblock ) {
0132 Scheduler_Node *scheduler_node;
0133
0134 scheduler_node = _Thread_Scheduler_get_home_node( first );
0135 _Chain_Append_unprotected(
0136 &unblock,
0137 &scheduler_node->Wait.Priority.Node.Node.Chain
0138 );
0139 }
0140
0141 priority_updates +=
0142 _Thread_queue_Context_get_priority_updates( queue_context );
0143 ++flushed;
0144 }
0145
0146 node = _Chain_First( &unblock );
0147 tail = _Chain_Tail( &unblock );
0148
0149 if ( node != tail ) {
0150 Per_CPU_Control *cpu_self;
0151
0152 cpu_self = _Thread_queue_Dispatch_disable( queue_context );
0153 _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
0154
0155 do {
0156 Scheduler_Node *scheduler_node;
0157 Thread_Control *the_thread;
0158 Chain_Node *next;
0159
0160 next = _Chain_Next( node );
0161 scheduler_node = SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( node );
0162 the_thread = _Scheduler_Node_get_owner( scheduler_node );
0163 _Thread_Remove_timer_and_unblock( the_thread, queue );
0164
0165 node = next;
0166 } while ( node != tail );
0167
0168 if ( priority_updates != 0 ) {
0169 Thread_Control *owner;
0170 ISR_lock_Context lock_context;
0171
0172 owner = queue->owner;
0173 _Assert( owner != NULL );
0174 _Thread_State_acquire( owner, &lock_context );
0175 _Scheduler_Update_priority( owner );
0176 _Thread_State_release( owner, &lock_context );
0177 }
0178
0179 _Thread_Dispatch_enable( cpu_self );
0180 } else {
0181 _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
0182 }
0183
0184 return flushed;
0185 }