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

4.104.114.84.95
Last change on this file since cda7ecc was cda7ecc, checked in by Joel Sherrill <joel.sherrill@…>, on 09/21/95 at 17:58:58

More file movement

  • Property mode set to 100644
File size: 7.4 KB
RevLine 
[ac7d5ef0]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>
[3a4ae6c]17#include <rtems/core/cpu.h>
18#include <rtems/core/interr.h>
19#include <rtems/core/mpci.h>
20#include <rtems/core/mppkt.h>
21#include <rtems/core/states.h>
22#include <rtems/core/thread.h>
23#include <rtems/core/threadq.h>
24#include <rtems/core/tqdata.h>
25#include <rtems/core/watchdog.h>
[be650a84]26#include <rtems/core/sysstate.h>
[3a4ae6c]27
28#include <rtems/core/coresem.h>
29
[ac7d5ef0]30/*PAGE
31 *
32 *  _MPCI_Handler_initialization
33 *
34 *  This subprogram performs the initialization necessary for this handler.
35 */
36
[3a4ae6c]37void _MPCI_Handler_initialization(
[cda7ecc]38  MPCI_Control            *users_mpci_table,
39  unsigned32               timeout_status
[3a4ae6c]40)
[ac7d5ef0]41{
[3a4ae6c]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  attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
54
55  _CORE_semaphore_Initialize(
56    &_MPCI_Semaphore,
57    OBJECTS_NO_CLASS,         /* free floating semaphore */
58    &attributes,              /* the_semaphore_attributes */
59    0,                        /* initial_value */
60    NULL                      /* proxy_extract_callout */
61  );
62
[ac7d5ef0]63  _Thread_queue_Initialize(
64    &_MPCI_Remote_blocked_threads,
[7f6a24ab]65    OBJECTS_NO_CLASS,
66    THREAD_QUEUE_DISCIPLINE_FIFO,
67    STATES_WAITING_FOR_RPC_REPLY,
[3a4ae6c]68    NULL,
[cda7ecc]69    timeout_status
[ac7d5ef0]70  );
71}
72
73/*PAGE
74 *
75 *  _MPCI_Initialization
76 *
77 *  This subprogram initializes the MPCI driver by
78 *  invoking the user provided MPCI initialization callout.
79 */
80
81void _MPCI_Initialization ( void )
82{
[3a4ae6c]83  (*_MPCI_table->initialization)();
84}
85
86/*PAGE
87 *
88 *  _MPCI_Register_packet_processor
89 *
90 *  This routine registers the MPCI packet processor for the
91 *  designated object class.
92 */
93 
94void _MPCI_Register_packet_processor(
95  Objects_Classes        the_class,
96  MPCI_Packet_processor  the_packet_processor
97 
98)
99{
100  _MPCI_Packet_processors[ the_class ] = the_packet_processor;
[ac7d5ef0]101}
102
103/*PAGE
104 *
105 *  _MPCI_Get_packet
106 *
107 *  This subprogram obtains a packet by invoking the user provided
108 *  MPCI get packet callout.
109 */
110
[3a4ae6c]111MP_packet_Prefix *_MPCI_Get_packet ( void )
[ac7d5ef0]112{
[3a4ae6c]113  MP_packet_Prefix  *the_packet;
[ac7d5ef0]114
[3a4ae6c]115  (*_MPCI_table->get_packet)( &the_packet );
[ac7d5ef0]116
117  if ( the_packet == NULL )
[3a4ae6c]118    _Internal_error_Occurred(
119      INTERNAL_ERROR_CORE,
120      TRUE,
121      INTERNAL_ERROR_OUT_OF_PACKETS
122    );
[ac7d5ef0]123
124  /*
125   *  Put in a default timeout that will be used for
126   *  all packets that do not otherwise have a timeout.
127   */
128
129  the_packet->timeout = MPCI_DEFAULT_TIMEOUT;
130
131  return the_packet;
132}
133
134/*PAGE
135 *
136 *  _MPCI_Return_packet
137 *
138 *  This subprogram returns a packet by invoking the user provided
139 *  MPCI return packet callout.
140 */
141
142void _MPCI_Return_packet (
[3a4ae6c]143  MP_packet_Prefix   *the_packet
[ac7d5ef0]144)
145{
[3a4ae6c]146  (*_MPCI_table->return_packet)( the_packet );
[ac7d5ef0]147}
148
149/*PAGE
150 *
151 *  _MPCI_Send_process_packet
152 *
153 *  This subprogram sends a process packet by invoking the user provided
154 *  MPCI send callout.
155 */
156
157void _MPCI_Send_process_packet (
158  unsigned32          destination,
[3a4ae6c]159  MP_packet_Prefix   *the_packet
[ac7d5ef0]160)
161{
162  the_packet->source_tid = _Thread_Executing->Object.id;
163  the_packet->to_convert =
[3a4ae6c]164     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
[ac7d5ef0]165       sizeof(unsigned32);
166
[3a4ae6c]167  (*_MPCI_table->send_packet)( destination, the_packet );
[ac7d5ef0]168}
169
170/*PAGE
171 *
172 *  _MPCI_Send_request_packet
173 *
174 *  This subprogram sends a request packet by invoking the user provided
175 *  MPCI send callout.
176 */
177
[3a4ae6c]178unsigned32 _MPCI_Send_request_packet (
[ac7d5ef0]179  unsigned32          destination,
[3a4ae6c]180  MP_packet_Prefix   *the_packet,
[ac7d5ef0]181  States_Control      extra_state
182)
183{
184  the_packet->source_tid      = _Thread_Executing->Object.id;
185  the_packet->source_priority = _Thread_Executing->current_priority;
186  the_packet->to_convert =
[3a4ae6c]187     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
[ac7d5ef0]188       sizeof(unsigned32);
189
190  _Thread_Executing->Wait.id = the_packet->id;
191
192  _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads;
193
194  _Thread_Disable_dispatch();
195
[3a4ae6c]196    (*_MPCI_table->send_packet)( destination, the_packet );
[ac7d5ef0]197
198    _MPCI_Remote_blocked_threads.sync = TRUE;
199
200    /*
201     *  See if we need a default timeout
202     */
203
204    if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT)
[3a4ae6c]205        the_packet->timeout = _MPCI_table->default_timeout;
[ac7d5ef0]206
207    _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout );
208
209    _Thread_Executing->current_state =
210      _States_Set( extra_state, _Thread_Executing->current_state );
211
212  _Thread_Enable_dispatch();
213
214  return _Thread_Executing->Wait.return_code;
215}
216
217/*PAGE
218 *
219 *  _MPCI_Send_response_packet
220 *
221 *  This subprogram sends a response packet by invoking the user provided
222 *  MPCI send callout.
223 */
224
225void _MPCI_Send_response_packet (
226  unsigned32          destination,
[3a4ae6c]227  MP_packet_Prefix   *the_packet
[ac7d5ef0]228)
229{
230  the_packet->source_tid = _Thread_Executing->Object.id;
231
[3a4ae6c]232  (*_MPCI_table->send_packet)( destination, the_packet );
[ac7d5ef0]233}
234
235/*PAGE
236 *
237 *  _MPCI_Receive_packet
238 *
239 *  This subprogram receives a packet by invoking the user provided
240 *  MPCI receive callout.
241 */
242
[3a4ae6c]243MP_packet_Prefix  *_MPCI_Receive_packet ( void )
[ac7d5ef0]244{
[3a4ae6c]245  MP_packet_Prefix  *the_packet;
[ac7d5ef0]246
[3a4ae6c]247  (*_MPCI_table->receive_packet)( &the_packet );
[ac7d5ef0]248
249  return the_packet;
250}
251
252/*PAGE
253 *
254 *  _MPCI_Process_response
255 *
256 *  This subprogram obtains a packet by invoking the user provided
257 *  MPCI get packet callout.
258 */
259
260Thread_Control *_MPCI_Process_response (
[3a4ae6c]261  MP_packet_Prefix  *the_packet
[ac7d5ef0]262)
263{
264  Thread_Control    *the_thread;
265  Objects_Locations  location;
266
267  the_thread = _Thread_Get( the_packet->id, &location );
268  switch ( location ) {
269    case OBJECTS_ERROR:
270    case OBJECTS_REMOTE:
271      the_thread = NULL;          /* IMPOSSIBLE */
272      break;
273    case OBJECTS_LOCAL:
274      _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread );
275      the_thread->Wait.return_code = the_packet->return_code;
276      _Thread_Unnest_dispatch();
277    break;
278  }
279
280  return the_thread;
281}
282
[3a4ae6c]283/*PAGE
284 *
285 *  _MPCI_Receive_server
286 *
287 */
288
289void _MPCI_Receive_server( void )
290{
291 
292  MP_packet_Prefix         *the_packet;
293  MPCI_Packet_processor     the_function;
294  Thread_Control           *executing;
295 
296  executing = _Thread_Executing;
297  _MPCI_Receive_server_tcb = executing;
298
299  for ( ; ; ) {
300 
301    executing->receive_packet = NULL;
302
303    _Thread_Disable_dispatch();
304    _CORE_semaphore_Seize( &_MPCI_Semaphore, 0, TRUE, WATCHDOG_NO_TIMEOUT );
305    _Thread_Enable_dispatch();
306 
307    for ( ; ; ) {
308      the_packet = _MPCI_Receive_packet();
309 
310      if ( !the_packet )
311        break;
312 
313      executing->receive_packet = the_packet;
314 
315      if ( !_Mp_packet_Is_valid_packet_class ( the_packet->the_class ) )
316        break;
317 
318      the_function = _MPCI_Packet_processors[ the_packet->the_class ];
319 
320      if ( !the_function )
321        _Internal_error_Occurred(
322          INTERNAL_ERROR_CORE,
323          TRUE,
324          INTERNAL_ERROR_BAD_PACKET
325        );
326 
327        (*the_function)( the_packet );
328    }
329  }
330}
331
332/*PAGE
333 *
334 *  _MPCI_Announce
335 *
336 */
337 
338void _MPCI_Announce ( void )
339{
340  _Thread_Disable_dispatch();
341  (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, 0, 0 );
342  _Thread_Enable_dispatch();
343}
344
[ac7d5ef0]345/* end of file */
Note: See TracBrowser for help on using the repository browser.