source: rtems/cpukit/score/src/mpci.c @ 1019ae4

4.104.114.84.95
Last change on this file since 1019ae4 was 1019ae4, checked in by Joel Sherrill <joel.sherrill@…>, on 01/08/97 at 16:20:47

added some casts to reduce warnings reported by users with Microtec C++
compiler.

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