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

4.104.114.84.95
Last change on this file since adf98bd was adf98bd, checked in by Joel Sherrill <joel.sherrill@…>, on 02/21/96 at 14:44:11

Removed the internal thread objects and dispersed its contents to
the thread handler (IDLE), MPCI object (SYSI now MP Receive)
and initialize_executive_early (IO initialization). The SYSI task
no longer exists in a single processor configuration. This reduces
single processor Workspace requirements by a TCB and a stack which
is often larger than the minimum stack size. Moving the IO initialization
plus accompanying BSP hooks eliminated an initialization ordering problem
in which a global task could be created before the MPCI was initialized.

  • Property mode set to 100644
File size: 11.1 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    FALSE,       /* not timesliced */
119    0,           /* all interrupts enabled */
120    _MPCI_Internal_name
121  );
122 
123  _Thread_Start(
124    _MPCI_Receive_server_tcb,
125    THREAD_START_NUMERIC,
126    _MPCI_Receive_server,
127    NULL,
128    0
129  );
130}
131
132/*PAGE
133 *
134 *  _MPCI_Initialization
135 *
136 *  This subprogram initializes the MPCI driver by
137 *  invoking the user provided MPCI initialization callout.
138 */
139
140void _MPCI_Initialization ( void )
141{
142  (*_MPCI_table->initialization)();
143}
144
145/*PAGE
146 *
147 *  _MPCI_Register_packet_processor
148 *
149 *  This routine registers the MPCI packet processor for the
150 *  designated object class.
151 */
152 
153void _MPCI_Register_packet_processor(
154  Objects_Classes        the_class,
155  MPCI_Packet_processor  the_packet_processor
156 
157)
158{
159  _MPCI_Packet_processors[ the_class ] = the_packet_processor;
160}
161
162/*PAGE
163 *
164 *  _MPCI_Get_packet
165 *
166 *  This subprogram obtains a packet by invoking the user provided
167 *  MPCI get packet callout.
168 */
169
170MP_packet_Prefix *_MPCI_Get_packet ( void )
171{
172  MP_packet_Prefix  *the_packet;
173
174  (*_MPCI_table->get_packet)( &the_packet );
175
176  if ( the_packet == NULL )
177    _Internal_error_Occurred(
178      INTERNAL_ERROR_CORE,
179      TRUE,
180      INTERNAL_ERROR_OUT_OF_PACKETS
181    );
182
183  /*
184   *  Put in a default timeout that will be used for
185   *  all packets that do not otherwise have a timeout.
186   */
187
188  the_packet->timeout = MPCI_DEFAULT_TIMEOUT;
189
190  return the_packet;
191}
192
193/*PAGE
194 *
195 *  _MPCI_Return_packet
196 *
197 *  This subprogram returns a packet by invoking the user provided
198 *  MPCI return packet callout.
199 */
200
201void _MPCI_Return_packet (
202  MP_packet_Prefix   *the_packet
203)
204{
205  (*_MPCI_table->return_packet)( the_packet );
206}
207
208/*PAGE
209 *
210 *  _MPCI_Send_process_packet
211 *
212 *  This subprogram sends a process packet by invoking the user provided
213 *  MPCI send callout.
214 */
215
216void _MPCI_Send_process_packet (
217  unsigned32          destination,
218  MP_packet_Prefix   *the_packet
219)
220{
221  the_packet->source_tid = _Thread_Executing->Object.id;
222  the_packet->to_convert =
223     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
224       sizeof(unsigned32);
225
226  (*_MPCI_table->send_packet)( destination, the_packet );
227}
228
229/*PAGE
230 *
231 *  _MPCI_Send_request_packet
232 *
233 *  This subprogram sends a request packet by invoking the user provided
234 *  MPCI send callout.
235 */
236
237unsigned32 _MPCI_Send_request_packet (
238  unsigned32          destination,
239  MP_packet_Prefix   *the_packet,
240  States_Control      extra_state
241)
242{
243  the_packet->source_tid      = _Thread_Executing->Object.id;
244  the_packet->source_priority = _Thread_Executing->current_priority;
245  the_packet->to_convert =
246     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
247       sizeof(unsigned32);
248
249  _Thread_Executing->Wait.id = the_packet->id;
250
251  _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads;
252
253  _Thread_Disable_dispatch();
254
255    (*_MPCI_table->send_packet)( destination, the_packet );
256
257    _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads );
258
259    /*
260     *  See if we need a default timeout
261     */
262
263    if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
264        the_packet->timeout = _MPCI_table->default_timeout;
265
266    _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout );
267
268    _Thread_Executing->current_state =
269      _States_Set( extra_state, _Thread_Executing->current_state );
270
271  _Thread_Enable_dispatch();
272
273  return _Thread_Executing->Wait.return_code;
274}
275
276/*PAGE
277 *
278 *  _MPCI_Send_response_packet
279 *
280 *  This subprogram sends a response packet by invoking the user provided
281 *  MPCI send callout.
282 */
283
284void _MPCI_Send_response_packet (
285  unsigned32          destination,
286  MP_packet_Prefix   *the_packet
287)
288{
289  the_packet->source_tid = _Thread_Executing->Object.id;
290
291  (*_MPCI_table->send_packet)( destination, the_packet );
292}
293
294/*PAGE
295 *
296 *  _MPCI_Receive_packet
297 *
298 *  This subprogram receives a packet by invoking the user provided
299 *  MPCI receive callout.
300 */
301
302MP_packet_Prefix  *_MPCI_Receive_packet ( void )
303{
304  MP_packet_Prefix  *the_packet;
305
306  (*_MPCI_table->receive_packet)( &the_packet );
307
308  return the_packet;
309}
310
311/*PAGE
312 *
313 *  _MPCI_Process_response
314 *
315 *  This subprogram obtains a packet by invoking the user provided
316 *  MPCI get packet callout.
317 */
318
319Thread_Control *_MPCI_Process_response (
320  MP_packet_Prefix  *the_packet
321)
322{
323  Thread_Control    *the_thread;
324  Objects_Locations  location;
325
326  the_thread = _Thread_Get( the_packet->id, &location );
327  switch ( location ) {
328    case OBJECTS_ERROR:
329    case OBJECTS_REMOTE:
330      the_thread = NULL;          /* IMPOSSIBLE */
331      break;
332    case OBJECTS_LOCAL:
333      _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread );
334      the_thread->Wait.return_code = the_packet->return_code;
335      _Thread_Unnest_dispatch();
336    break;
337  }
338
339  return the_thread;
340}
341
342/*PAGE
343 *
344 *  _MPCI_Receive_server
345 *
346 */
347
348Thread _MPCI_Receive_server(
349  unsigned32 ignored
350)
351{
352 
353  MP_packet_Prefix         *the_packet;
354  MPCI_Packet_processor     the_function;
355  Thread_Control           *executing;
356 
357  executing = _Thread_Executing;
358
359  for ( ; ; ) {
360 
361    executing->receive_packet = NULL;
362
363    _Thread_Disable_dispatch();
364    _CORE_semaphore_Seize( &_MPCI_Semaphore, 0, TRUE, WATCHDOG_NO_TIMEOUT );
365    _Thread_Enable_dispatch();
366 
367    for ( ; ; ) {
368      the_packet = _MPCI_Receive_packet();
369 
370      if ( !the_packet )
371        break;
372 
373      executing->receive_packet = the_packet;
374 
375      if ( !_Mp_packet_Is_valid_packet_class ( the_packet->the_class ) )
376        break;
377 
378      the_function = _MPCI_Packet_processors[ the_packet->the_class ];
379 
380      if ( !the_function )
381        _Internal_error_Occurred(
382          INTERNAL_ERROR_CORE,
383          TRUE,
384          INTERNAL_ERROR_BAD_PACKET
385        );
386 
387        (*the_function)( the_packet );
388    }
389  }
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.