source: rtems/c/src/exec/score/src/coremutexseize.c @ b68cc333

Last change on this file since b68cc333 was 6f1118a, checked in by Joel Sherrill <joel.sherrill@…>, on 08/30/01 at 18:32:12

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

  • src/coremutex.c, src/coremutexseize.c, src/coremutexsurrender.c: 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.0 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
29 *
30 *  This routine attempts to allocate a mutex to the calling thread.
31 *
32 *  Input parameters:
33 *    the_mutex - pointer to mutex control block
34 *    id        - id of object to wait on
35 *    wait      - TRUE if wait is allowed, FALSE otherwise
36 *    timeout   - number of ticks to wait (0 means forever)
37 *
38 *  Output parameters:  NONE
39 *
40 *  INTERRUPT LATENCY:
41 *    available
42 *    wait
43 */
44
45void _CORE_mutex_Seize(
46  CORE_mutex_Control  *the_mutex,
47  Objects_Id           id,
48  boolean              wait,
49  Watchdog_Interval    timeout
50)
51{
52  Thread_Control *executing;
53  ISR_Level       level;
54
55  executing = _Thread_Executing;
56  if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
57    if ( executing->current_priority < the_mutex->Attributes.priority_ceiling) {
58      executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
59      return;
60    }
61  }
62  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
63  _ISR_Disable( level );
64  if ( ! _CORE_mutex_Is_locked( the_mutex ) ) {
65    the_mutex->lock       = CORE_MUTEX_LOCKED;
66    the_mutex->holder     = executing;
67    the_mutex->holder_id  = executing->Object.id;
68    the_mutex->nest_count = 1;
69    if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ||
70         _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) )
71      executing->resource_count++;
72    _ISR_Enable( level );
73    /*
74     *  if CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT then nothing to do
75     *  because this task is already the highest priority.
76     */
77
78    if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
79      if (the_mutex->Attributes.priority_ceiling < executing->current_priority){
80        _Thread_Change_priority(
81          the_mutex->holder,
82          the_mutex->Attributes.priority_ceiling,
83          FALSE
84        );
85      }
86    }
87    executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
88    return;
89  }
90
91  if ( _Thread_Is_executing( the_mutex->holder ) ) {
92    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
93      case CORE_MUTEX_NESTING_ACQUIRES:
94        the_mutex->nest_count++;
95        _ISR_Enable( level );
96        return;
97      case CORE_MUTEX_NESTING_IS_ERROR:
98        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
99        _ISR_Enable( level );
100        return;
101      case CORE_MUTEX_NESTING_BLOCKS:
102        break;
103    }
104  }
105
106  if ( !wait ) {
107    _ISR_Enable( level );
108    executing->Wait.return_code = CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
109    return;
110  }
111
112  _Thread_queue_Enter_critical_section( &the_mutex->Wait_queue );
113  executing->Wait.queue = &the_mutex->Wait_queue;
114  executing->Wait.id    = id;
115  _ISR_Enable( level );
116
117  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
118    if ( the_mutex->holder->current_priority > executing->current_priority ) {
119      _Thread_Change_priority(
120        the_mutex->holder,
121        executing->current_priority,
122        FALSE
123      );
124    }
125  }
126
127  _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
128
129  if ( _Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL ) {
130    if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
131      if (the_mutex->Attributes.priority_ceiling < executing->current_priority){
132        _Thread_Change_priority(
133          executing,
134          the_mutex->Attributes.priority_ceiling,
135          FALSE
136        );
137      }
138    }
139  }
140}
141
Note: See TracBrowser for help on using the repository browser.