source: rtems/cpukit/score/src/threadqflush.c @ 8a8b95aa

5
Last change on this file since 8a8b95aa was 4c20da4b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/19 at 07:18:11

doxygen: Rename Score* groups in RTEMSScore*

Update #3706

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Queue Flush
5 * @ingroup RTEMSScoreThreadQ
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/score/threadimpl.h>
22#include <rtems/score/schedulerimpl.h>
23#include <rtems/score/status.h>
24
25Thread_Control *_Thread_queue_Flush_default_filter(
26  Thread_Control       *the_thread,
27  Thread_queue_Queue   *queue,
28  Thread_queue_Context *queue_context
29)
30{
31  (void) queue;
32  (void) queue_context;
33  return the_thread;
34}
35
36Thread_Control *_Thread_queue_Flush_status_object_was_deleted(
37  Thread_Control       *the_thread,
38  Thread_queue_Queue   *queue,
39  Thread_queue_Context *queue_context
40)
41{
42  the_thread->Wait.return_code = STATUS_OBJECT_WAS_DELETED;
43
44  (void) queue;
45  (void) queue_context;
46  return the_thread;
47}
48
49Thread_Control *_Thread_queue_Flush_status_unavailable(
50  Thread_Control       *the_thread,
51  Thread_queue_Queue   *queue,
52  Thread_queue_Context *queue_context
53)
54{
55  the_thread->Wait.return_code = STATUS_UNAVAILABLE;
56
57  (void) queue;
58  (void) queue_context;
59  return the_thread;
60}
61
62size_t _Thread_queue_Flush_critical(
63  Thread_queue_Queue            *queue,
64  const Thread_queue_Operations *operations,
65  Thread_queue_Flush_filter      filter,
66  Thread_queue_Context          *queue_context
67)
68{
69  size_t          flushed;
70  Chain_Control   unblock;
71  Thread_Control *owner;
72  Chain_Node     *node;
73  Chain_Node     *tail;
74
75  flushed = 0;
76  _Chain_Initialize_empty( &unblock );
77  owner = queue->owner;
78
79  while ( true ) {
80    Thread_queue_Heads *heads;
81    Thread_Control     *first;
82    bool                do_unblock;
83
84    heads = queue->heads;
85    if ( heads == NULL ) {
86      break;
87    }
88
89    first = ( *operations->first )( heads );
90    first = ( *filter )( first, queue, queue_context );
91    if ( first == NULL ) {
92      break;
93    }
94
95    /*
96     * We do not have enough space in the queue context to collect all priority
97     * updates, so clear it each time.  We unconditionally do the priority
98     * update for the owner later if it exists.
99     */
100    _Thread_queue_Context_clear_priority_updates( queue_context );
101
102    do_unblock = _Thread_queue_Extract_locked(
103      queue,
104      operations,
105      first,
106      queue_context
107    );
108    if ( do_unblock ) {
109      Scheduler_Node *scheduler_node;
110
111      scheduler_node = _Thread_Scheduler_get_home_node( first );
112      _Chain_Append_unprotected(
113        &unblock,
114        &scheduler_node->Wait.Priority.Node.Node.Chain
115      );
116    }
117
118    ++flushed;
119  }
120
121  node = _Chain_First( &unblock );
122  tail = _Chain_Tail( &unblock );
123
124  if ( node != tail ) {
125    Per_CPU_Control *cpu_self;
126
127    cpu_self = _Thread_queue_Dispatch_disable( queue_context );
128    _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
129
130    do {
131      Scheduler_Node *scheduler_node;
132      Thread_Control *the_thread;
133      Chain_Node     *next;
134
135      next = _Chain_Next( node );
136      scheduler_node = SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( node );
137      the_thread = _Scheduler_Node_get_owner( scheduler_node );
138      _Thread_Remove_timer_and_unblock( the_thread, queue );
139
140      node = next;
141    } while ( node != tail );
142
143    if ( owner != NULL ) {
144      ISR_lock_Context lock_context;
145
146      _Thread_State_acquire( owner, &lock_context );
147      _Scheduler_Update_priority( owner );
148      _Thread_State_release( owner, &lock_context );
149    }
150
151    _Thread_Dispatch_enable( cpu_self );
152  } else {
153    _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
154  }
155
156  return flushed;
157}
Note: See TracBrowser for help on using the repository browser.