source: rtems/cpukit/score/inline/rtems/score/coremutex.inl @ 6390256

4.104.115
Last change on this file since 6390256 was 6390256, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/22/08 at 09:22:17

Eliminate TRUE/FALSE.

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