source: rtems/cpukit/score/src/threaddispatchdisablelevel.c @ 3a8a999

4.115
Last change on this file since 3a8a999 was 3a8a999, checked in by Jennifer Averett <Jennifer.Averett@…>, on 05/23/11 at 13:30:15

2011-05-23 Jennifer Averett <Jennifer.Averett@…>

  • score/Makefile.am, score/include/rtems/score/thread.h, score/inline/rtems/score/thread.inl: Add smp support to dispable dispatch level accesses.
  • score/src/threaddispatchdisablelevel.c: New file.
  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*
2 *  Thread Dispatch Disable Level Methods
3 *
4 *  COPYRIGHT (c) 1989-2011.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#include <rtems/system.h>
15#include <rtems/score/apiext.h>
16#include <rtems/score/context.h>
17#include <rtems/score/interr.h>
18#include <rtems/score/isr.h>
19#include <rtems/score/object.h>
20#include <rtems/score/priority.h>
21#include <rtems/score/states.h>
22#include <rtems/score/sysstate.h>
23#include <rtems/score/thread.h>
24
25void _Thread_Dispatch_initialization( void )
26{
27  _Thread_Dispatch_disable_level = 0;
28  _SMP_lock_spinlock_nested_Initialize(&_Thread_Dispatch_disable_level_lock);
29  _Thread_Dispatch_set_disable_level( 1 );
30}
31
32bool _Thread_Dispatch_in_critical_section(void)
33{
34  if (  _Thread_Dispatch_disable_level == 0 )
35   return false;
36
37  return true;
38}
39
40uint32_t _Thread_Dispatch_get_disable_level(void)
41{
42  return _Thread_Dispatch_disable_level;
43}
44
45uint32_t _Thread_Dispatch_increment_disable_level(void)
46{
47  ISR_Level  isr_level;
48  uint32_t   level;
49
50  /*
51   * Note: _SMP_lock_spinlock_nested_Obtain returns
52   *       with ISR's disabled and the isr_level that
53   *       should be restored after a short period.
54   *
55   * Here we obtain the lock and increment the
56   * Thread dispatch disable level while under the
57   * protection of the isr being off.  After this
58   * point it is safe to re-enable ISRs and allow
59   * the dispatch disable lock to provide protection.
60   */
61
62  isr_level = _SMP_lock_spinlock_nested_Obtain(
63    &_Thread_Dispatch_disable_level_lock
64  );
65 
66  _Thread_Dispatch_disable_level++;
67  level = _Thread_Dispatch_disable_level;
68
69  _ISR_Enable(isr_level);
70
71  return level;
72}
73
74uint32_t _Thread_Dispatch_decrement_disable_level(void)
75{
76  ISR_Level  isr_level;
77  uint32_t   level;
78
79  /*  First we must disable ISRs in order to protect
80   *  accesses to the dispatch disable level.
81   */
82
83  _ISR_Disable( isr_level );
84
85  _Thread_Dispatch_disable_level--;
86  level = _Thread_Dispatch_disable_level;
87
88
89  /*
90   * Note: _SMP_lock_spinlock_nested_Obtain returns with
91   *        ISR's disabled and _SMP_lock_spinlock_nested_Release
92   *        is responsable for re-enabling interrupts.
93   */
94  _SMP_lock_spinlock_nested_Release(
95    &_Thread_Dispatch_disable_level_lock,
96    isr_level
97  );
98
99  return level;
100}
101
102
103/*
104 * Note this method is taking a heavy handed approach to
105 * setting the dispatch level. This may be optimized at a
106 * later timee, but it must be in such a way that the nesting
107 * level is decremented by the same number as the dispatch level.
108 * This approach is safest until we are sure the nested spinlock
109 * is successfully working with smp isr source code. 
110 */
111
112uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
113{
114  /*
115   * If we need the dispatch level to go higher
116   * call increment method the desired number of times.
117   */
118
119  while ( value > _Thread_Dispatch_disable_level ) {
120    _Thread_Dispatch_increment_disable_level();
121  }
122
123  /*
124   * If we need the dispatch level to go lower
125   * call increment method the desired number of times.
126   */
127
128  while ( value < _Thread_Dispatch_disable_level ) {
129    _Thread_Dispatch_decrement_disable_level();
130  }
131
132  return value;
133}
Note: See TracBrowser for help on using the repository browser.