OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [score/] [src/] [coremutexseize.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 *  coremutexseize.c,v 1.7 2001/08/30 18:33:57 joel Exp
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
 
38
void _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)
79
int _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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.