source: rtems/cpukit/score/src/mpci.c @ b041968

4.104.114.84.95
Last change on this file since b041968 was b041968, checked in by Joel Sherrill <joel.sherrill@…>, on 10/31/02 at 20:09:49

2002-10-31 Joel Sherrill <joel@…>

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