source: rtems/cpukit/score/src/coremutexseize.c @ 83df49f

4.104.114.84.95
Last change on this file since 83df49f was 83df49f, checked in by Joel Sherrill <joel.sherrill@…>, on 07/11/06 at 21:05:12

2006-07-11 Joel Sherrill <joel@…>

PR 1124/rtems

  • score/include/rtems/score/threadq.h, score/src/coremutexseize.c, score/src/coremutexsurrender.c, score/src/threadqenqueue.c, score/src/threadqenqueuefifo.c, score/src/threadqenqueuepriority.c: The placement of the changing a thread's priority when using priority ceiling should be on the successful transfer of the mutex -- not when the thread tries to acquire. Plus the lack of a dispatch disable point lead to the potential for a thread timing out and already having inherited the ceiling priority.
  • Property mode set to 100644
File size: 3.8 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-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#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <rtems/system.h>
24#include <rtems/score/isr.h>
25#include <rtems/score/coremutex.h>
26#include <rtems/score/states.h>
27#include <rtems/score/thread.h>
28#include <rtems/score/threadq.h>
29
30/*PAGE
31 *
32 *  _CORE_mutex_Seize (interrupt blocking support)
33 *
34 *  This routine blocks the caller thread after an attempt attempts to obtain
35 *  the specified mutex has failed.
36 *
37 *  Input parameters:
38 *    the_mutex - pointer to mutex control block
39 *    timeout   - number of ticks to wait (0 means forever)
40 */
41
42void _CORE_mutex_Seize_interrupt_blocking(
43  CORE_mutex_Control  *the_mutex,
44  Watchdog_Interval    timeout
45)
46{
47  Thread_Control   *executing;
48
49  executing = _Thread_Executing;
50  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
51    if ( the_mutex->holder->current_priority > executing->current_priority ) {
52      _Thread_Change_priority(
53        the_mutex->holder,
54        executing->current_priority,
55        FALSE
56      );
57    }
58  }
59
60  the_mutex->blocked_count++;
61  _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
62
63  _Thread_Enable_dispatch();
64}
65
66#if !defined(RTEMS_INLINES)
67int _CORE_mutex_Seize_interrupt_trylock(
68  CORE_mutex_Control  *the_mutex,
69  ISR_Level           *level_p
70)
71{
72  Thread_Control   *executing;
73  ISR_Level         level = *level_p;
74
75  /* disabled when you get here */
76
77  executing = _Thread_Executing;
78  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
79  if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
80    the_mutex->lock       = CORE_MUTEX_LOCKED;
81    the_mutex->holder     = executing;
82    the_mutex->holder_id  = executing->Object.id;
83    the_mutex->nest_count = 1;
84    if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
85         _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) )
86      executing->resource_count++;
87
88    if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
89      _ISR_Enable( level );
90      return 0;
91    }
92    /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */
93    {
94       Priority_Control  ceiling;
95       Priority_Control  current;
96
97       ceiling = the_mutex->Attributes.priority_ceiling;
98       current = executing->current_priority;
99       if ( current == ceiling ) {
100         _ISR_Enable( level );
101         return 0;
102       }
103       if ( current > ceiling ) {
104        _Thread_Disable_dispatch();
105        _ISR_Enable( level );
106        _Thread_Change_priority(
107          the_mutex->holder,
108          the_mutex->Attributes.priority_ceiling,
109          FALSE
110        );
111        _Thread_Enable_dispatch();
112        return 0;
113      }
114      /* if ( current < ceiling ) */ {
115        executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
116        the_mutex->nest_count = 0;     /* undo locking above */
117        executing->resource_count--;   /* undo locking above */
118        _ISR_Enable( level );
119        return 0;
120      }
121    }
122    return 0;
123  }
124
125  if ( _Thread_Is_executing( the_mutex->holder ) ) {
126    switch ( the_mutex->Attributes.lock_nesting_behavior ) {
127      case CORE_MUTEX_NESTING_ACQUIRES:
128        the_mutex->nest_count++;
129        _ISR_Enable( level );
130        return 0;
131      case CORE_MUTEX_NESTING_IS_ERROR:
132        executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
133        _ISR_Enable( level );
134        return 0;
135      case CORE_MUTEX_NESTING_BLOCKS:
136        break;
137    }
138  }
139
140  return 1;
141}
142#endif
Note: See TracBrowser for help on using the repository browser.