source: rtems/cpukit/score/src/threaddispatchdisablelevel.c @ 39e51758

4.115
Last change on this file since 39e51758 was 39e51758, checked in by Sebastian Huber <sebastian.huber@…>, on 06/14/13 at 12:00:38

smp: Add and use _CPU_SMP_Get_current_processor()

Add and use _SMP_Get_current_processor() and
rtems_smp_get_current_processor().

Delete bsp_smp_interrupt_cpu().

Change type of current processor index from int to uint32_t to match
_SMP_Processor_count type.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Thread Dispatch Disable Functions
5 *
6 * @ingroup ScoreThread
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2011.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 */
17
18#include <rtems/system.h>
19#include <rtems/score/apiext.h>
20#include <rtems/score/context.h>
21#include <rtems/score/interr.h>
22#include <rtems/score/isr.h>
23#include <rtems/score/object.h>
24#include <rtems/score/priority.h>
25#include <rtems/score/states.h>
26#include <rtems/score/sysstate.h>
27#include <rtems/score/threaddispatch.h>
28
29#define NO_OWNER_CPU 0xffffffffU
30
31void _Thread_Dispatch_initialization( void )
32{
33  Thread_Dispatch_disable_level_lock_control *level_lock =
34    &_Thread_Dispatch_disable_level_lock;
35
36  _Thread_Dispatch_disable_level = 0;
37  _SMP_lock_Initialize( &level_lock->lock );
38  level_lock->owner_cpu = NO_OWNER_CPU;
39  _Thread_Dispatch_set_disable_level( 1 );
40}
41
42uint32_t _Thread_Dispatch_get_disable_level(void)
43{
44  return _Thread_Dispatch_disable_level;
45}
46
47uint32_t _Thread_Dispatch_increment_disable_level( void )
48{
49  Thread_Dispatch_disable_level_lock_control *level_lock =
50    &_Thread_Dispatch_disable_level_lock;
51  ISR_Level isr_level;
52  uint32_t self_cpu;
53  uint32_t disable_level;
54
55  _ISR_Disable_on_this_core( isr_level );
56
57  /*
58   * We must obtain the processor ID after interrupts are disabled since a
59   * non-optimizing compiler may store the value on the stack and read it back.
60   */
61  self_cpu = _SMP_Get_current_processor();
62
63  if ( level_lock->owner_cpu != self_cpu ) {
64    _SMP_lock_Acquire( &level_lock->lock );
65    level_lock->owner_cpu = self_cpu;
66    level_lock->nest_level = 1;
67  } else {
68    ++level_lock->nest_level;
69  }
70
71  disable_level = _Thread_Dispatch_disable_level;
72  ++disable_level;
73  _Thread_Dispatch_disable_level = disable_level;
74
75  _ISR_Enable_on_this_core( isr_level );
76
77  return disable_level;
78}
79
80uint32_t _Thread_Dispatch_decrement_disable_level( void )
81{
82  Thread_Dispatch_disable_level_lock_control *level_lock =
83    &_Thread_Dispatch_disable_level_lock;
84  ISR_Level isr_level;
85  uint32_t disable_level;
86
87  _ISR_Disable_on_this_core( isr_level );
88
89  disable_level = _Thread_Dispatch_disable_level;
90  --disable_level;
91  _Thread_Dispatch_disable_level = disable_level;
92
93  --level_lock->nest_level;
94  if ( level_lock->nest_level == 0 ) {
95    level_lock->owner_cpu = NO_OWNER_CPU;
96    _SMP_lock_Release( &level_lock->lock );
97  }
98
99  _ISR_Enable_on_this_core( isr_level );
100
101  return disable_level;
102}
103
104
105/*
106 * Note this method is taking a heavy handed approach to
107 * setting the dispatch level. This may be optimized at a
108 * later timee, but it must be in such a way that the nesting
109 * level is decremented by the same number as the dispatch level.
110 * This approach is safest until we are sure the nested spinlock
111 * is successfully working with smp isr source code. 
112 */
113
114uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
115{
116  /*
117   * If we need the dispatch level to go higher
118   * call increment method the desired number of times.
119   */
120
121  while ( value > _Thread_Dispatch_disable_level ) {
122    _Thread_Dispatch_increment_disable_level();
123  }
124
125  /*
126   * If we need the dispatch level to go lower
127   * call increment method the desired number of times.
128   */
129
130  while ( value < _Thread_Dispatch_disable_level ) {
131    _Thread_Dispatch_decrement_disable_level();
132  }
133
134  return value;
135}
Note: See TracBrowser for help on using the repository browser.