source: rtems/cpukit/rtems/src/partmp.c @ 57c676c6

5
Last change on this file since 57c676c6 was dce48791, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/16 at 11:37:59

score: Add Status_Control for all APIs

Unify the status codes of the Classic and POSIX API to use the new enum
Status_Control. This eliminates the Thread_Control::Wait::timeout_code
field and the timeout parameter of _Thread_queue_Enqueue_critical() and
_MPCI_Send_request_packet(). It gets rid of the status code translation
tables and instead uses simple bit operations to get the status for a
particular API. This enables translation of status code constants at
compile time. Add _Thread_Wait_get_status() to avoid direct access of
thread internal data structures.

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief Partition_MP_Send_process_packet
5 * @ingroup ClassicPartMP Partition MP Support
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/rtems/partimpl.h>
22#include <rtems/rtems/statusimpl.h>
23#include <rtems/score/statesimpl.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/score/threadqimpl.h>
26
27RTEMS_STATIC_ASSERT(
28  sizeof(Partition_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
29  Partition_MP_Packet
30);
31
32static Partition_MP_Packet *_Partition_MP_Get_packet( void )
33{
34  return (Partition_MP_Packet *) _MPCI_Get_packet();
35}
36
37static void _Partition_MP_Initialize_packet(
38  Partition_MP_Packet            *the_packet,
39  Objects_Id                      id,
40  Partition_MP_Remote_operations  operation
41)
42{
43  the_packet->Prefix.the_class  = MP_PACKET_PARTITION;
44  the_packet->Prefix.length     = sizeof( *the_packet );
45  the_packet->Prefix.to_convert = sizeof( *the_packet );
46  the_packet->Prefix.id         = id;
47  the_packet->operation         = operation;
48}
49
50/*
51 *  _Partition_MP_Send_process_packet
52 *
53 */
54
55void _Partition_MP_Send_process_packet (
56  Partition_MP_Remote_operations  operation,
57  Objects_Id                      partition_id,
58  rtems_name                      name,
59  Objects_Id                      proxy_id
60)
61{
62  Partition_MP_Packet *the_packet;
63  uint32_t             node;
64
65  switch ( operation ) {
66
67    case PARTITION_MP_ANNOUNCE_CREATE:
68    case PARTITION_MP_ANNOUNCE_DELETE:
69    case PARTITION_MP_EXTRACT_PROXY:
70
71      the_packet = _Partition_MP_Get_packet();
72      _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
73      the_packet->name     = name;
74      the_packet->proxy_id = proxy_id;
75
76      if ( operation == PARTITION_MP_EXTRACT_PROXY )
77         node = _Objects_Get_node( partition_id );
78      else
79         node = MPCI_ALL_NODES;
80
81      _MPCI_Send_process_packet( node, &the_packet->Prefix );
82      break;
83
84    case PARTITION_MP_GET_BUFFER_REQUEST:
85    case PARTITION_MP_GET_BUFFER_RESPONSE:
86    case PARTITION_MP_RETURN_BUFFER_REQUEST:
87    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
88      break;
89  }
90}
91
92/*
93 *  _Partition_MP_Send_request_packet
94 *
95 */
96
97static rtems_status_code _Partition_MP_Send_request_packet (
98  Objects_Id                      partition_id,
99  void                           *buffer,
100  Partition_MP_Remote_operations  operation
101)
102{
103  Partition_MP_Packet *the_packet;
104  Status_Control       status;
105
106  if ( !_Partition_MP_Is_remote( partition_id ) ) {
107    return RTEMS_INVALID_ID;
108  }
109
110  switch ( operation ) {
111
112    case PARTITION_MP_GET_BUFFER_REQUEST:
113    case PARTITION_MP_RETURN_BUFFER_REQUEST:
114
115      the_packet = _Partition_MP_Get_packet();
116      _Partition_MP_Initialize_packet( the_packet, partition_id, operation );
117      the_packet->buffer = buffer;
118
119      status = _MPCI_Send_request_packet(
120        _Objects_Get_node( partition_id ),
121        &the_packet->Prefix,
122        STATES_READY /* Not used */
123      );
124      return _Status_Get( status );
125
126    case PARTITION_MP_ANNOUNCE_CREATE:
127    case PARTITION_MP_ANNOUNCE_DELETE:
128    case PARTITION_MP_EXTRACT_PROXY:
129    case PARTITION_MP_GET_BUFFER_RESPONSE:
130    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
131      break;
132
133  }
134  /*
135   *  The following line is included to satisfy compilers which
136   *  produce warnings when a function does not end with a return.
137   */
138  return RTEMS_SUCCESSFUL;
139}
140
141rtems_status_code _Partition_MP_Get_buffer(
142  rtems_id   id,
143  void     **buffer
144)
145{
146  _Thread_Get_executing()->Wait.return_argument = buffer;
147  return _Partition_MP_Send_request_packet(
148    id,
149    buffer,
150    PARTITION_MP_GET_BUFFER_REQUEST
151  );
152}
153
154rtems_status_code _Partition_MP_Return_buffer(
155  rtems_id  id,
156  void     *buffer
157)
158{
159  return _Partition_MP_Send_request_packet(
160    id,
161    buffer,
162    PARTITION_MP_RETURN_BUFFER_REQUEST
163  );
164}
165
166/*
167 *  _Partition_MP_Send_response_packet
168 *
169 */
170
171static void _Partition_MP_Send_response_packet (
172  Partition_MP_Remote_operations  operation,
173  Objects_Id                      partition_id,
174  Thread_Control                 *the_thread
175)
176{
177  Partition_MP_Packet *the_packet;
178
179  switch ( operation ) {
180
181    case PARTITION_MP_GET_BUFFER_RESPONSE:
182    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
183
184      the_packet = ( Partition_MP_Packet *) the_thread->receive_packet;
185
186/*
187 *  The packet being returned already contains the class, length, and
188 *  to_convert fields, therefore they are not set in this routine.
189 */
190      the_packet->operation = operation;
191      the_packet->Prefix.id = the_packet->Prefix.source_tid;
192
193      _MPCI_Send_response_packet(
194        _Objects_Get_node( the_packet->Prefix.source_tid ),
195        &the_packet->Prefix
196      );
197      break;
198
199    case PARTITION_MP_ANNOUNCE_CREATE:
200    case PARTITION_MP_ANNOUNCE_DELETE:
201    case PARTITION_MP_EXTRACT_PROXY:
202    case PARTITION_MP_GET_BUFFER_REQUEST:
203    case PARTITION_MP_RETURN_BUFFER_REQUEST:
204      break;
205
206  }
207}
208
209/*
210 *
211 *  _Partition_MP_Process_packet
212 *
213 */
214
215void _Partition_MP_Process_packet (
216  rtems_packet_prefix  *the_packet_prefix
217)
218{
219  Partition_MP_Packet *the_packet;
220  Thread_Control      *the_thread;
221
222  the_packet = (Partition_MP_Packet *) the_packet_prefix;
223
224  switch ( the_packet->operation ) {
225
226    case PARTITION_MP_ANNOUNCE_CREATE:
227
228      _Objects_MP_Allocate_and_open(
229        &_Partition_Information,
230        the_packet->name,
231        the_packet->Prefix.id,
232        true
233      );
234
235      _MPCI_Return_packet( the_packet_prefix );
236      break;
237
238    case PARTITION_MP_ANNOUNCE_DELETE:
239
240      _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id );
241
242      _MPCI_Return_packet( the_packet_prefix );
243      break;
244
245    case PARTITION_MP_EXTRACT_PROXY:
246
247      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
248
249      if ( ! _Thread_Is_null( the_thread ) )
250         _Thread_queue_Extract( the_thread );
251
252      _MPCI_Return_packet( the_packet_prefix );
253      break;
254
255    case PARTITION_MP_GET_BUFFER_REQUEST:
256
257      the_packet->Prefix.return_code = rtems_partition_get_buffer(
258        the_packet->Prefix.id,
259        &the_packet->buffer
260      );
261
262      _Partition_MP_Send_response_packet(
263        PARTITION_MP_GET_BUFFER_RESPONSE,
264        the_packet->Prefix.id,
265        _Thread_Executing
266      );
267      break;
268
269    case PARTITION_MP_GET_BUFFER_RESPONSE:
270
271      the_thread = _MPCI_Process_response( the_packet_prefix );
272
273      *(void **)the_thread->Wait.return_argument = the_packet->buffer;
274
275      _MPCI_Return_packet( the_packet_prefix );
276      break;
277
278    case PARTITION_MP_RETURN_BUFFER_REQUEST:
279
280      the_packet->Prefix.return_code = rtems_partition_return_buffer(
281        the_packet->Prefix.id,
282        the_packet->buffer
283      );
284
285      _Partition_MP_Send_response_packet(
286        PARTITION_MP_RETURN_BUFFER_RESPONSE,
287        the_packet->Prefix.id,
288        _Thread_Executing
289      );
290      break;
291
292    case PARTITION_MP_RETURN_BUFFER_RESPONSE:
293
294      the_thread = _MPCI_Process_response( the_packet_prefix );
295
296      _MPCI_Return_packet( the_packet_prefix );
297      break;
298
299  }
300}
301
302/*
303 *  _Partition_MP_Send_object_was_deleted
304 *
305 *  This routine is not needed by the Partition since a partition
306 *  cannot be deleted when buffers are in use.
307 *
308 */
309
310/*
311 *  _Partition_MP_Send_extract_proxy
312 *
313 */
314
315void _Partition_MP_Send_extract_proxy (
316  Thread_Control *the_thread,
317  Objects_Id      id
318)
319{
320  _Partition_MP_Send_process_packet(
321    PARTITION_MP_EXTRACT_PROXY,
322    id,
323    (rtems_name) 0,
324    the_thread->Object.id
325  );
326
327}
328
329/* end of file */
Note: See TracBrowser for help on using the repository browser.