source: rtems/cpukit/score/inline/rtems/score/coremutex.inl @ 66a9239a

4.104.114.9
Last change on this file since 66a9239a was 66a9239a, checked in by Ralf Corsepius <ralf.corsepius@…>, on Jun 30, 2008 at 3:03:03 PM

Rename STRICT_ORDER_MUTEX to RTEMS_STRICT_ORDER_MUTEX.

  • Property mode set to 100644
File size: 6.0 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_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 *  @return This method returns TRUE if the mutex is using priority
105 *          ceiling.
106 */
107RTEMS_INLINE_ROUTINE boolean _CORE_mutex_Is_priority_ceiling(
108  CORE_mutex_Attributes *the_attribute
109)
110{
111  return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
112}
113 
114/*
115 *  Seize Mutex with Quick Success Path
116 *
117 *  NOTE: There is no MACRO version of this routine.  A body is in
118 *  coremutexseize.c that is duplicated from the .inl by hand.
119 *
120 *  NOTE: The Doxygen for this routine is in the .h file.
121 */
122
123RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body(
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
143#ifdef __RTEMS_STRICT_ORDER_MUTEX__
144       _Chain_Prepend_unprotected( &executing->lock_mutex,
145                                   &the_mutex->queue.lock_queue );
146       the_mutex->queue.priority_before = executing->current_priority;
147#endif
148
149      executing->resource_count++;
150    }
151
152    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
153        _ISR_Enable( level );
154        return 0;
155    } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING
156       *
157       * we possibly bump the priority of the current holder -- which
158       * happens to be _Thread_Executing.
159       */
160    {
161      Priority_Control  ceiling;
162      Priority_Control  current;
163
164      ceiling = the_mutex->Attributes.priority_ceiling;
165      current = executing->current_priority;
166      if ( current == ceiling ) {
167        _ISR_Enable( level );
168        return 0;
169      }
170
171      if ( current > ceiling ) {
172        _Thread_Disable_dispatch();
173        _ISR_Enable( level );
174        _Thread_Change_priority(
175          the_mutex->holder,
176          the_mutex->Attributes.priority_ceiling,
177         FALSE
178        );
179        _Thread_Enable_dispatch();
180        return 0;
181      }
182      /* if ( current < ceiling ) */ {
183        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
184        the_mutex->nest_count = 0;     /* undo locking above */
185        executing->resource_count--;   /* undo locking above */
186        _ISR_Enable( level );
187        return 0;
188      }
189    }
190    return 0;
191  }
192
193  /*
194   *  At this point, we know the mutex was not available.  If this thread
195   *  is the thread that has locked the mutex, let's see if we are allowed
196   *  to nest access.
197   */
198  if ( _Thread_Is_executing( the_mutex->holder ) ) {
199    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
200      case CORE_MUTEX_NESTING_ACQUIRES:
201        the_mutex->nest_count++;
202        _ISR_Enable( level );
203        return 0;
204      case CORE_MUTEX_NESTING_IS_ERROR:
205        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
206        _ISR_Enable( level );
207        return 0;
208      case CORE_MUTEX_NESTING_BLOCKS:
209        break;
210    }
211  }
212
213  /*
214   *  The mutex is not available and the caller must deal with the possibility
215   *  of blocking.
216   */
217  return 1;
218}
219
220/**@}*/
221
222#endif
223/* end of include file */
Note: See TracBrowser for help on using the repository browser.