source: rtems/c/src/exec/score/src/mpci.c @ 97e2729d

4.104.114.84.95
Last change on this file since 97e2729d was 97e2729d, checked in by Joel Sherrill <joel.sherrill@…>, on 11/23/98 at 17:38:09

Added --disable-multiprocessing flag and modified a lot of files to make
it work.

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