source: rtems/cpukit/rtems/src/semmp.c @ 0a75a4aa

Last change on this file since 0a75a4aa was 6378978, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 26, 2018 at 9:14:00 AM

rtems: Fix semaphore MPCI support

  • Property mode set to 100644
File size: 7.9 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  if ( !_Semaphore_MP_Is_remote( semaphore_id ) ) {
87    return RTEMS_INVALID_ID;
88  }
89
90  switch ( operation ) {
91
92    case SEMAPHORE_MP_OBTAIN_REQUEST:
93    case SEMAPHORE_MP_RELEASE_REQUEST:
94
95      the_packet                    = _Semaphore_MP_Get_packet();
96      the_packet->Prefix.the_class  = MP_PACKET_SEMAPHORE;
97      the_packet->Prefix.length     = sizeof ( Semaphore_MP_Packet );
98      the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet );
99      if ( ! _Options_Is_no_wait(option_set))
100          the_packet->Prefix.timeout = timeout;
101
102      the_packet->operation         = operation;
103      the_packet->Prefix.id         = semaphore_id;
104      the_packet->option_set        = option_set;
105
106      status = _MPCI_Send_request_packet(
107        _Objects_Get_node( semaphore_id ),
108        &the_packet->Prefix,
109        STATES_WAITING_FOR_SEMAPHORE
110      );
111      return _Status_Get( status );
112
113    case SEMAPHORE_MP_ANNOUNCE_CREATE:
114    case SEMAPHORE_MP_ANNOUNCE_DELETE:
115    case SEMAPHORE_MP_EXTRACT_PROXY:
116    case SEMAPHORE_MP_OBTAIN_RESPONSE:
117    case SEMAPHORE_MP_RELEASE_RESPONSE:
118      break;
119
120  }
121  /*
122   *  The following line is included to satisfy compilers which
123   *  produce warnings when a function does not end with a return.
124   */
125  return RTEMS_SUCCESSFUL;
126}
127
128rtems_status_code _Semaphore_MP_Obtain(
129  rtems_id        id,
130  rtems_option    option_set,
131  rtems_interval  timeout
132)
133{
134  return _Semaphore_MP_Send_request_packet(
135    id,
136    option_set,
137    timeout,
138    SEMAPHORE_MP_OBTAIN_REQUEST
139  );
140}
141
142rtems_status_code _Semaphore_MP_Release( rtems_id id )
143{
144  return _Semaphore_MP_Send_request_packet(
145    id,
146    0,
147    MPCI_DEFAULT_TIMEOUT,
148    SEMAPHORE_MP_RELEASE_REQUEST
149  );
150}
151
152static void _Semaphore_MP_Send_response_packet (
153  Semaphore_MP_Remote_operations  operation,
154  Objects_Id                      semaphore_id,
155  Thread_Control                 *the_thread
156)
157{
158  Semaphore_MP_Packet *the_packet;
159
160  switch ( operation ) {
161
162    case SEMAPHORE_MP_OBTAIN_RESPONSE:
163    case SEMAPHORE_MP_RELEASE_RESPONSE:
164
165      the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet;
166
167/*
168 *  The packet being returned already contains the class, length, and
169 *  to_convert fields, therefore they are not set in this routine.
170 */
171      the_packet->operation = operation;
172      the_packet->Prefix.id = the_packet->Prefix.source_tid;
173
174      _MPCI_Send_response_packet(
175        _Objects_Get_node( the_packet->Prefix.source_tid ),
176        &the_packet->Prefix
177      );
178      break;
179
180    case SEMAPHORE_MP_ANNOUNCE_CREATE:
181    case SEMAPHORE_MP_ANNOUNCE_DELETE:
182    case SEMAPHORE_MP_EXTRACT_PROXY:
183    case SEMAPHORE_MP_OBTAIN_REQUEST:
184    case SEMAPHORE_MP_RELEASE_REQUEST:
185      break;
186
187  }
188}
189
190void _Semaphore_MP_Process_packet (
191  rtems_packet_prefix  *the_packet_prefix
192)
193{
194  Semaphore_MP_Packet *the_packet;
195  Thread_Control      *the_thread;
196
197  the_packet = (Semaphore_MP_Packet *) the_packet_prefix;
198
199  switch ( the_packet->operation ) {
200
201    case SEMAPHORE_MP_ANNOUNCE_CREATE:
202
203      _Objects_MP_Allocate_and_open(
204        &_Semaphore_Information,
205        the_packet->name,
206        the_packet->Prefix.id,
207        true
208      );
209
210      _MPCI_Return_packet( the_packet_prefix );
211      break;
212
213    case SEMAPHORE_MP_ANNOUNCE_DELETE:
214
215      _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id );
216
217      _MPCI_Return_packet( the_packet_prefix );
218      break;
219
220    case SEMAPHORE_MP_EXTRACT_PROXY:
221
222      the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id );
223
224      if ( ! _Thread_Is_null( the_thread ) )
225        _Thread_queue_Extract( the_thread );
226
227      _MPCI_Return_packet( the_packet_prefix );
228      break;
229
230    case SEMAPHORE_MP_OBTAIN_REQUEST:
231
232      the_packet->Prefix.return_code = rtems_semaphore_obtain(
233        the_packet->Prefix.id,
234        the_packet->option_set,
235        the_packet->Prefix.timeout
236      );
237
238      if ( the_packet->Prefix.return_code != RTEMS_PROXY_BLOCKING )
239        _Semaphore_MP_Send_response_packet(
240           SEMAPHORE_MP_OBTAIN_RESPONSE,
241           the_packet->Prefix.id,
242           _Thread_Executing
243        );
244      break;
245
246    case SEMAPHORE_MP_OBTAIN_RESPONSE:
247    case SEMAPHORE_MP_RELEASE_RESPONSE:
248
249      the_thread = _MPCI_Process_response( the_packet_prefix );
250
251      _MPCI_Return_packet( the_packet_prefix );
252      break;
253
254    case SEMAPHORE_MP_RELEASE_REQUEST:
255
256      the_packet->Prefix.return_code = rtems_semaphore_release(
257        the_packet->Prefix.id
258      );
259
260      _Semaphore_MP_Send_response_packet(
261        SEMAPHORE_MP_RELEASE_RESPONSE,
262        the_packet->Prefix.id,
263        _Thread_Executing
264      );
265      break;
266  }
267}
268
269void _Semaphore_MP_Send_object_was_deleted (
270  Thread_Control *the_proxy,
271  Objects_Id      mp_id
272)
273{
274  the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED;
275
276  _Semaphore_MP_Send_response_packet(
277    SEMAPHORE_MP_OBTAIN_RESPONSE,
278    mp_id,
279    the_proxy
280  );
281
282}
283
284void _Semaphore_MP_Send_extract_proxy (
285  Thread_Control *the_thread,
286  Objects_Id      id
287)
288{
289  _Semaphore_MP_Send_process_packet(
290    SEMAPHORE_MP_EXTRACT_PROXY,
291    id,
292    (rtems_name) 0,
293    the_thread->Object.id
294  );
295
296}
297
298#if defined(RTEMS_MULTIPROCESSING)
299void  _Semaphore_Core_mutex_mp_support (
300  Thread_Control *the_thread,
301  Objects_Id      id
302)
303{
304  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
305
306  _Semaphore_MP_Send_response_packet(
307     SEMAPHORE_MP_OBTAIN_RESPONSE,
308     id,
309     the_thread
310   );
311}
312#endif
313
314#if defined(RTEMS_MULTIPROCESSING)
315void  _Semaphore_Core_semaphore_mp_support (
316  Thread_Control *the_thread,
317  Objects_Id      id
318)
319{
320  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
321
322  _Semaphore_MP_Send_response_packet(
323     SEMAPHORE_MP_OBTAIN_RESPONSE,
324     id,
325     the_thread
326   );
327}
328#endif
329/* end of file */
Note: See TracBrowser for help on using the repository browser.