source: rtems/cpukit/rtems/src/taskmp.c @ 4d76300a

5
Last change on this file since 4d76300a was 4d76300a, checked in by Sebastian Huber <sebastian.huber@…>, on 05/11/16 at 08:21:57

rtems: Avoid Giant lock for some task operations

Avoid Giant lock for rtems_task_set_priority(), rtems_task_suspend() and
rtems_task_resume().

Update #2555.

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