source: rtems/cpukit/score/inline/rtems/score/coremutex.inl @ 4fc370e

4.115
Last change on this file since 4fc370e was 4fc370e, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 5, 2013 at 10:08:23 AM

score: Move thread dispatch content to new file

Move thread dispatch declarations and inline functions to new header
<rtems/score/threaddispatch.h> to make it independent of the
Thread_Control structure. This avoids a cyclic dependency in case
thread dispatch functions are used for the object implementation.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with the CORE Mutexes
5 *
6 * This include file contains all of the inlined routines associated
7 * with the CORE mutexes.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2009.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_COREMUTEX_H
20# error "Never use <rtems/score/coremutex.inl> directly; include <rtems/score/coremutex.h> instead."
21#endif
22
23#ifndef _RTEMS_SCORE_COREMUTEX_INL
24#define _RTEMS_SCORE_COREMUTEX_INL
25
26#include <rtems/score/threaddispatch.h>
27
28/**
29 * @addtogroup ScoreMutex
30 */
31/**@{**/
32
33/**
34 * @brief Is mutex locked.
35 *
36 * This routine returns true if the mutex specified is locked and false
37 * otherwise.
38 *
39 * @param[in] the_mutex is the mutex to check.
40 *
41 * @retval true The mutex is locked.
42 * @retval false The mutex is not locked.
43 */
44RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
45  CORE_mutex_Control  *the_mutex
46)
47{
48  return the_mutex->lock == CORE_MUTEX_LOCKED;
49}
50
51/**
52 * @brief Does core mutex use FIFO blocking.
53 *
54 * This routine returns true if the mutex's wait discipline is FIFO and false
55 * otherwise.
56 *
57 * @param[in] the_attribute is the attribute set of the mutex.
58 *
59 * @retval true The mutex is using FIFO blocking order.
60 * @retval false The mutex is not using FIFO blocking order.
61 */
62RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
63  CORE_mutex_Attributes *the_attribute
64)
65{
66  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
67}
68
69/**
70 * @brief Doex core mutex use priority blocking.
71 *
72 * This routine returns true if the mutex's wait discipline is PRIORITY and
73 * false otherwise.
74 *
75 * @param[in] the_attribute is the attribute set of the mutex.
76 *
77 * @retval true The mutex is using priority blocking order.
78 * @retval false The mutex is not using priority blocking order.
79 *
80 */
81RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority(
82  CORE_mutex_Attributes *the_attribute
83)
84{
85  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY;
86}
87
88/**
89 * @brief Does mutex use priority inheritance.
90 *
91 * This routine returns true if the mutex's wait discipline is
92 * INHERIT_PRIORITY and false otherwise.
93 *
94 * @param[in] the_attribute is the attribute set of the mutex.
95 *
96 * @retval true The mutex is using priority inheritance.
97 * @retval false The mutex is not using priority inheritance.
98 */
99RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority(
100  CORE_mutex_Attributes *the_attribute
101)
102{
103  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
104}
105
106/**
107 * @brief Does mutex use priority ceiling.
108 *
109 * This routine returns true if the mutex's wait discipline is
110 * PRIORITY_CEILING and false otherwise.
111 *
112 * @param[in] the_attribute is the attribute set of the mutex.
113 *
114 * @retval true The mutex is using priority ceiling.
115 * @retval false The mutex is not using priority ceiling.
116 */
117RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling(
118  CORE_mutex_Attributes *the_attribute
119)
120{
121  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
122}
123
124/*
125 *  Seize Mutex with Quick Success Path
126 *
127 *  NOTE: There is no MACRO version of this routine.  A body is in
128 *  coremutexseize.c that is duplicated from the .inl by hand.
129 *
130 *  NOTE: The Doxygen for this routine is in the .h file.
131 */
132
133RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
134  CORE_mutex_Control  *the_mutex,
135  ISR_Level            level
136)
137{
138  Thread_Control   *executing;
139
140  /* disabled when you get here */
141
142  executing = _Thread_Executing;
143  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
144  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
145    the_mutex->lock       = CORE_MUTEX_LOCKED;
146    the_mutex->holder     = executing;
147    the_mutex->holder_id  = executing->Object.id;
148    the_mutex->nest_count = 1;
149    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
150         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
151
152#ifdef __RTEMS_STRICT_ORDER_MUTEX__
153       _Chain_Prepend_unprotected( &executing->lock_mutex,
154                                   &the_mutex->queue.lock_queue );
155       the_mutex->queue.priority_before = executing->current_priority;
156#endif
157
158      executing->resource_count++;
159    }
160
161    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
162      _ISR_Enable( level );
163      return 0;
164    } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
165       *
166       * we possibly bump the priority of the current holder -- which
167       * happens to be _Thread_Executing.
168       */
169    {
170      Priority_Control  ceiling;
171      Priority_Control  current;
172
173      ceiling = the_mutex->Attributes.priority_ceiling;
174      current = executing->current_priority;
175      if ( current == ceiling ) {
176        _ISR_Enable( level );
177        return 0;
178      }
179
180      if ( current > ceiling ) {
181        _Thread_Disable_dispatch();
182        _ISR_Enable( level );
183        _Thread_Change_priority(
184          the_mutex->holder,
185          the_mutex->Attributes.priority_ceiling,
186         false
187        );
188        _Thread_Enable_dispatch();
189        return 0;
190      }
191      /* if ( current < ceiling ) */ {
192        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
193        the_mutex->lock       = CORE_MUTEX_UNLOCKED;
194        the_mutex->nest_count = 0;     /* undo locking above */
195        executing->resource_count--;   /* undo locking above */
196        _ISR_Enable( level );
197        return 0;
198      }
199    }
200    return 0;
201  }
202
203  /*
204   *  At this point, we know the mutex was not available.  If this thread
205   *  is the thread that has locked the mutex, let's see if we are allowed
206   *  to nest access.
207   */
208  if ( _Thread_Is_executing( the_mutex->holder ) ) {
209    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
210      case CORE_MUTEX_NESTING_ACQUIRES:
211        the_mutex->nest_count++;
212        _ISR_Enable( level );
213        return 0;
214      #if defined(RTEMS_POSIX_API)
215        case CORE_MUTEX_NESTING_IS_ERROR:
216          executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
217          _ISR_Enable( level );
218          return 0;
219      #endif
220      case CORE_MUTEX_NESTING_BLOCKS:
221        break;
222    }
223  }
224
225  /*
226   *  The mutex is not available and the caller must deal with the possibility
227   *  of blocking.
228   */
229  return 1;
230}
231
232/** @} */
233
234#endif
235/* end of include file */
Note: See TracBrowser for help on using the repository browser.