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 Oct 31, 2002 at 8:09:49 PM

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
Line 
1/*
2 *  Multiprocessing Communications Interface (MPCI) Handler
3 *
4 *
5 *  COPYRIGHT (c) 1989-1999.
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.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#include <rtems/system.h>
16#include <rtems/score/cpu.h>
17#include <rtems/score/interr.h>
18#if defined(RTEMS_MULTIPROCESSING)
19#include <rtems/score/mpci.h>
20#include <rtems/score/mppkt.h>
21#endif
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>
30
31/*PAGE
32 *
33 *  _MPCI_Handler_initialization
34 *
35 *  This subprogram performs the initialization necessary for this handler.
36 */
37
38void _MPCI_Handler_initialization( 
39  MPCI_Control            *users_mpci_table,
40  unsigned32               timeout_status
41)
42{
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
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
70  attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
71
72  _CORE_semaphore_Initialize(
73    &_MPCI_Semaphore,
74    &attributes,              /* the_semaphore_attributes */
75    0                         /* initial_value */
76  );
77
78  _Thread_queue_Initialize(
79    &_MPCI_Remote_blocked_threads,
80    THREAD_QUEUE_DISCIPLINE_FIFO,
81    STATES_WAITING_FOR_RPC_REPLY,
82    timeout_status
83  );
84}
85
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 */
115    THREAD_CPU_BUDGET_ALGORITHM_NONE,
116    NULL,        /* no budget algorithm callout */
117    0,           /* all interrupts enabled */
118    _MPCI_Internal_name
119  );
120 
121  _Thread_Start(
122    _MPCI_Receive_server_tcb,
123    THREAD_START_NUMERIC,
124    (void *) _MPCI_Receive_server,
125    NULL,
126    0
127  );
128}
129
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{
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(
152  MP_packet_Classes      the_class,
153  MPCI_Packet_processor  the_packet_processor
154 
155)
156{
157  _MPCI_Packet_processors[ the_class ] = the_packet_processor;
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
168MP_packet_Prefix *_MPCI_Get_packet ( void )
169{
170  MP_packet_Prefix  *the_packet;
171
172  (*_MPCI_table->get_packet)( &the_packet );
173
174  if ( the_packet == NULL )
175    _Internal_error_Occurred(
176      INTERNAL_ERROR_CORE,
177      TRUE,
178      INTERNAL_ERROR_OUT_OF_PACKETS
179    );
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 (
200  MP_packet_Prefix   *the_packet
201)
202{
203  (*_MPCI_table->return_packet)( the_packet );
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,
216  MP_packet_Prefix   *the_packet
217)
218{
219  the_packet->source_tid = _Thread_Executing->Object.id;
220  the_packet->to_convert =
221     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
222       sizeof(unsigned32);
223
224  (*_MPCI_table->send_packet)( destination, the_packet );
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
235unsigned32 _MPCI_Send_request_packet (
236  unsigned32          destination,
237  MP_packet_Prefix   *the_packet,
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 =
244     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
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
253    (*_MPCI_table->send_packet)( destination, the_packet );
254
255    _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );
256
257    /*
258     *  See if we need a default timeout
259     */
260
261    if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
262        the_packet->timeout = _MPCI_table->default_timeout;
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,
284  MP_packet_Prefix   *the_packet
285)
286{
287  the_packet->source_tid = _Thread_Executing->Object.id;
288
289  (*_MPCI_table->send_packet)( destination, the_packet );
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
300MP_packet_Prefix  *_MPCI_Receive_packet ( void )
301{
302  MP_packet_Prefix  *the_packet;
303
304  (*_MPCI_table->receive_packet)( &the_packet );
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 (
318  MP_packet_Prefix  *the_packet
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
340/*PAGE
341 *
342 *  _MPCI_Receive_server
343 *
344 */
345
346Thread _MPCI_Receive_server(
347  unsigned32 ignored
348)
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  }
388
389  return 0;   /* unreached - only to remove warnings */
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
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
524/* end of file */
Note: See TracBrowser for help on using the repository browser.