source: rtems/c/src/exec/score/src/coremutexseize.c @ 6ba9c27

4.104.114.84.95
Last change on this file since 6ba9c27 was fb1d8f81, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/01 at 18:33:57

2001-08-30 Joel Sherrill <joel@…>

  • src/coremutex.c, src/coremutexseize.c, src/coremutexsurrender.c, inline/rtems/score/coremutex.inl: The per thread field resource_count should only be manipulated when a mutex is priority ceiling or priority inherit. This was reported by Chris Johns <ccj@…> who also noticed that the use of switches for all disciplines generated less efficient code than using explicit tests for the one or two cases we were really interested in. Further review of his modifications made it apparent that the "isa" methods to test mutex discipline were not being used so this modification was swept into the code as well.
  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 *  Mutex Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the Mutex Handler.
7 *  This handler provides synchronization and mutual exclusion capabilities.
8 *
9 *  COPYRIGHT (c) 1989-1999.
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.OARcorp.com/rtems/license.html.
15 *
16 *  $Id$
17 */
18
19#include <rtems/system.h>
20#include <rtems/score/isr.h>
21#include <rtems/score/coremutex.h>
22#include <rtems/score/states.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/threadq.h>
25
26/*PAGE
27 *
28 *  _CORE_mutex_Seize (interrupt blocking support)
29 *
30 *  This routine blocks the caller thread after an attempt attempts to obtain
31 *  the specified mutex has failed.
32 *
33 *  Input parameters:
34 *    the_mutex - pointer to mutex control block
35 *    timeout   - number of ticks to wait (0 means forever)
36 */
37
38void _CORE_mutex_Seize_interrupt_blocking(
39  CORE_mutex_Control  *the_mutex,
40  Watchdog_Interval    timeout
41)
42{
43  Thread_Control   *executing;
44
45  executing = _Thread_Executing;
46  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
47    if ( the_mutex->holder->current_priority > executing->current_priority ) {
48      _Thread_Change_priority(
49        the_mutex->holder,
50        executing->current_priority,
51        FALSE
52      );
53    }
54  }
55
56  the_mutex->blocked_count++;
57  _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
58
59  if ( _Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL ) {
60    /*
61     *  if CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT then nothing to do
62     *  because this task is already the highest priority.
63     */
64
65    if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
66      if (the_mutex->Attributes.priority_ceiling < executing->current_priority){
67        _Thread_Change_priority(
68          executing,
69          the_mutex->Attributes.priority_ceiling,
70          FALSE
71        );
72      }
73    }
74  }
75  _Thread_Enable_dispatch();
76}
77
78#if !defined(USE_INLINES)
79int _CORE_mutex_Seize_interrupt_trylock(
80  CORE_mutex_Control  *the_mutex,
81  ISR_Level           *level_p
82)
83{
84  Thread_Control   *executing;
85  ISR_Level         level = *level_p;
86 
87  /* disabled when you get here */
88   
89  executing = _Thread_Executing;
90  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
91  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
92    the_mutex->lock       = CORE_MUTEX_LOCKED;
93    the_mutex->holder     = executing;
94    the_mutex->holder_id  = executing->Object.id;
95    the_mutex->nest_count = 1;
96    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
97         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
98      executing->resource_count++;
99
100    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
101      _ISR_Enable( level );
102      return 0;
103    }
104    /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
105    {
106       Priority_Control  ceiling;
107       Priority_Control  current;
108
109       ceiling = the_mutex->Attributes.priority_ceiling;
110       current = executing->current_priority;
111       if ( current == ceiling ) {
112         _ISR_Enable( level );
113         return 0;
114       }
115       if ( current > ceiling ) {
116        _Thread_Disable_dispatch();
117        _ISR_Enable( level );
118        _Thread_Change_priority(
119          the_mutex->holder,
120          the_mutex->Attributes.priority_ceiling,
121          FALSE
122        );
123        _Thread_Enable_dispatch();
124        return 0;
125      }
126      /* if ( current < ceiling ) */ {
127        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
128        the_mutex->nest_count = 0;     /* undo locking above */
129        executing->resource_count--;   /* undo locking above */
130        _ISR_Enable( level );
131        return 0;
132      }
133    }
134    return 0;
135  }
136
137  if ( _Thread_Is_executing( the_mutex->holder ) ) {
138    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
139      case CORE_MUTEX_NESTING_ACQUIRES:
140        the_mutex->nest_count++;
141        _ISR_Enable( level );
142        return 0;
143      case CORE_MUTEX_NESTING_IS_ERROR:
144        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
145        _ISR_Enable( level );
146        return 0;
147      case CORE_MUTEX_NESTING_BLOCKS:
148        break;
149    }
150  }
151
152  return 1;
153}
154#endif
Note: See TracBrowser for help on using the repository browser.