source: rtems/cpukit/score/src/mpci.c @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 11.3 KB
Line 
1/*
2 *  Multiprocessing Communications Interface (MPCI) Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-2008.
6 *  On-Line Applications Research Corporation (OAR).
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 */
12
13#if HAVE_CONFIG_H
14#include "config.h"
15#endif
16
17#include <rtems/system.h>
18#if defined(RTEMS_MULTIPROCESSING)
19#include <rtems/score/mpci.h>
20#include <rtems/score/mppkt.h>
21#endif
22#include <rtems/config.h>
23#include <rtems/score/cpu.h>
24#include <rtems/score/interr.h>
25#include <rtems/score/states.h>
26#include <rtems/score/thread.h>
27#include <rtems/score/threadq.h>
28#include <rtems/score/tqdata.h>
29#include <rtems/score/watchdog.h>
30#include <rtems/score/sysstate.h>
31
32#include <rtems/score/coresem.h>
33#include <rtems/config.h>
34
35RTEMS_STATIC_ASSERT(
36  sizeof(MPCI_Internal_packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
37  MPCI_Internal_packet
38);
39
40/**
41 *  This is the core semaphore which the MPCI Receive Server blocks on.
42 */
43CORE_semaphore_Control _MPCI_Semaphore;
44
45/*
46 *  _MPCI_Handler_initialization
47 *
48 *  This subprogram performs the initialization necessary for this handler.
49 */
50
51void _MPCI_Handler_initialization(
52  uint32_t   timeout_status
53)
54{
55  CORE_semaphore_Attributes   attributes;
56  MPCI_Control               *users_mpci_table;
57
58  users_mpci_table = _Configuration_MP_table->User_mpci_table;
59
60  if ( _System_state_Is_multiprocessing && !users_mpci_table )
61    _Internal_error_Occurred(
62      INTERNAL_ERROR_CORE,
63      true,
64      INTERNAL_ERROR_NO_MPCI
65    );
66
67  _MPCI_table = users_mpci_table;
68
69  if ( !_System_state_Is_multiprocessing )
70    return;
71
72  /*
73   *  Register the MP Process Packet routine.
74   */
75
76  _MPCI_Register_packet_processor(
77    MP_PACKET_MPCI_INTERNAL,
78    _MPCI_Internal_packets_Process_packet
79  );
80
81  /*
82   *  Create the counting semaphore used by the MPCI Receive Server.
83   */
84
85  attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
86
87  _CORE_semaphore_Initialize(
88    &_MPCI_Semaphore,
89    &attributes,              /* the_semaphore_attributes */
90    0                         /* initial_value */
91  );
92
93  _Thread_queue_Initialize(
94    &_MPCI_Remote_blocked_threads,
95    THREAD_QUEUE_DISCIPLINE_FIFO,
96    STATES_WAITING_FOR_RPC_REPLY,
97    timeout_status
98  );
99}
100
101/*
102 *  _MPCI_Create_server
103 *
104 *  This subprogram creates the MPCI receive server.
105 */
106
107void _MPCI_Create_server( void )
108{
109  Objects_Name name;
110
111
112  if ( !_System_state_Is_multiprocessing )
113    return;
114
115  /*
116   *  Initialize the MPCI Receive Server
117   */
118
119  _MPCI_Receive_server_tcb = _Thread_Internal_allocate();
120
121  name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' );
122  _Thread_Initialize(
123    &_Thread_Internal_information,
124    _MPCI_Receive_server_tcb,
125    NULL,        /* allocate the stack */
126    _Stack_Minimum() +
127      CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK +
128      _Configuration_MP_table->extra_mpci_receive_server_stack,
129    CPU_ALL_TASKS_ARE_FP,
130    PRIORITY_MINIMUM,
131    false,       /* no preempt */
132    THREAD_CPU_BUDGET_ALGORITHM_NONE,
133    NULL,        /* no budget algorithm callout */
134    0,           /* all interrupts enabled */
135    name
136  );
137
138  _Thread_Start(
139    _MPCI_Receive_server_tcb,
140    THREAD_START_NUMERIC,
141    (void *) _MPCI_Receive_server,
142    NULL,
143    0
144  );
145}
146
147/*
148 *  _MPCI_Initialization
149 *
150 *  This subprogram initializes the MPCI driver by
151 *  invoking the user provided MPCI initialization callout.
152 */
153
154void _MPCI_Initialization ( void )
155{
156  (*_MPCI_table->initialization)();
157}
158
159/*
160 *  _MPCI_Register_packet_processor
161 *
162 *  This routine registers the MPCI packet processor for the
163 *  designated object class.
164 */
165
166void _MPCI_Register_packet_processor(
167  MP_packet_Classes      the_class,
168  MPCI_Packet_processor  the_packet_processor
169
170)
171{
172  _MPCI_Packet_processors[ the_class ] = the_packet_processor;
173}
174
175/*
176 *  _MPCI_Get_packet
177 *
178 *  This subprogram obtains a packet by invoking the user provided
179 *  MPCI get packet callout.
180 */
181
182MP_packet_Prefix *_MPCI_Get_packet ( void )
183{
184  MP_packet_Prefix  *the_packet;
185
186  (*_MPCI_table->get_packet)( &the_packet );
187
188  if ( the_packet == NULL )
189    _Internal_error_Occurred(
190      INTERNAL_ERROR_CORE,
191      true,
192      INTERNAL_ERROR_OUT_OF_PACKETS
193    );
194
195  /*
196   *  Put in a default timeout that will be used for
197   *  all packets that do not otherwise have a timeout.
198   */
199
200  the_packet->timeout = MPCI_DEFAULT_TIMEOUT;
201
202  return the_packet;
203}
204
205/*
206 *  _MPCI_Return_packet
207 *
208 *  This subprogram returns a packet by invoking the user provided
209 *  MPCI return packet callout.
210 */
211
212void _MPCI_Return_packet (
213  MP_packet_Prefix   *the_packet
214)
215{
216  (*_MPCI_table->return_packet)( the_packet );
217}
218
219/*
220 *  _MPCI_Send_process_packet
221 *
222 *  This subprogram sends a process packet by invoking the user provided
223 *  MPCI send callout.
224 */
225
226void _MPCI_Send_process_packet (
227  uint32_t            destination,
228  MP_packet_Prefix   *the_packet
229)
230{
231  the_packet->source_tid = _Thread_Executing->Object.id;
232  the_packet->to_convert =
233     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) / sizeof(uint32_t);
234
235  (*_MPCI_table->send_packet)( destination, the_packet );
236}
237
238/*
239 *  _MPCI_Send_request_packet
240 *
241 *  This subprogram sends a request packet by invoking the user provided
242 *  MPCI send callout.
243 */
244
245uint32_t   _MPCI_Send_request_packet (
246  uint32_t            destination,
247  MP_packet_Prefix   *the_packet,
248  States_Control      extra_state
249)
250{
251  the_packet->source_tid      = _Thread_Executing->Object.id;
252  the_packet->source_priority = _Thread_Executing->current_priority;
253  the_packet->to_convert =
254     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) / sizeof(uint32_t);
255
256  _Thread_Executing->Wait.id = the_packet->id;
257
258  _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads;
259
260  _Thread_Disable_dispatch();
261
262    (*_MPCI_table->send_packet)( destination, the_packet );
263
264    _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );
265
266    /*
267     *  See if we need a default timeout
268     */
269
270    if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
271        the_packet->timeout = _MPCI_table->default_timeout;
272
273    _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout );
274
275    _Thread_Executing->current_state =
276      _States_Set( extra_state, _Thread_Executing->current_state );
277
278  _Thread_Enable_dispatch();
279
280  return _Thread_Executing->Wait.return_code;
281}
282
283/*
284 *  _MPCI_Send_response_packet
285 *
286 *  This subprogram sends a response packet by invoking the user provided
287 *  MPCI send callout.
288 */
289
290void _MPCI_Send_response_packet (
291  uint32_t            destination,
292  MP_packet_Prefix   *the_packet
293)
294{
295  the_packet->source_tid = _Thread_Executing->Object.id;
296
297  (*_MPCI_table->send_packet)( destination, the_packet );
298}
299
300/*
301 *  _MPCI_Receive_packet
302 *
303 *  This subprogram receives a packet by invoking the user provided
304 *  MPCI receive callout.
305 */
306
307MP_packet_Prefix  *_MPCI_Receive_packet ( void )
308{
309  MP_packet_Prefix  *the_packet;
310
311  (*_MPCI_table->receive_packet)( &the_packet );
312
313  return the_packet;
314}
315
316/*
317 *  _MPCI_Process_response
318 *
319 *  This subprogram obtains a packet by invoking the user provided
320 *  MPCI get packet callout.
321 */
322
323Thread_Control *_MPCI_Process_response (
324  MP_packet_Prefix  *the_packet
325)
326{
327  Thread_Control    *the_thread;
328  Objects_Locations  location;
329
330  the_thread = _Thread_Get( the_packet->id, &location );
331  switch ( location ) {
332    case OBJECTS_ERROR:
333#if defined(RTEMS_MULTIPROCESSING)
334    case OBJECTS_REMOTE:
335#endif
336      the_thread = NULL;          /* IMPOSSIBLE */
337      break;
338    case OBJECTS_LOCAL:
339      _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread );
340      the_thread->Wait.return_code = the_packet->return_code;
341      _Thread_Unnest_dispatch();
342    break;
343  }
344
345  return the_thread;
346}
347
348/*
349 *  _MPCI_Receive_server
350 *
351 */
352
353Thread _MPCI_Receive_server(
354  uint32_t   ignored
355)
356{
357
358  MP_packet_Prefix         *the_packet;
359  MPCI_Packet_processor     the_function;
360  Thread_Control           *executing;
361
362  executing = _Thread_Executing;
363
364  for ( ; ; ) {
365
366    executing->receive_packet = NULL;
367
368    _Thread_Disable_dispatch();
369    _CORE_semaphore_Seize( &_MPCI_Semaphore, 0, true, WATCHDOG_NO_TIMEOUT );
370    _Thread_Enable_dispatch();
371
372    for ( ; ; ) {
373      the_packet = _MPCI_Receive_packet();
374
375      if ( !the_packet )
376        break;
377
378      executing->receive_packet = the_packet;
379
380      if ( !_Mp_packet_Is_valid_packet_class ( the_packet->the_class ) )
381        break;
382
383      the_function = _MPCI_Packet_processors[ the_packet->the_class ];
384
385      if ( !the_function )
386        _Internal_error_Occurred(
387          INTERNAL_ERROR_CORE,
388          true,
389          INTERNAL_ERROR_BAD_PACKET
390        );
391
392        (*the_function)( the_packet );
393    }
394  }
395
396  return 0;   /* unreached - only to remove warnings */
397}
398
399/*
400 *  _MPCI_Announce
401 *
402 */
403
404void _MPCI_Announce ( void )
405{
406  _Thread_Disable_dispatch();
407  (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0 );
408  _Thread_Enable_dispatch();
409}
410
411/*
412 *  _MPCI_Internal_packets_Send_process_packet
413 *
414 */
415
416void _MPCI_Internal_packets_Send_process_packet (
417   MPCI_Internal_Remote_operations operation
418)
419{
420  MPCI_Internal_packet *the_packet;
421
422  switch ( operation ) {
423
424    case MPCI_PACKETS_SYSTEM_VERIFY:
425
426      the_packet                    = _MPCI_Internal_packets_Get_packet();
427      the_packet->Prefix.the_class  = MP_PACKET_MPCI_INTERNAL;
428      the_packet->Prefix.length     = sizeof ( MPCI_Internal_packet );
429      the_packet->Prefix.to_convert = sizeof ( MPCI_Internal_packet );
430      the_packet->operation         = operation;
431
432      the_packet->maximum_nodes = _Objects_Maximum_nodes;
433
434      the_packet->maximum_global_objects = _Objects_MP_Maximum_global_objects;
435
436      _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
437      break;
438  }
439}
440
441/*
442 *  _MPCI_Internal_packets_Send_request_packet
443 *
444 *  This subprogram is not needed since there are no request
445 *  packets to be sent by this manager.
446 *
447 */
448
449/*
450 *  _MPCI_Internal_packets_Send_response_packet
451 *
452 *  This subprogram is not needed since there are no response
453 *  packets to be sent by this manager.
454 *
455 */
456
457/*
458 *
459 *  _MPCI_Internal_packets_Process_packet
460 *
461 */
462
463void _MPCI_Internal_packets_Process_packet (
464  MP_packet_Prefix  *the_packet_prefix
465)
466{
467  MPCI_Internal_packet *the_packet;
468  uint32_t                    maximum_nodes;
469  uint32_t                    maximum_global_objects;
470
471  the_packet = (MPCI_Internal_packet *) the_packet_prefix;
472
473  switch ( the_packet->operation ) {
474
475    case MPCI_PACKETS_SYSTEM_VERIFY:
476
477      maximum_nodes          = the_packet->maximum_nodes;
478      maximum_global_objects = the_packet->maximum_global_objects;
479      if ( maximum_nodes != _Objects_Maximum_nodes ||
480           maximum_global_objects != _Objects_MP_Maximum_global_objects ) {
481
482        _MPCI_Return_packet( the_packet_prefix );
483
484        _Internal_error_Occurred(
485          INTERNAL_ERROR_CORE,
486          true,
487          INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION
488        );
489      }
490
491      _MPCI_Return_packet( the_packet_prefix );
492
493      break;
494  }
495}
496
497/*
498 *  _MPCI_Internal_packets_Send_object_was_deleted
499 *
500 *  This subprogram is not needed since there are no objects
501 *  deleted by this manager.
502 *
503 */
504
505/*
506 *  _MPCI_Internal_packets_Send_extract_proxy
507 *
508 *  This subprogram is not needed since there are no objects
509 *  deleted by this manager.
510 *
511 */
512
513/*
514 *  _MPCI_Internal_packets_Get_packet
515 *
516 */
517
518MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void )
519{
520  return ( (MPCI_Internal_packet *) _MPCI_Get_packet() );
521}
522
523/* end of file */
Note: See TracBrowser for help on using the repository browser.