source: rtems/cpukit/score/src/objectmp.c @ fce900b5

5
Last change on this file since fce900b5 was 3a659b04, checked in by Sebastian Huber <sebastian.huber@…>, on 12/09/16 at 06:19:22

score: Introduce _Internal_error()

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Objects MP Support
5 *  @ingroup ScoreObjectMP
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-1999.
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/objectimpl.h>
22#include <rtems/score/interr.h>
23#include <rtems/score/isrlock.h>
24#include <rtems/score/wkspace.h>
25#include <rtems/config.h>
26
27#define OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( node ) \
28  RTEMS_CONTAINER_OF( node, Objects_MP_Control, Nodes.Active.Id_lookup )
29
30#define OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( node ) \
31  RTEMS_CONTAINER_OF( node, Objects_MP_Control, Nodes.Active.Name_lookup )
32
33typedef struct {
34  uint32_t name;
35  uint32_t node;
36} Objects_MP_Name_and_node;
37
38uint16_t _Objects_Local_node;
39
40uint16_t _Objects_Maximum_nodes;
41
42uint32_t _Objects_MP_Maximum_global_objects;
43
44static CHAIN_DEFINE_EMPTY( _Objects_MP_Inactive_global_objects );
45
46ISR_LOCK_DEFINE( static, _Objects_MP_Global_lock, "MP Objects" )
47
48static void _Objects_MP_Global_acquire( ISR_lock_Context *lock_context )
49{
50  _ISR_lock_ISR_disable_and_acquire( &_Objects_MP_Global_lock, lock_context );
51}
52
53static void _Objects_MP_Global_release( ISR_lock_Context *lock_context )
54{
55  _ISR_lock_Release_and_ISR_enable( &_Objects_MP_Global_lock, lock_context );
56}
57
58static bool _Objects_MP_Id_equal(
59  const void        *left,
60  const RBTree_Node *right
61)
62{
63  const Objects_Id         *the_left;
64  const Objects_MP_Control *the_right;
65
66  the_left = left;
67  the_right = OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( right );
68
69  return *the_left == the_right->id;
70}
71
72static bool _Objects_MP_Id_less(
73  const void        *left,
74  const RBTree_Node *right
75)
76{
77  const Objects_Id         *the_left;
78  const Objects_MP_Control *the_right;
79
80  the_left = left;
81  the_right = OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( right );
82
83  return *the_left < the_right->id;
84}
85
86static void *_Objects_MP_Id_map( RBTree_Node *node )
87{
88  return OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( node );
89}
90
91static bool _Objects_MP_Name_equal(
92  const void        *left,
93  const RBTree_Node *right
94)
95{
96  const uint32_t           *the_left;
97  const Objects_MP_Control *the_right;
98
99  the_left = left;
100  the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
101
102  return *the_left == the_right->name;
103}
104
105static bool _Objects_MP_Name_less(
106  const void        *left,
107  const RBTree_Node *right
108)
109{
110  const uint32_t           *the_left;
111  const Objects_MP_Control *the_right;
112
113  the_left = left;
114  the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
115
116  return *the_left < the_right->name;
117}
118
119static void *_Objects_MP_Name_map( RBTree_Node *node )
120{
121  return OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( node );
122}
123
124static bool _Objects_MP_Name_and_node_equal(
125  const void        *left,
126  const RBTree_Node *right
127)
128{
129  const Objects_MP_Name_and_node *the_left;
130  const Objects_MP_Control       *the_right;
131
132  the_left = left;
133  the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
134
135  return the_left->name == the_right->name
136    && the_left->node == _Objects_Get_node( the_right->id );
137}
138
139static bool _Objects_MP_Name_and_node_less(
140  const void        *left,
141  const RBTree_Node *right
142)
143{
144  const Objects_MP_Name_and_node *the_left;
145  const Objects_MP_Control       *the_right;
146
147  the_left = left;
148  the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
149
150  /*
151   * Use > for the node to find smaller numbered nodes first in case of equal
152   * names.
153   */
154  return the_left->name < the_right->name
155    || ( the_left->name == the_right->name
156      && the_left->node > _Objects_Get_node( the_right->id ) );
157}
158
159void _Objects_MP_Handler_early_initialization(void)
160{
161  uint32_t   node;
162  uint32_t   maximum_nodes;
163
164  node                   = _Configuration_MP_table->node;
165  maximum_nodes          = _Configuration_MP_table->maximum_nodes;
166
167  if ( node < 1 || node > maximum_nodes )
168    _Internal_error( INTERNAL_ERROR_INVALID_NODE );
169
170  _Objects_Local_node    = node;
171  _Objects_Maximum_nodes = maximum_nodes;
172}
173
174void _Objects_MP_Handler_initialization( void )
175{
176  uint32_t maximum_global_objects;
177
178  maximum_global_objects = _Configuration_MP_table->maximum_global_objects;
179
180  _Objects_MP_Maximum_global_objects = maximum_global_objects;
181
182  if ( maximum_global_objects == 0 ) {
183    return;
184  }
185
186  _Chain_Initialize(
187    &_Objects_MP_Inactive_global_objects,
188    _Workspace_Allocate_or_fatal_error(
189      maximum_global_objects * sizeof( Objects_MP_Control )
190    ),
191    maximum_global_objects,
192    sizeof( Objects_MP_Control )
193  );
194}
195
196void _Objects_MP_Open (
197  Objects_Information *information,
198  Objects_MP_Control  *the_global_object,
199  uint32_t             the_name,      /* XXX -- wrong for variable */
200  Objects_Id           the_id
201)
202{
203  Objects_MP_Name_and_node name_and_node;
204  ISR_lock_Context         lock_context;
205
206  the_global_object->id = the_id;
207  the_global_object->name = the_name;
208
209  name_and_node.name = the_name;
210  name_and_node.node = _Objects_Get_node( the_id );
211
212  _Objects_MP_Global_acquire( &lock_context );
213
214  _RBTree_Insert_inline(
215    &information->Global_by_id,
216    &the_global_object->Nodes.Active.Id_lookup,
217    &the_id,
218    _Objects_MP_Id_less
219  );
220  _RBTree_Insert_inline(
221    &information->Global_by_name,
222    &the_global_object->Nodes.Active.Name_lookup,
223    &name_and_node,
224    _Objects_MP_Name_and_node_less
225  );
226
227  _Objects_MP_Global_release( &lock_context );
228}
229
230bool _Objects_MP_Allocate_and_open (
231  Objects_Information *information,
232  uint32_t             the_name,      /* XXX -- wrong for variable */
233  Objects_Id           the_id,
234  bool                 is_fatal_error
235)
236{
237  Objects_MP_Control  *the_global_object;
238
239  the_global_object = _Objects_MP_Allocate_global_object();
240  if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
241
242    if ( is_fatal_error == false )
243      return false;
244
245    _Internal_error( INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS );
246  }
247
248  _Objects_MP_Open( information, the_global_object, the_name, the_id );
249
250  return true;
251}
252
253void _Objects_MP_Close (
254  Objects_Information *information,
255  Objects_Id           the_id
256)
257{
258  Objects_MP_Control *the_global_object;
259  ISR_lock_Context    lock_context;
260
261  _Objects_MP_Global_acquire( &lock_context );
262
263  the_global_object = _RBTree_Find_inline(
264    &information->Global_by_id,
265    &the_id,
266    _Objects_MP_Id_equal,
267    _Objects_MP_Id_less,
268    _Objects_MP_Id_map
269  );
270
271  if ( the_global_object != NULL ) {
272    _RBTree_Extract(
273      &information->Global_by_id,
274      &the_global_object->Nodes.Active.Id_lookup
275    );
276    _RBTree_Extract(
277      &information->Global_by_name,
278      &the_global_object->Nodes.Active.Name_lookup
279    );
280    _Objects_MP_Free_global_object( the_global_object );
281    _Objects_MP_Global_release( &lock_context );
282  } else {
283    _Objects_MP_Global_release( &lock_context );
284
285    _Internal_error( INTERNAL_ERROR_INVALID_GLOBAL_ID );
286  }
287}
288
289Objects_Name_or_id_lookup_errors _Objects_MP_Global_name_search(
290  Objects_Information *information,
291  Objects_Name         the_name,
292  uint32_t             nodes_to_search,
293  Objects_Id          *the_id
294)
295{
296  Objects_Name_or_id_lookup_errors  status;
297  Objects_MP_Control               *the_global_object;
298  ISR_lock_Context                  lock_context;
299
300  if ( nodes_to_search > _Objects_Maximum_nodes ) {
301    return OBJECTS_INVALID_NODE;
302  }
303
304  _Objects_MP_Global_acquire( &lock_context );
305
306  if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES ) {
307    the_global_object = _RBTree_Find_inline(
308      &information->Global_by_name,
309      &the_name.name_u32,
310      _Objects_MP_Name_equal,
311      _Objects_MP_Name_less,
312      _Objects_MP_Name_map
313    );
314  } else {
315    Objects_MP_Name_and_node name_and_node;
316
317    name_and_node.name = the_name.name_u32;
318    name_and_node.node = nodes_to_search;
319
320    the_global_object = _RBTree_Find_inline(
321      &information->Global_by_name,
322      &name_and_node,
323      _Objects_MP_Name_and_node_equal,
324      _Objects_MP_Name_and_node_less,
325      _Objects_MP_Name_map
326    );
327  }
328
329  if ( the_global_object != NULL ) {
330    *the_id = the_global_object->id;
331    status = OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL;
332  } else {
333    status = OBJECTS_INVALID_NAME;
334  }
335
336  _Objects_MP_Global_release( &lock_context );
337
338  return status;
339}
340
341bool _Objects_MP_Is_remote(
342  Objects_Id                 the_id,
343  const Objects_Information *information
344)
345{
346  Objects_MP_Control *the_global_object;
347  ISR_lock_Context    lock_context;
348
349  _Objects_MP_Global_acquire( &lock_context );
350
351  the_global_object = _RBTree_Find_inline(
352    &information->Global_by_id,
353    &the_id,
354    _Objects_MP_Id_equal,
355    _Objects_MP_Id_less,
356    _Objects_MP_Id_map
357  );
358
359  _Objects_MP_Global_release( &lock_context );
360
361  return the_global_object != NULL;
362}
363
364Objects_MP_Control *_Objects_MP_Allocate_global_object( void )
365{
366  Objects_MP_Control *the_global_object;
367  ISR_lock_Context    lock_context;
368
369  _Objects_MP_Global_acquire( &lock_context );
370
371  the_global_object = (Objects_MP_Control *)
372    _Chain_Get_unprotected( &_Objects_MP_Inactive_global_objects );
373
374  _Objects_MP_Global_release( &lock_context );
375  return the_global_object;
376}
377
378void _Objects_MP_Free_global_object( Objects_MP_Control *the_global_object )
379{
380  ISR_lock_Context lock_context;
381
382  _Objects_MP_Global_acquire( &lock_context );
383
384  _Chain_Initialize_node( &the_global_object->Nodes.Inactive );
385  _Chain_Append_unprotected(
386    &_Objects_MP_Inactive_global_objects,
387    &the_global_object->Nodes.Inactive
388  );
389
390  _Objects_MP_Global_release( &lock_context );
391}
Note: See TracBrowser for help on using the repository browser.