source: rtems/cpukit/include/rtems/score/mrspimpl.h @ 21275b58

5
Last change on this file since 21275b58 was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Copyright (c) 2014, 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifndef _RTEMS_SCORE_MRSPIMPL_H
16#define _RTEMS_SCORE_MRSPIMPL_H
17
18#include <rtems/score/mrsp.h>
19
20#if defined(RTEMS_SMP)
21
22#include <rtems/score/assert.h>
23#include <rtems/score/status.h>
24#include <rtems/score/threadqimpl.h>
25#include <rtems/score/watchdogimpl.h>
26#include <rtems/score/wkspace.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif /* __cplusplus */
31
32/**
33 * @addtogroup ScoreMRSP
34 *
35 * @{
36 */
37
38#define MRSP_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit
39
40RTEMS_INLINE_ROUTINE void _MRSP_Acquire_critical(
41  MRSP_Control         *mrsp,
42  Thread_queue_Context *queue_context
43)
44{
45  _Thread_queue_Acquire_critical( &mrsp->Wait_queue, queue_context );
46}
47
48RTEMS_INLINE_ROUTINE void _MRSP_Release(
49  MRSP_Control         *mrsp,
50  Thread_queue_Context *queue_context
51)
52{
53  _Thread_queue_Release( &mrsp->Wait_queue, queue_context );
54}
55
56RTEMS_INLINE_ROUTINE Thread_Control *_MRSP_Get_owner(
57  const MRSP_Control *mrsp
58)
59{
60  return mrsp->Wait_queue.Queue.owner;
61}
62
63RTEMS_INLINE_ROUTINE void _MRSP_Set_owner(
64  MRSP_Control   *mrsp,
65  Thread_Control *owner
66)
67{
68  mrsp->Wait_queue.Queue.owner = owner;
69}
70
71RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_priority(
72  const MRSP_Control      *mrsp,
73  const Scheduler_Control *scheduler
74)
75{
76  uint32_t scheduler_index;
77
78  scheduler_index = _Scheduler_Get_index( scheduler );
79  return mrsp->ceiling_priorities[ scheduler_index ];
80}
81
82RTEMS_INLINE_ROUTINE void _MRSP_Set_priority(
83  MRSP_Control            *mrsp,
84  const Scheduler_Control *scheduler,
85  Priority_Control         new_priority
86)
87{
88  uint32_t scheduler_index;
89
90  scheduler_index = _Scheduler_Get_index( scheduler );
91  mrsp->ceiling_priorities[ scheduler_index ] = new_priority;
92}
93
94RTEMS_INLINE_ROUTINE Status_Control _MRSP_Raise_priority(
95  MRSP_Control         *mrsp,
96  Thread_Control       *thread,
97  Priority_Node        *priority_node,
98  Thread_queue_Context *queue_context
99)
100{
101  Status_Control           status;
102  ISR_lock_Context         lock_context;
103  const Scheduler_Control *scheduler;
104  Priority_Control         ceiling_priority;
105  Scheduler_Node          *scheduler_node;
106
107  _Thread_queue_Context_clear_priority_updates( queue_context );
108  _Thread_Wait_acquire_default_critical( thread, &lock_context );
109
110  scheduler = _Thread_Scheduler_get_home( thread );
111  scheduler_node = _Thread_Scheduler_get_home_node( thread );
112  ceiling_priority = _MRSP_Get_priority( mrsp, scheduler );
113
114  if (
115    ceiling_priority
116      <= _Priority_Get_priority( &scheduler_node->Wait.Priority )
117  ) {
118    _Priority_Node_initialize( priority_node, ceiling_priority );
119    _Thread_Priority_add( thread, priority_node, queue_context );
120    status = STATUS_SUCCESSFUL;
121  } else {
122    status = STATUS_MUTEX_CEILING_VIOLATED;
123  }
124
125  _Thread_Wait_release_default_critical( thread, &lock_context );
126  return status;
127}
128
129RTEMS_INLINE_ROUTINE void _MRSP_Remove_priority(
130  Thread_Control       *thread,
131  Priority_Node        *priority_node,
132  Thread_queue_Context *queue_context
133)
134{
135  ISR_lock_Context lock_context;
136
137  _Thread_queue_Context_clear_priority_updates( queue_context );
138  _Thread_Wait_acquire_default_critical( thread, &lock_context );
139  _Thread_Priority_remove( thread, priority_node, queue_context );
140  _Thread_Wait_release_default_critical( thread, &lock_context );
141}
142
143RTEMS_INLINE_ROUTINE void _MRSP_Replace_priority(
144  MRSP_Control   *mrsp,
145  Thread_Control *thread,
146  Priority_Node  *ceiling_priority
147)
148{
149  ISR_lock_Context lock_context;
150
151  _Thread_Wait_acquire_default( thread, &lock_context );
152  _Thread_Priority_replace(
153    thread,
154    ceiling_priority,
155    &mrsp->Ceiling_priority
156  );
157  _Thread_Wait_release_default( thread, &lock_context );
158}
159
160RTEMS_INLINE_ROUTINE Status_Control _MRSP_Claim_ownership(
161  MRSP_Control         *mrsp,
162  Thread_Control       *executing,
163  Thread_queue_Context *queue_context
164)
165{
166  Status_Control   status;
167  Per_CPU_Control *cpu_self;
168
169  status = _MRSP_Raise_priority(
170    mrsp,
171    executing,
172    &mrsp->Ceiling_priority,
173    queue_context
174  );
175
176  if ( status != STATUS_SUCCESSFUL ) {
177    _MRSP_Release( mrsp, queue_context );
178    return status;
179  }
180
181  _MRSP_Set_owner( mrsp, executing );
182  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
183  _MRSP_Release( mrsp, queue_context );
184  _Thread_Priority_and_sticky_update( executing, 1 );
185  _Thread_Dispatch_enable( cpu_self );
186  return STATUS_SUCCESSFUL;
187}
188
189RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
190  MRSP_Control            *mrsp,
191  const Scheduler_Control *scheduler,
192  Priority_Control         ceiling_priority,
193  Thread_Control          *executing,
194  bool                     initially_locked
195)
196{
197  uint32_t scheduler_count = _Scheduler_Count;
198  uint32_t i;
199
200  if ( initially_locked ) {
201    return STATUS_INVALID_NUMBER;
202  }
203
204  mrsp->ceiling_priorities = _Workspace_Allocate(
205    sizeof( *mrsp->ceiling_priorities ) * scheduler_count
206  );
207  if ( mrsp->ceiling_priorities == NULL ) {
208    return STATUS_NO_MEMORY;
209  }
210
211  for ( i = 0 ; i < scheduler_count ; ++i ) {
212    const Scheduler_Control *scheduler_of_index;
213
214    scheduler_of_index = &_Scheduler_Table[ i ];
215
216    if ( scheduler != scheduler_of_index ) {
217      mrsp->ceiling_priorities[ i ] =
218        _Scheduler_Map_priority( scheduler_of_index, 0 );
219    } else {
220      mrsp->ceiling_priorities[ i ] = ceiling_priority;
221    }
222  }
223
224  _Thread_queue_Object_initialize( &mrsp->Wait_queue );
225  return STATUS_SUCCESSFUL;
226}
227
228RTEMS_INLINE_ROUTINE Status_Control _MRSP_Wait_for_ownership(
229  MRSP_Control         *mrsp,
230  Thread_Control       *executing,
231  Thread_queue_Context *queue_context
232)
233{
234  Status_Control status;
235  Priority_Node  ceiling_priority;
236
237  status = _MRSP_Raise_priority(
238    mrsp,
239    executing,
240    &ceiling_priority,
241    queue_context
242  );
243
244  if ( status != STATUS_SUCCESSFUL ) {
245    _MRSP_Release( mrsp, queue_context );
246    return status;
247  }
248
249  _Thread_queue_Context_set_deadlock_callout(
250    queue_context,
251    _Thread_queue_Deadlock_status
252  );
253  status = _Thread_queue_Enqueue_sticky(
254    &mrsp->Wait_queue.Queue,
255    MRSP_TQ_OPERATIONS,
256    executing,
257    queue_context
258  );
259
260  if ( status == STATUS_SUCCESSFUL ) {
261    _MRSP_Replace_priority( mrsp, executing, &ceiling_priority );
262  } else {
263    Thread_queue_Context  queue_context;
264    Per_CPU_Control      *cpu_self;
265    int                   sticky_level_change;
266
267    if ( status != STATUS_DEADLOCK ) {
268      sticky_level_change = -1;
269    } else {
270      sticky_level_change = 0;
271    }
272
273    _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
274    _MRSP_Remove_priority( executing, &ceiling_priority, &queue_context );
275    cpu_self = _Thread_Dispatch_disable_critical(
276      &queue_context.Lock_context.Lock_context
277    );
278    _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
279    _Thread_Priority_and_sticky_update( executing, sticky_level_change );
280    _Thread_Dispatch_enable( cpu_self );
281  }
282
283  return status;
284}
285
286RTEMS_INLINE_ROUTINE Status_Control _MRSP_Seize(
287  MRSP_Control         *mrsp,
288  Thread_Control       *executing,
289  bool                  wait,
290  Thread_queue_Context *queue_context
291)
292{
293  Status_Control  status;
294  Thread_Control *owner;
295
296  _MRSP_Acquire_critical( mrsp, queue_context );
297
298  owner = _MRSP_Get_owner( mrsp );
299
300  if ( owner == NULL ) {
301    status = _MRSP_Claim_ownership( mrsp, executing, queue_context );
302  } else if ( owner == executing ) {
303    _MRSP_Release( mrsp, queue_context );
304    status = STATUS_UNAVAILABLE;
305  } else if ( wait ) {
306    status = _MRSP_Wait_for_ownership( mrsp, executing, queue_context );
307  } else {
308    _MRSP_Release( mrsp, queue_context );
309    status = STATUS_UNAVAILABLE;
310  }
311
312  return status;
313}
314
315RTEMS_INLINE_ROUTINE Status_Control _MRSP_Surrender(
316  MRSP_Control         *mrsp,
317  Thread_Control       *executing,
318  Thread_queue_Context *queue_context
319)
320{
321  Thread_queue_Heads *heads;
322
323  if ( _MRSP_Get_owner( mrsp ) != executing ) {
324    _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
325    return STATUS_NOT_OWNER;
326  }
327
328  _MRSP_Acquire_critical( mrsp, queue_context );
329
330  _MRSP_Set_owner( mrsp, NULL );
331  _MRSP_Remove_priority( executing, &mrsp->Ceiling_priority, queue_context );
332
333  heads = mrsp->Wait_queue.Queue.heads;
334
335  if ( heads == NULL ) {
336    Per_CPU_Control *cpu_self;
337
338    cpu_self = _Thread_Dispatch_disable_critical(
339      &queue_context->Lock_context.Lock_context
340    );
341    _MRSP_Release( mrsp, queue_context );
342    _Thread_Priority_and_sticky_update( executing, -1 );
343    _Thread_Dispatch_enable( cpu_self );
344    return STATUS_SUCCESSFUL;
345  }
346
347  _Thread_queue_Surrender_sticky(
348    &mrsp->Wait_queue.Queue,
349    heads,
350    executing,
351    queue_context,
352    MRSP_TQ_OPERATIONS
353  );
354  return STATUS_SUCCESSFUL;
355}
356
357RTEMS_INLINE_ROUTINE Status_Control _MRSP_Can_destroy( MRSP_Control *mrsp )
358{
359  if ( _MRSP_Get_owner( mrsp ) != NULL ) {
360    return STATUS_RESOURCE_IN_USE;
361  }
362
363  return STATUS_SUCCESSFUL;
364}
365
366RTEMS_INLINE_ROUTINE void _MRSP_Destroy(
367  MRSP_Control         *mrsp,
368  Thread_queue_Context *queue_context
369)
370{
371  _MRSP_Release( mrsp, queue_context );
372  _Thread_queue_Destroy( &mrsp->Wait_queue );
373  _Workspace_Free( mrsp->ceiling_priorities );
374}
375
376/** @} */
377
378#ifdef __cplusplus
379}
380#endif /* __cplusplus */
381
382#endif /* RTEMS_SMP */
383
384#endif /* _RTEMS_SCORE_MRSPIMPL_H */
Note: See TracBrowser for help on using the repository browser.