source: rtems/cpukit/rtems/src/taskmp.c @ 66cb142

Last change on this file since 66cb142 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 RTEMS Tasks MP Send Process Packet
5 * @ingroup ClassicTaskMP Task 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/tasksimpl.h>
22#include <rtems/rtems/optionsimpl.h>
23#include <rtems/rtems/statusimpl.h>
24#include <rtems/score/statesimpl.h>
25#include <rtems/score/threadimpl.h>
26#include <rtems/score/threadqimpl.h>
27
28/**
29 *  The following data structure defines the packet used to perform
30 *  remote task operations.
31 */
32typedef struct {
33  rtems_packet_prefix               Prefix;
34  RTEMS_tasks_MP_Remote_operations  operation;
35  rtems_name                        name;
36  rtems_task_priority               the_priority;
37}   RTEMS_tasks_MP_Packet;
38
39RTEMS_STATIC_ASSERT(
40  sizeof(RTEMS_tasks_MP_Packet) <= MP_PACKET_MINIMUM_PACKET_SIZE,
41  RTEMS_tasks_MP_Packet
42);
43
44static RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet( void )
45{
46  return (RTEMS_tasks_MP_Packet *) _MPCI_Get_packet();
47}
48
49static RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_request_packet(
50  Objects_Id id
51)
52{
53  if ( !_Thread_MP_Is_remote( id ) ) {
54    return NULL;
55  }
56
57  return _RTEMS_tasks_MP_Get_packet();
58}
59
60/*
61 *  _RTEMS_tasks_MP_Send_process_packet
62 *
63 */
64
65void _RTEMS_tasks_MP_Send_process_packet (
66  RTEMS_tasks_MP_Remote_operations operation,
67  Objects_Id                       task_id,
68  rtems_name                       name
69)
70{
71  RTEMS_tasks_MP_Packet *the_packet;
72
73  switch ( operation ) {
74
75    case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
76    case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
77
78      the_packet                    = _RTEMS_tasks_MP_Get_packet();
79      the_packet->Prefix.the_class  = MP_PACKET_TASKS;
80      the_packet->Prefix.length     = sizeof ( RTEMS_tasks_MP_Packet );
81      the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet );
82      the_packet->operation         = operation;
83      the_packet->Prefix.id         = task_id;
84      the_packet->name              = name;
85
86      _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix );
87      break;
88
89    case RTEMS_TASKS_MP_SUSPEND_REQUEST:
90    case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
91    case RTEMS_TASKS_MP_RESUME_REQUEST:
92    case RTEMS_TASKS_MP_RESUME_RESPONSE:
93    case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
94    case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
95      break;
96  }
97}
98
99static rtems_status_code _RTEMS_tasks_MP_Send_request_packet(
100  RTEMS_tasks_MP_Packet            *the_packet,
101  Objects_Id                        id,
102  RTEMS_tasks_MP_Remote_operations  operation
103)
104{
105  Status_Control status;
106
107  the_packet->Prefix.the_class  = MP_PACKET_TASKS;
108  the_packet->Prefix.length     = sizeof( *the_packet );
109  the_packet->Prefix.to_convert = sizeof( *the_packet );
110  the_packet->Prefix.id         = id;
111  the_packet->operation         = operation;
112
113  status = _MPCI_Send_request_packet(
114    _Objects_Get_node( id ),
115    &the_packet->Prefix,
116    STATES_READY /* Not used */
117  );
118  return _Status_Get( status );
119}
120
121rtems_status_code _RTEMS_tasks_MP_Set_priority(
122  rtems_id             id,
123  rtems_task_priority  new_priority,
124  rtems_task_priority *old_priority
125)
126{
127  RTEMS_tasks_MP_Packet *the_packet;
128
129  the_packet = _RTEMS_tasks_MP_Get_request_packet( id );
130  if ( the_packet == NULL ) {
131    return RTEMS_INVALID_ID;
132  }
133
134  the_packet->the_priority = new_priority;
135  _Thread_Executing->Wait.return_argument = old_priority;
136  return _RTEMS_tasks_MP_Send_request_packet(
137    the_packet,
138    id,
139    RTEMS_TASKS_MP_SET_PRIORITY_REQUEST
140  );
141}
142
143rtems_status_code _RTEMS_tasks_MP_Suspend( rtems_id id )
144{
145  RTEMS_tasks_MP_Packet *the_packet;
146
147  the_packet = _RTEMS_tasks_MP_Get_request_packet( id );
148  if ( the_packet == NULL ) {
149    return RTEMS_INVALID_ID;
150  }
151
152  return _RTEMS_tasks_MP_Send_request_packet(
153    the_packet,
154    id,
155    RTEMS_TASKS_MP_SUSPEND_REQUEST
156  );
157}
158
159rtems_status_code _RTEMS_tasks_MP_Resume( rtems_id id )
160{
161  RTEMS_tasks_MP_Packet *the_packet;
162
163  the_packet = _RTEMS_tasks_MP_Get_request_packet( id );
164  if ( the_packet == NULL ) {
165    return RTEMS_INVALID_ID;
166  }
167
168  return _RTEMS_tasks_MP_Send_request_packet(
169    the_packet,
170    id,
171    RTEMS_TASKS_MP_RESUME_REQUEST
172  );
173}
174
175/*
176 *  _RTEMS_tasks_MP_Send_response_packet
177 *
178 */
179
180static void _RTEMS_tasks_MP_Send_response_packet (
181  RTEMS_tasks_MP_Remote_operations  operation,
182  Thread_Control                   *the_thread
183)
184{
185  RTEMS_tasks_MP_Packet *the_packet;
186
187  switch ( operation ) {
188
189    case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
190    case RTEMS_TASKS_MP_RESUME_RESPONSE:
191    case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
192
193      the_packet = (RTEMS_tasks_MP_Packet *) the_thread->receive_packet;
194
195/*
196 *  The packet being returned already contains the class, length, and
197 *  to_convert fields, therefore they are not set in this routine.
198 */
199      the_packet->operation    = operation;
200      the_packet->Prefix.id    = the_packet->Prefix.source_tid;
201
202      _MPCI_Send_response_packet(
203        _Objects_Get_node( the_packet->Prefix.source_tid ),
204        &the_packet->Prefix
205      );
206      break;
207
208    case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
209    case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
210    case RTEMS_TASKS_MP_SUSPEND_REQUEST:
211    case RTEMS_TASKS_MP_RESUME_REQUEST:
212    case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
213      break;
214
215  }
216}
217
218/*
219 *
220 *  _RTEMS_tasks_MP_Process_packet
221 *
222 */
223
224void _RTEMS_tasks_MP_Process_packet (
225  rtems_packet_prefix  *the_packet_prefix
226)
227{
228  RTEMS_tasks_MP_Packet *the_packet;
229  Thread_Control   *the_thread;
230
231  the_packet = (RTEMS_tasks_MP_Packet *) the_packet_prefix;
232
233  switch ( the_packet->operation ) {
234
235    case RTEMS_TASKS_MP_ANNOUNCE_CREATE:
236
237      _Objects_MP_Allocate_and_open(
238        &_RTEMS_tasks_Information.Objects,
239        the_packet->name,
240        the_packet->Prefix.id,
241        true
242      );
243
244      _MPCI_Return_packet( the_packet_prefix );
245      break;
246
247    case RTEMS_TASKS_MP_ANNOUNCE_DELETE:
248
249      _Objects_MP_Close(
250        &_RTEMS_tasks_Information.Objects,
251        the_packet->Prefix.id
252      );
253
254      _MPCI_Return_packet( the_packet_prefix );
255      break;
256
257    case RTEMS_TASKS_MP_SUSPEND_REQUEST:
258
259      the_packet->Prefix.return_code = rtems_task_suspend(
260        the_packet->Prefix.id
261      );
262
263      _RTEMS_tasks_MP_Send_response_packet(
264        RTEMS_TASKS_MP_SUSPEND_RESPONSE,
265        _Thread_Executing
266      );
267      break;
268
269    case RTEMS_TASKS_MP_SUSPEND_RESPONSE:
270    case RTEMS_TASKS_MP_RESUME_RESPONSE:
271
272      the_thread = _MPCI_Process_response( the_packet_prefix );
273
274      _MPCI_Return_packet( the_packet_prefix );
275      break;
276
277    case RTEMS_TASKS_MP_RESUME_REQUEST:
278
279      the_packet->Prefix.return_code = rtems_task_resume(
280        the_packet->Prefix.id
281      );
282
283      _RTEMS_tasks_MP_Send_response_packet(
284        RTEMS_TASKS_MP_RESUME_RESPONSE,
285        _Thread_Executing
286      );
287      break;
288
289    case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST:
290
291      the_packet->Prefix.return_code = rtems_task_set_priority(
292        the_packet->Prefix.id,
293        the_packet->the_priority,
294        &the_packet->the_priority
295      );
296
297      _RTEMS_tasks_MP_Send_response_packet(
298        RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE,
299        _Thread_Executing
300      );
301      break;
302
303    case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE:
304
305      the_thread = _MPCI_Process_response( the_packet_prefix );
306
307      *(rtems_task_priority *)the_thread->Wait.return_argument =
308                                               the_packet->the_priority;
309
310      _MPCI_Return_packet( the_packet_prefix );
311      break;
312  }
313}
314
315/*
316 *  _RTEMS_tasks_MP_Send_object_was_deleted
317 *
318 *  This routine is not neededby the Tasks since a task
319 *  cannot be globally deleted.
320 *
321 */
322
323/*
324 *  _RTEMS_tasks_MP_Send_extract_proxy
325 *
326 *  This routine is not neededby the Tasks since a task
327 *  cannot be globally deleted.
328 *
329 */
330
331/* end of file */
Note: See TracBrowser for help on using the repository browser.