source: rtems/cpukit/score/src/threadqflush.c @ 15b5678d

5
Last change on this file since 15b5678d was 15b5678d, checked in by Sebastian Huber <sebastian.huber@…>, on 08/01/16 at 09:03:16

score: Move thread wait node to scheduler node

Update #2556.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Queue Flush
5 * @ingroup ScoreThreadQ
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  Chain_Node    *node;
72  Chain_Node    *tail;
73
74  flushed = 0;
75  _Chain_Initialize_empty( &unblock );
76
77  while ( true ) {
78    Thread_queue_Heads *heads;
79    Thread_Control     *first;
80    bool                do_unblock;
81
82    heads = queue->heads;
83    if ( heads == NULL ) {
84      break;
85    }
86
87    first = ( *operations->first )( heads );
88    first = ( *filter )( first, queue, queue_context );
89    if ( first == NULL ) {
90      break;
91    }
92
93    do_unblock = _Thread_queue_Extract_locked(
94      queue,
95      operations,
96      first,
97      queue_context
98    );
99    if ( do_unblock ) {
100      Scheduler_Node *scheduler_node;
101
102      scheduler_node = _Scheduler_Thread_get_own_node( first );
103      _Chain_Append_unprotected( &unblock, &scheduler_node->Wait.Node.Chain );
104    }
105
106    ++flushed;
107  }
108
109  node = _Chain_First( &unblock );
110  tail = _Chain_Tail( &unblock );
111
112  if ( node != tail ) {
113    Per_CPU_Control *cpu_self;
114
115    cpu_self = _Thread_Dispatch_disable_critical(
116      &queue_context->Lock_context.Lock_context
117    );
118    _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
119
120    do {
121      Scheduler_Node *scheduler_node;
122      Thread_Control *the_thread;
123      Chain_Node     *next;
124
125      next = _Chain_Next( node );
126      scheduler_node = SCHEDULER_NODE_OF_WAIT_CHAIN_NODE( node );
127      the_thread = _Scheduler_Node_get_owner( scheduler_node );
128      _Thread_Remove_timer_and_unblock( the_thread, queue );
129
130      node = next;
131    } while ( node != tail );
132
133    _Thread_Dispatch_enable( cpu_self );
134  } else {
135    _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context );
136  }
137
138  return flushed;
139}
Note: See TracBrowser for help on using the repository browser.