source: rtems/cpukit/score/src/mpci.c @ 79aaec8

4.104.114.84.95
Last change on this file since 79aaec8 was be650a84, checked in by Joel Sherrill <joel.sherrill@…>, on 09/21/95 at 16:22:25

moving files around

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