source: rtems/cpukit/include/rtems/score/coremuteximpl.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: 11.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreMutex
5 *
6 * @brief CORE Mutex Implementation
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2009.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_COREMUTEXIMPL_H
19#define _RTEMS_SCORE_COREMUTEXIMPL_H
20
21#include <rtems/score/coremutex.h>
22#include <rtems/score/chainimpl.h>
23#include <rtems/score/schedulerimpl.h>
24#include <rtems/score/status.h>
25#include <rtems/score/threadimpl.h>
26#include <rtems/score/threadqimpl.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 * @addtogroup ScoreMutex
34 */
35/**@{**/
36
37#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
38
39#define CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS \
40  &_Thread_queue_Operations_priority_inherit
41
42RTEMS_INLINE_ROUTINE void _CORE_mutex_Initialize(
43  CORE_mutex_Control *the_mutex
44)
45{
46  _Thread_queue_Object_initialize( &the_mutex->Wait_queue );
47}
48
49RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
50{
51  _Thread_queue_Destroy( &the_mutex->Wait_queue );
52}
53
54RTEMS_INLINE_ROUTINE void _CORE_mutex_Acquire_critical(
55  CORE_mutex_Control   *the_mutex,
56  Thread_queue_Context *queue_context
57)
58{
59  _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, queue_context );
60}
61
62RTEMS_INLINE_ROUTINE void _CORE_mutex_Release(
63  CORE_mutex_Control   *the_mutex,
64  Thread_queue_Context *queue_context
65)
66{
67  _Thread_queue_Release( &the_mutex->Wait_queue, queue_context );
68}
69
70RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
71  const CORE_mutex_Control *the_mutex
72)
73{
74  return the_mutex->Wait_queue.Queue.owner;
75}
76
77/**
78 * @brief Is mutex locked.
79 *
80 * This routine returns true if the mutex specified is locked and false
81 * otherwise.
82 *
83 * @param[in] the_mutex is the mutex to check.
84 *
85 * @retval true The mutex is locked.
86 * @retval false The mutex is not locked.
87 */
88RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
89  const CORE_mutex_Control *the_mutex
90)
91{
92  return _CORE_mutex_Get_owner( the_mutex ) != NULL;
93}
94
95Status_Control _CORE_mutex_Seize_slow(
96  CORE_mutex_Control            *the_mutex,
97  const Thread_queue_Operations *operations,
98  Thread_Control                *executing,
99  bool                           wait,
100  Thread_queue_Context          *queue_context
101);
102
103RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
104  CORE_mutex_Control *the_mutex,
105  Thread_Control     *owner
106)
107{
108  the_mutex->Wait_queue.Queue.owner = owner;
109}
110
111RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
112  const CORE_mutex_Control *the_mutex,
113  const Thread_Control     *the_thread
114)
115{
116  return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
117}
118
119RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
120  CORE_recursive_mutex_Control *the_mutex
121)
122{
123  _CORE_mutex_Initialize( &the_mutex->Mutex );
124  the_mutex->nest_level = 0;
125}
126
127RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_nested(
128  CORE_recursive_mutex_Control *the_mutex
129)
130{
131  ++the_mutex->nest_level;
132  return STATUS_SUCCESSFUL;
133}
134
135RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize(
136  CORE_recursive_mutex_Control  *the_mutex,
137  const Thread_queue_Operations *operations,
138  Thread_Control                *executing,
139  bool                           wait,
140  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
141  Thread_queue_Context          *queue_context
142)
143{
144  Thread_Control *owner;
145
146  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
147
148  owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
149
150  if ( owner == NULL ) {
151    _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
152    _Thread_Resource_count_increment( executing );
153    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
154    return STATUS_SUCCESSFUL;
155  }
156
157  if ( owner == executing ) {
158    Status_Control status;
159
160    status = ( *nested )( the_mutex );
161    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
162    return status;
163  }
164
165  return _CORE_mutex_Seize_slow(
166    &the_mutex->Mutex,
167    operations,
168    executing,
169    wait,
170    queue_context
171  );
172}
173
174RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
175  CORE_recursive_mutex_Control  *the_mutex,
176  const Thread_queue_Operations *operations,
177  Thread_Control                *executing,
178  Thread_queue_Context          *queue_context
179)
180{
181  unsigned int        nest_level;
182  Thread_queue_Heads *heads;
183
184  _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
185
186  if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
187    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
188    return STATUS_NOT_OWNER;
189  }
190
191  nest_level = the_mutex->nest_level;
192
193  if ( nest_level > 0 ) {
194    the_mutex->nest_level = nest_level - 1;
195    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
196    return STATUS_SUCCESSFUL;
197  }
198
199  _Thread_Resource_count_decrement( executing );
200  _CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
201
202  heads = the_mutex->Mutex.Wait_queue.Queue.heads;
203
204  if ( heads == NULL ) {
205    _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
206    return STATUS_SUCCESSFUL;
207  }
208
209  _Thread_queue_Surrender(
210    &the_mutex->Mutex.Wait_queue.Queue,
211    heads,
212    executing,
213    queue_context,
214    operations
215  );
216  return STATUS_SUCCESSFUL;
217}
218
219RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
220  CORE_ceiling_mutex_Control *the_mutex,
221  const Scheduler_Control    *scheduler,
222  Priority_Control            priority_ceiling
223)
224{
225  _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
226  _Priority_Node_initialize( &the_mutex->Priority_ceiling, priority_ceiling );
227#if defined(RTEMS_SMP)
228  the_mutex->scheduler = scheduler;
229#endif
230}
231
232RTEMS_INLINE_ROUTINE const Scheduler_Control *
233_CORE_ceiling_mutex_Get_scheduler(
234  const CORE_ceiling_mutex_Control *the_mutex
235)
236{
237#if defined(RTEMS_SMP)
238  return the_mutex->scheduler;
239#else
240  return &_Scheduler_Table[ 0 ];
241#endif
242}
243
244RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Set_priority(
245  CORE_ceiling_mutex_Control *the_mutex,
246  Priority_Control            priority_ceiling,
247  Thread_queue_Context       *queue_context
248)
249{
250  Thread_Control *owner;
251
252  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
253
254  if ( owner != NULL ) {
255    _Thread_Wait_acquire( owner, queue_context );
256    _Thread_Priority_change(
257      owner,
258      &the_mutex->Priority_ceiling,
259      priority_ceiling,
260      false,
261      queue_context
262    );
263    _Thread_Wait_release( owner, queue_context );
264  } else {
265    the_mutex->Priority_ceiling.priority = priority_ceiling;
266  }
267}
268
269RTEMS_INLINE_ROUTINE Priority_Control _CORE_ceiling_mutex_Get_priority(
270  const CORE_ceiling_mutex_Control *the_mutex
271)
272{
273  return the_mutex->Priority_ceiling.priority;
274}
275
276RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
277  CORE_ceiling_mutex_Control *the_mutex,
278  Thread_Control             *owner,
279  Thread_queue_Context       *queue_context
280)
281{
282  ISR_lock_Context  lock_context;
283  Scheduler_Node   *scheduler_node;
284  Per_CPU_Control  *cpu_self;
285
286  _Thread_Wait_acquire_default_critical( owner, &lock_context );
287
288  scheduler_node = _Thread_Scheduler_get_home_node( owner );
289
290  if (
291    _Priority_Get_priority( &scheduler_node->Wait.Priority )
292      < the_mutex->Priority_ceiling.priority
293  ) {
294    _Thread_Wait_release_default_critical( owner, &lock_context );
295    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
296    return STATUS_MUTEX_CEILING_VIOLATED;
297  }
298
299  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
300  _Thread_Resource_count_increment( owner );
301  _Thread_Priority_add(
302    owner,
303    &the_mutex->Priority_ceiling,
304    queue_context
305  );
306  _Thread_Wait_release_default_critical( owner, &lock_context );
307
308  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
309  _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
310  _Thread_Priority_update( queue_context );
311  _Thread_Dispatch_enable( cpu_self );
312  return STATUS_SUCCESSFUL;
313}
314
315RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize(
316  CORE_ceiling_mutex_Control    *the_mutex,
317  Thread_Control                *executing,
318  bool                           wait,
319  Status_Control              ( *nested )( CORE_recursive_mutex_Control * ),
320  Thread_queue_Context          *queue_context
321)
322{
323  Thread_Control *owner;
324
325  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
326
327  owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
328
329  if ( owner == NULL ) {
330#if defined(RTEMS_SMP)
331    if (
332      _Thread_Scheduler_get_home( executing )
333        != _CORE_ceiling_mutex_Get_scheduler( the_mutex )
334    ) {
335      _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
336      return STATUS_NOT_DEFINED;
337    }
338#endif
339
340    _Thread_queue_Context_clear_priority_updates( queue_context );
341    return _CORE_ceiling_mutex_Set_owner(
342      the_mutex,
343      executing,
344      queue_context
345    );
346  }
347
348  if ( owner == executing ) {
349    Status_Control status;
350
351    status = ( *nested )( &the_mutex->Recursive );
352    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
353    return status;
354  }
355
356  return _CORE_mutex_Seize_slow(
357    &the_mutex->Recursive.Mutex,
358    CORE_MUTEX_TQ_OPERATIONS,
359    executing,
360    wait,
361    queue_context
362  );
363}
364
365RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
366  CORE_ceiling_mutex_Control *the_mutex,
367  Thread_Control             *executing,
368  Thread_queue_Context       *queue_context
369)
370{
371  unsigned int      nest_level;
372  ISR_lock_Context  lock_context;
373  Per_CPU_Control  *cpu_self;
374  Thread_Control   *new_owner;
375
376  _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
377
378  if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
379    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
380    return STATUS_NOT_OWNER;
381  }
382
383  nest_level = the_mutex->Recursive.nest_level;
384
385  if ( nest_level > 0 ) {
386    the_mutex->Recursive.nest_level = nest_level - 1;
387    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
388    return STATUS_SUCCESSFUL;
389  }
390
391  _Thread_Resource_count_decrement( executing );
392
393  _Thread_queue_Context_clear_priority_updates( queue_context );
394  _Thread_Wait_acquire_default_critical( executing, &lock_context );
395  _Thread_Priority_remove(
396    executing,
397    &the_mutex->Priority_ceiling,
398    queue_context
399  );
400  _Thread_Wait_release_default_critical( executing, &lock_context );
401
402  new_owner = _Thread_queue_First_locked(
403    &the_mutex->Recursive.Mutex.Wait_queue,
404    CORE_MUTEX_TQ_OPERATIONS
405  );
406  _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
407
408  cpu_self = _Thread_Dispatch_disable_critical(
409    &queue_context->Lock_context.Lock_context
410  );
411
412  if ( new_owner != NULL ) {
413#if defined(RTEMS_MULTIPROCESSING)
414    if ( _Objects_Is_local_id( new_owner->Object.id ) )
415#endif
416    {
417      _Thread_Resource_count_increment( new_owner );
418      _Thread_Priority_add(
419        new_owner,
420        &the_mutex->Priority_ceiling,
421        queue_context
422      );
423    }
424
425    _Thread_queue_Extract_critical(
426      &the_mutex->Recursive.Mutex.Wait_queue.Queue,
427      CORE_MUTEX_TQ_OPERATIONS,
428      new_owner,
429      queue_context
430    );
431  } else {
432    _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
433  }
434
435  _Thread_Priority_update( queue_context );
436  _Thread_Dispatch_enable( cpu_self );
437  return STATUS_SUCCESSFUL;
438}
439
440/** @} */
441
442#ifdef __cplusplus
443}
444#endif
445
446#endif
447/* end of include file */
Note: See TracBrowser for help on using the repository browser.