source: rtems/cpukit/rtems/src/semmp.c @ dce48791

Last change on this file since dce48791 was dce48791, checked in by Sebastian Huber <sebastian.huber@…>, on May 23, 2016 at 11:37:59 AM

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.8 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Semaphore MP Support
5 *  @ingroup ClassicSEM
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/semimpl.h>
22#include <rtems/rtems/optionsimpl.h>
23#include <rtems/rtems/statusimpl.h>
24
25RTEMS_STATIC_ASSERT(
26  sizeof(Semaphore_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
27  Semaphore_MP_Packet
28);
29
30static Semaphore_MP_Packet *_Semaphore_MP_Get_packet( void )
31{
32  return (Semaphore_MP_Packet *) _MPCI_Get_packet();
33}
34
35void _Semaphore_MP_Send_process_packet (
36  Semaphore_MP_Remote_operations  operation,
37  Objects_Id                      semaphore_id,
38  rtems_name                      name,
39  Objects_Id                      proxy_id
40)
41{
42  Semaphore_MP_Packet *the_packet;
43  uint32_t             node;
44
45  switch ( operation ) {
46
47    case SEMAPHORE_MP_ANNOUNCE_CREATE:
48    case SEMAPHORE_MP_ANNOUNCE_DELETE:
49    case SEMAPHORE_MP_EXTRACT_PROXY:
50
51      the_packet                    = _Semaphore_MP_Get_packet();
52      the_packet->Prefix.the_class  = MP_PACKET_SEMAPHORE;
53      the_packet->Prefix.length     = sizeof ( Semaphore_MP_Packet );
54      the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
55      the_packet->operation         = operation;
56      the_packet->Prefix.id         = semaphore_id;
57      the_packet->name              = name;
58      the_packet->proxy_id          = proxy_id;
59
60      if ( operation == SEMAPHORE_MP_EXTRACT_PROXY )
61         node = _Objects_Get_node( semaphore_id );
62      else
63         node = MPCI_ALL_NODES;
64
65      _MPCI_Send_process_packet( node, &the_packet->Prefix );
66      break;
67
68    case SEMAPHORE_MP_OBTAIN_REQUEST:
69    case SEMAPHORE_MP_OBTAIN_RESPONSE:
70    case SEMAPHORE_MP_RELEASE_REQUEST:
71    case SEMAPHORE_MP_RELEASE_RESPONSE:
72      break;
73  }
74}
75
76static rtems_status_code _Semaphore_MP_Send_request_packet(
77  Objects_Id                     semaphore_id,
78  rtems_option                   option_set,
79  rtems_interval                 timeout,
80  Semaphore_MP_Remote_operations operation
81)
82{
83  Semaphore_MP_Packet *the_packet;
84  Status_Control       status;
85
86  switch ( operation ) {
87
88    case SEMAPHORE_MP_OBTAIN_REQUEST:
89    case SEMAPHORE_MP_RELEASE_REQUEST:
90
91      the_packet                    = _Semaphore_MP_Get_packet();
92      the_packet->Prefix.the_class  = MP_PACKET_SEMAPHORE;
93      the_packet->Prefix.length     = sizeof ( Semaphore_MP_Packet );
94      the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
95      if ( ! _Options_Is_no_wait(option_set))
96          the_packet->Prefix.timeout = timeout;
97
98      the_packet->operation         = operation;
99      the_packet->Prefix.id         = semaphore_id;
100      the_packet->option_set        = option_set;
101
102      status = _MPCI_Send_request_packet(
103        _Objects_Get_node( semaphore_id ),
104        &the_packet->Prefix,
105        STATES_WAITING_FOR_SEMAPHORE
106      );
107      return _Status_Get( status );
108
109    case SEMAPHORE_MP_ANNOUNCE_CREATE:
110    case SEMAPHORE_MP_ANNOUNCE_DELETE:
111    case SEMAPHORE_MP_EXTRACT_PROXY:
112    case SEMAPHORE_MP_OBTAIN_RESPONSE:
113    case SEMAPHORE_MP_RELEASE_RESPONSE:
114      break;
115
116  }
117  /*
118   *  The following line is included to satisfy compilers which
119   *  produce warnings when a function does not end with a return.
120   */
121  return RTEMS_SUCCESSFUL;
122}
123
124rtems_status_code _Semaphore_MP_Obtain(
125  rtems_id        id,
126  rtems_option    option_set,
127  rtems_interval  timeout
128)
129{
130  return _Semaphore_MP_Send_request_packet(
131    id,
132    option_set,
133    timeout,
134    SEMAPHORE_MP_OBTAIN_REQUEST
135  );
136}
137
138rtems_status_code _Semaphore_MP_Release( rtems_id id )
139{
140  return _Semaphore_MP_Send_request_packet(
141    id,
142    0,
143    MPCI_DEFAULT_TIMEOUT,
144    SEMAPHORE_MP_RELEASE_REQUEST
145  );
146}
147
148static void _Semaphore_MP_Send_response_packet (
149  Semaphore_MP_Remote_operations  operation,
150  Objects_Id                      semaphore_id,
151  Thread_Control                 *the_thread
152)
153{
154  Semaphore_MP_Packet *the_packet;
155
156  switch ( operation ) {
157
158    case SEMAPHORE_MP_OBTAIN_RESPONSE:
159    case SEMAPHORE_MP_RELEASE_RESPONSE:
160
161      the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet;
162
163/*
164 *  The packet being returned already contains the class, length, and
165 *  to_convert fields, therefore they are not set in this routine.
166 */
167      the_packet->operation = operation;
168      the_packet->Prefix.id = the_packet->Prefix.source_tid;
169
170      _MPCI_Send_response_packet(
171        _Objects_Get_node( the_packet->Prefix.source_tid ),
172        &the_packet->Prefix
173      );
174      break;
175
176    case SEMAPHORE_MP_ANNOUNCE_CREATE:
177    case SEMAPHORE_MP_ANNOUNCE_DELETE:
178    case SEMAPHORE_MP_EXTRACT_PROXY:
179    case SEMAPHORE_MP_OBTAIN_REQUEST:
180    case SEMAPHORE_MP_RELEASE_REQUEST:
181      break;
182
183  }
184}
185
186void _Semaphore_MP_Process_packet (
187  rtems_packet_prefix  *the_packet_prefix
188)
189{
190  Semaphore_MP_Packet *the_packet;
191  Thread_Control      *the_thread;
192
193  the_packet = (Semaphore_MP_Packet *) the_packet_prefix;
194
195  switch ( the_packet->operation ) {
196
197    case SEMAPHORE_MP_ANNOUNCE_CREATE:
198
199      _Objects_MP_Allocate_and_open(
200        &_Semaphore_Information,
201        the_packet->name,
202        the_packet->Prefix.id,
203        true
204      );
205
206      _MPCI_Return_packet( the_packet_prefix );
207      break;
208
209    case SEMAPHORE_MP_ANNOUNCE_DELETE:
210
211      _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id );
212
213      _MPCI_Return_packet( the_packet_prefix );
214      break;
215
216    case SEMAPHORE_MP_EXTRACT_PROXY:
217
218      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
219
220      if ( ! _Thread_Is_null( the_thread ) )
221        _Thread_queue_Extract( the_thread );
222
223      _MPCI_Return_packet( the_packet_prefix );
224      break;
225
226    case SEMAPHORE_MP_OBTAIN_REQUEST:
227
228      the_packet->Prefix.return_code = rtems_semaphore_obtain(
229        the_packet->Prefix.id,
230        the_packet->option_set,
231        the_packet->Prefix.timeout
232      );
233
234      if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
235        _Semaphore_MP_Send_response_packet(
236           SEMAPHORE_MP_OBTAIN_RESPONSE,
237           the_packet->Prefix.id,
238           _Thread_Executing
239        );
240      break;
241
242    case SEMAPHORE_MP_OBTAIN_RESPONSE:
243    case SEMAPHORE_MP_RELEASE_RESPONSE:
244
245      the_thread = _MPCI_Process_response( the_packet_prefix );
246
247      _MPCI_Return_packet( the_packet_prefix );
248      break;
249
250    case SEMAPHORE_MP_RELEASE_REQUEST:
251
252      the_packet->Prefix.return_code = rtems_semaphore_release(
253        the_packet->Prefix.id
254      );
255
256      _Semaphore_MP_Send_response_packet(
257        SEMAPHORE_MP_RELEASE_RESPONSE,
258        the_packet->Prefix.id,
259        _Thread_Executing
260      );
261      break;
262  }
263}
264
265void _Semaphore_MP_Send_object_was_deleted (
266  Thread_Control *the_proxy,
267  Objects_Id      mp_id
268)
269{
270  the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
271
272  _Semaphore_MP_Send_response_packet(
273    SEMAPHORE_MP_OBTAIN_RESPONSE,
274    mp_id,
275    the_proxy
276  );
277
278}
279
280void _Semaphore_MP_Send_extract_proxy (
281  Thread_Control *the_thread,
282  Objects_Id      id
283)
284{
285  _Semaphore_MP_Send_process_packet(
286    SEMAPHORE_MP_EXTRACT_PROXY,
287    id,
288    (rtems_name) 0,
289    the_thread->Object.id
290  );
291
292}
293
294#if defined(RTEMS_MULTIPROCESSING)
295void  _Semaphore_Core_mutex_mp_support (
296  Thread_Control *the_thread,
297  Objects_Id      id
298)
299{
300  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
301
302  _Semaphore_MP_Send_response_packet(
303     SEMAPHORE_MP_OBTAIN_RESPONSE,
304     id,
305     the_thread
306   );
307}
308#endif
309
310#if defined(RTEMS_MULTIPROCESSING)
311void  _Semaphore_Core_semaphore_mp_support (
312  Thread_Control *the_thread,
313  Objects_Id      id
314)
315{
316  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
317
318  _Semaphore_MP_Send_response_packet(
319     SEMAPHORE_MP_OBTAIN_RESPONSE,
320     id,
321     the_thread
322   );
323}
324#endif
325/* end of file */
Note: See TracBrowser for help on using the repository browser.