source: rtems/cpukit/score/src/threadmp.c @ 24f8915

5
Last change on this file since 24f8915 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: 5.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Distributed MP Support
5 *  @ingroup RTEMSScoreThreadMP
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2006.
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/isrlock.h>
23#include <rtems/score/schedulerimpl.h>
24#include <rtems/score/wkspace.h>
25
26#include <string.h>
27
28static RBTREE_DEFINE_EMPTY( _Thread_MP_Active_proxies );
29
30static CHAIN_DEFINE_EMPTY( _Thread_MP_Inactive_proxies );
31
32ISR_LOCK_DEFINE( static, _Thread_MP_Proxies_lock, "Thread MP Proxies" )
33
34static void _Thread_MP_Proxies_acquire( ISR_lock_Context *lock_context )
35{
36  _ISR_lock_ISR_disable_and_acquire( &_Thread_MP_Proxies_lock, lock_context );
37}
38
39static void _Thread_MP_Proxies_release( ISR_lock_Context *lock_context )
40{
41  _ISR_lock_Release_and_ISR_enable( &_Thread_MP_Proxies_lock, lock_context );
42}
43
44void _Thread_MP_Handler_initialization (
45  uint32_t    maximum_proxies
46)
47{
48  size_t    proxy_size;
49  size_t    alloc_size;
50  char     *proxies;
51  uint32_t  i;
52
53  if ( maximum_proxies == 0 ) {
54    return;
55  }
56
57  proxy_size = sizeof( Thread_Proxy_control ) + _Thread_queue_Heads_size;
58  alloc_size = maximum_proxies * proxy_size;
59  proxies = _Workspace_Allocate_or_fatal_error( alloc_size );
60  memset( proxies, 0, alloc_size );
61
62  _Chain_Initialize(
63    &_Thread_MP_Inactive_proxies,
64    proxies,
65    maximum_proxies,
66    proxy_size
67  );
68
69  for ( i = 0 ; i < maximum_proxies ; ++i ) {
70    Thread_Proxy_control *proxy;
71
72    proxy = (Thread_Proxy_control *) ( proxies + i * proxy_size );
73
74    _Thread_Timer_initialize( &proxy->Timer, _Per_CPU_Get_by_index( 0 ) );
75    _RBTree_Initialize_node( &proxy->Active );
76
77    proxy->Scheduler.nodes = &proxy->Scheduler_node;
78    _Scheduler_Node_do_initialize(
79      &_Scheduler_Table[ 0 ],
80      &proxy->Scheduler_node,
81      (Thread_Control *) proxy,
82      0
83    );
84
85    proxy->Wait.spare_heads = &proxy->Thread_queue_heads[ 0 ];
86    _Thread_queue_Heads_initialize( proxy->Wait.spare_heads );
87  }
88}
89
90#define THREAD_MP_PROXY_OF_ACTIVE_NODE( the_node ) \
91  RTEMS_CONTAINER_OF( the_node, Thread_Proxy_control, Active )
92
93static bool _Thread_MP_Proxy_equal(
94  const void        *left,
95  const RBTree_Node *right
96)
97{
98  const Objects_Id           *the_left;
99  const Thread_Proxy_control *the_right;
100
101  the_left = left;
102  the_right = THREAD_MP_PROXY_OF_ACTIVE_NODE( right );
103
104  return *the_left == the_right->Object.id;
105}
106
107static bool _Thread_MP_Proxy_less(
108  const void        *left,
109  const RBTree_Node *right
110)
111{
112  const Objects_Id           *the_left;
113  const Thread_Proxy_control *the_right;
114
115  the_left = left;
116  the_right = THREAD_MP_PROXY_OF_ACTIVE_NODE( right );
117
118  return *the_left < the_right->Object.id;
119}
120
121static void *_Thread_MP_Proxy_map( RBTree_Node *node )
122{
123  return THREAD_MP_PROXY_OF_ACTIVE_NODE( node );
124}
125
126Thread_Control *_Thread_MP_Allocate_proxy (
127  States_Control  the_state
128)
129{
130  Thread_Proxy_control *the_proxy;
131  ISR_lock_Context      lock_context;
132
133  _Thread_MP_Proxies_acquire( &lock_context );
134
135  the_proxy = (Thread_Proxy_control *)
136    _Chain_Get_unprotected( &_Thread_MP_Inactive_proxies );
137  if ( the_proxy != NULL ) {
138    Thread_Control   *executing;
139    MP_packet_Prefix *receive_packet;
140    Objects_Id        source_tid;
141
142    executing = _Thread_Executing;
143    receive_packet = _MPCI_Receive_server_tcb->receive_packet;
144    source_tid = receive_packet->source_tid;
145
146    executing->Wait.return_code = THREAD_STATUS_PROXY_BLOCKING;
147
148    the_proxy->receive_packet = receive_packet;
149    the_proxy->Object.id = source_tid;
150    the_proxy->Real_priority.priority = receive_packet->source_priority;
151    the_proxy->current_state = _States_Set( STATES_DORMANT, the_state );
152
153    the_proxy->Wait.count                   = executing->Wait.count;
154    the_proxy->Wait.return_argument         = executing->Wait.return_argument;
155    the_proxy->Wait.return_argument_second  = executing->Wait.return_argument_second;
156    the_proxy->Wait.option                  = executing->Wait.option;
157    the_proxy->Wait.return_code             = executing->Wait.return_code;
158
159    the_proxy->thread_queue_callout = _Thread_queue_MP_callout_do_nothing;
160
161    _RBTree_Insert_inline(
162      &_Thread_MP_Active_proxies,
163      &the_proxy->Active,
164      &source_tid,
165      _Thread_MP_Proxy_less
166    );
167
168    _Thread_MP_Proxies_release( &lock_context );
169
170    return (Thread_Control *) the_proxy;
171  }
172
173  _Thread_MP_Proxies_release( &lock_context );
174
175  _Internal_error( INTERNAL_ERROR_OUT_OF_PROXIES );
176
177  /*
178   *  NOTE: The following return ensures that the compiler will
179   *        think that all paths return a value.
180   */
181
182  return NULL;
183}
184
185Thread_Control *_Thread_MP_Find_proxy (
186  Objects_Id  the_id
187)
188{
189  Thread_Proxy_control *the_proxy;
190  ISR_lock_Context      lock_context;
191
192  _Thread_MP_Proxies_acquire( &lock_context );
193
194  the_proxy = _RBTree_Find_inline(
195    &_Thread_MP_Active_proxies,
196    &the_id,
197    _Thread_MP_Proxy_equal,
198    _Thread_MP_Proxy_less,
199    _Thread_MP_Proxy_map
200  );
201
202  _Thread_MP_Proxies_release( &lock_context );
203
204  return (Thread_Control *) the_proxy;
205}
206
207void _Thread_MP_Free_proxy( Thread_Control *the_thread )
208{
209  Thread_Proxy_control *the_proxy;
210  ISR_lock_Context      lock_context;
211
212  the_proxy = (Thread_Proxy_control *) the_thread;
213
214  _Thread_MP_Proxies_acquire( &lock_context );
215
216  _RBTree_Extract( &_Thread_MP_Active_proxies, &the_proxy->Active );
217  _Chain_Append_unprotected(
218    &_Thread_MP_Inactive_proxies,
219    &the_proxy->Object.Node
220  );
221
222  _Thread_MP_Proxies_release( &lock_context );
223}
Note: See TracBrowser for help on using the repository browser.