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 Sep 21, 1995 at 5:58:58 PM

More file movement

  • Property mode set to 100644
File size: 7.4 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/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>
26#include <rtems/core/sysstate.h>
27
28#include <rtems/core/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  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
63  _Thread_queue_Initialize(
64    &_MPCI_Remote_blocked_threads,
65    OBJECTS_NO_CLASS,
66    THREAD_QUEUE_DISCIPLINE_FIFO,
67    STATES_WAITING_FOR_RPC_REPLY,
68    NULL,
69    timeout_status
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{
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;
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
111MP_packet_Prefix *_MPCI_Get_packet ( void )
112{
113  MP_packet_Prefix  *the_packet;
114
115  (*_MPCI_table->get_packet)( &the_packet );
116
117  if ( the_packet == NULL )
118    _Internal_error_Occurred(
119      INTERNAL_ERROR_CORE,
120      TRUE,
121      INTERNAL_ERROR_OUT_OF_PACKETS
122    );
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 (
143  MP_packet_Prefix   *the_packet
144)
145{
146  (*_MPCI_table->return_packet)( the_packet );
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,
159  MP_packet_Prefix   *the_packet
160)
161{
162  the_packet->source_tid = _Thread_Executing->Object.id;
163  the_packet->to_convert =
164     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
165       sizeof(unsigned32);
166
167  (*_MPCI_table->send_packet)( destination, the_packet );
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
178unsigned32 _MPCI_Send_request_packet (
179  unsigned32          destination,
180  MP_packet_Prefix   *the_packet,
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 =
187     ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) /
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
196    (*_MPCI_table->send_packet)( destination, the_packet );
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)
205        the_packet->timeout = _MPCI_table->default_timeout;
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,
227  MP_packet_Prefix   *the_packet
228)
229{
230  the_packet->source_tid = _Thread_Executing->Object.id;
231
232  (*_MPCI_table->send_packet)( destination, the_packet );
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
243MP_packet_Prefix  *_MPCI_Receive_packet ( void )
244{
245  MP_packet_Prefix  *the_packet;
246
247  (*_MPCI_table->receive_packet)( &the_packet );
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 (
261  MP_packet_Prefix  *the_packet
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
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
345/* end of file */
Note: See TracBrowser for help on using the repository browser.