source: rtems/cpukit/score/src/coremutexseize.c @ a0ed4ed

4.104.114.84.95
Last change on this file since a0ed4ed was a0ed4ed, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/18/04 at 06:13:55

Remove stray white spaces.

  • Property mode set to 100644
File size: 4.2 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.rtems.com/license/LICENSE.
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(RTEMS_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.