source: rtems/cpukit/score/inline/rtems/score/coremutex.inl @ 8774fdd

4.8
Last change on this file since 8774fdd was 8774fdd, checked in by Joel Sherrill <joel.sherrill@…>, on 05/28/09 at 21:04:29

2009-05-28 Joel Sherrill <joel.sherrill@…>

PR 1415/cpukit

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