source: rtems/cpukit/score/src/mpci.c @ 0577ec1d

4.104.114.84.95
Last change on this file since 0577ec1d was ef9505a9, checked in by Joel Sherrill <joel.sherrill@…>, on 07/01/02 at 22:30:12

2002-07-01 Joel Sherrill <joel@…>

  • Mega patch merge to change the format of the object IDs to loosen the dependency between the SCORE and the various APIs. There was considerable work to simplify the object name management and it appears that the name_table field is no longer needed. This patch also includes the addition of the internal mutex which is currently only used to protect some types of allocation and deallocation. This significantly can reduce context switch latency under certain circumstances. In particular, some heap/region operations were O(n) and had dispatching disabled. This should help enormously. With this merge, the patch is not as clean as it should be. In particular, the documentation has not been modified to reflect the new object ID layout, the IDs in the test screens are not updated, and _Objects_Get_information needs to be a real routine not inlined. As part of this patch a lot of MP code for thread/proxy blocking was made conditional and cleaned up.
  • include/Makefile.am, include/rtems/score/coremsg.h, include/rtems/score/coremutex.h, include/rtems/score/coresem.h, include/rtems/score/object.h, include/rtems/score/threadq.h, inline/rtems/score/object.inl, inline/rtems/score/thread.inl, macros/rtems/score/object.inl, src/Makefile.am, src/coremsg.c, src/coremutex.c, src/coresem.c, src/mpci.c, src/objectcomparenameraw.c, src/objectextendinformation.c, src/objectinitializeinformation.c, src/objectnametoid.c, src/thread.c, src/threadclose.c, src/threadget.c, src/threadq.c, src/threadqextractwithproxy.c: Modified as part of above.
  • include/rtems/score/apimutex.h, src/objectgetnoprotection.c: New files.
  • Property mode set to 100644
File size: 10.9 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
390/*PAGE
391 *
392 *  _MPCI_Announce
393 *
394 */
395 
396void _MPCI_Announce ( void )
397{
398  _Thread_Disable_dispatch();
399  (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0 );
400  _Thread_Enable_dispatch();
401}
402
403/*PAGE
404 *
405 *  _MPCI_Internal_packets_Send_process_packet
406 *
407 */
408 
409void _MPCI_Internal_packets_Send_process_packet (
410   MPCI_Internal_Remote_operations operation
411)
412{
413  MPCI_Internal_packet *the_packet;
414 
415  switch ( operation ) {
416 
417    case MPCI_PACKETS_SYSTEM_VERIFY:
418 
419      the_packet                    = _MPCI_Internal_packets_Get_packet();
420      the_packet->Prefix.the_class  = MP_PACKET_MPCI_INTERNAL;
421      the_packet->Prefix.length     = sizeof ( MPCI_Internal_packet );
422      the_packet->Prefix.to_convert = sizeof ( MPCI_Internal_packet );
423      the_packet->operation         = operation;
424 
425      the_packet->maximum_nodes = _Objects_Maximum_nodes;
426 
427      the_packet->maximum_global_objects = _Objects_MP_Maximum_global_objects;
428 
429      _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
430      break;
431  }
432}
433 
434/*PAGE
435 *
436 *  _MPCI_Internal_packets_Send_request_packet
437 *
438 *  This subprogram is not needed since there are no request
439 *  packets to be sent by this manager.
440 *
441 */
442 
443/*PAGE
444 *
445 *  _MPCI_Internal_packets_Send_response_packet
446 *
447 *  This subprogram is not needed since there are no response
448 *  packets to be sent by this manager.
449 *
450 */
451 
452/*PAGE
453 *
454 *
455 *  _MPCI_Internal_packets_Process_packet
456 *
457 */
458 
459void _MPCI_Internal_packets_Process_packet (
460  MP_packet_Prefix  *the_packet_prefix
461)
462{
463  MPCI_Internal_packet *the_packet;
464  unsigned32                  maximum_nodes;
465  unsigned32                  maximum_global_objects;
466 
467  the_packet = (MPCI_Internal_packet *) the_packet_prefix;
468 
469  switch ( the_packet->operation ) {
470 
471    case MPCI_PACKETS_SYSTEM_VERIFY:
472 
473      maximum_nodes          = the_packet->maximum_nodes;
474      maximum_global_objects = the_packet->maximum_global_objects;
475      if ( maximum_nodes != _Objects_Maximum_nodes ||
476           maximum_global_objects != _Objects_MP_Maximum_global_objects ) {
477 
478        _MPCI_Return_packet( the_packet_prefix );
479 
480        _Internal_error_Occurred(
481          INTERNAL_ERROR_CORE,
482          TRUE,
483          INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION
484        );
485      }
486 
487      _MPCI_Return_packet( the_packet_prefix );
488 
489      break;
490  }
491}
492 
493/*PAGE
494 *
495 *  _MPCI_Internal_packets_Send_object_was_deleted
496 *
497 *  This subprogram is not needed since there are no objects
498 *  deleted by this manager.
499 *
500 */
501 
502/*PAGE
503 *
504 *  _MPCI_Internal_packets_Send_extract_proxy
505 *
506 *  This subprogram is not needed since there are no objects
507 *  deleted by this manager.
508 *
509 */
510 
511/*PAGE
512 *
513 *  _MPCI_Internal_packets_Get_packet
514 *
515 */
516 
517MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void )
518{
519  return ( (MPCI_Internal_packet *) _MPCI_Get_packet() );
520}
521
522/* end of file */
Note: See TracBrowser for help on using the repository browser.