source: rtems/cpukit/score/src/threadmp.c @ 21275b58

Last change on this file since 21275b58 was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 22, 2018 at 6:14:51 PM

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Distributed MP Support
5 *  @ingroup ScoreThreadMP
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.