source: rtems/cpukit/score/src/threaddispatchdisablelevel.c @ 21ff802

4.115
Last change on this file since 21ff802 was 21ff802, checked in by Sebastian Huber <sebastian.huber@…>, on 07/26/13 at 14:26:07

smp: Delete _ISR_Disable_on_this_core(), etc.

Delete _ISR_Enable_on_this_core(), _ISR_Flash_on_this_core(),
_ISR_SMP_Disable(), _ISR_SMP_Enable(), _ISR_SMP_Flash().

The ISR disable/enable interface has no parameter to pass a specific
object. Thus it is only possible to implement a single global lock
object with this interface. Using the ISR disable/enable as the giant
lock on SMP configurations is not feasible.

Potentially blocking resource obtain sequences protected by the thread
dispatch disable level are subdivided into smaller ISR disabled critical
sections. This works since on single processor configurations there is
only one thread of execution that can block. On SMP this is different
(image a mutex obtained concurrently by different threads on different
processors).

The thread dispatch disable level is currently used as the giant lock.
There is not need to complicate things with this unused interface.

  • Property mode set to 100644
File size: 3.3 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/priority.h>
24#include <rtems/score/threaddispatch.h>
25
26#define NO_OWNER_CPU 0xffffffffU
27
28void _Thread_Dispatch_initialization( void )
29{
30  Thread_Dispatch_disable_level_lock_control *level_lock =
31    &_Thread_Dispatch_disable_level_lock;
32
33  _Thread_Dispatch_disable_level = 0;
34  _SMP_lock_Initialize( &level_lock->lock );
35  level_lock->owner_cpu = NO_OWNER_CPU;
36  _Thread_Dispatch_set_disable_level( 1 );
37}
38
39uint32_t _Thread_Dispatch_get_disable_level(void)
40{
41  return _Thread_Dispatch_disable_level;
42}
43
44uint32_t _Thread_Dispatch_increment_disable_level( void )
45{
46  Thread_Dispatch_disable_level_lock_control *level_lock =
47    &_Thread_Dispatch_disable_level_lock;
48  ISR_Level isr_level;
49  uint32_t self_cpu;
50  uint32_t disable_level;
51
52  _ISR_Disable( isr_level );
53
54  /*
55   * We must obtain the processor ID after interrupts are disabled since a
56   * non-optimizing compiler may store the value on the stack and read it back.
57   */
58  self_cpu = _SMP_Get_current_processor();
59
60  if ( level_lock->owner_cpu != self_cpu ) {
61    _SMP_lock_Acquire( &level_lock->lock );
62    level_lock->owner_cpu = self_cpu;
63    level_lock->nest_level = 1;
64  } else {
65    ++level_lock->nest_level;
66  }
67
68  disable_level = _Thread_Dispatch_disable_level;
69  ++disable_level;
70  _Thread_Dispatch_disable_level = disable_level;
71
72  _ISR_Enable( isr_level );
73
74  return disable_level;
75}
76
77uint32_t _Thread_Dispatch_decrement_disable_level( void )
78{
79  Thread_Dispatch_disable_level_lock_control *level_lock =
80    &_Thread_Dispatch_disable_level_lock;
81  ISR_Level isr_level;
82  uint32_t disable_level;
83
84  _ISR_Disable( isr_level );
85
86  disable_level = _Thread_Dispatch_disable_level;
87  --disable_level;
88  _Thread_Dispatch_disable_level = disable_level;
89
90  --level_lock->nest_level;
91  if ( level_lock->nest_level == 0 ) {
92    level_lock->owner_cpu = NO_OWNER_CPU;
93    _SMP_lock_Release( &level_lock->lock );
94  }
95
96  _ISR_Enable( isr_level );
97
98  return disable_level;
99}
100
101
102/*
103 * Note this method is taking a heavy handed approach to
104 * setting the dispatch level. This may be optimized at a
105 * later timee, but it must be in such a way that the nesting
106 * level is decremented by the same number as the dispatch level.
107 * This approach is safest until we are sure the nested spinlock
108 * is successfully working with smp isr source code. 
109 */
110
111uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
112{
113  /*
114   * If we need the dispatch level to go higher
115   * call increment method the desired number of times.
116   */
117
118  while ( value > _Thread_Dispatch_disable_level ) {
119    _Thread_Dispatch_increment_disable_level();
120  }
121
122  /*
123   * If we need the dispatch level to go lower
124   * call increment method the desired number of times.
125   */
126
127  while ( value < _Thread_Dispatch_disable_level ) {
128    _Thread_Dispatch_decrement_disable_level();
129  }
130
131  return value;
132}
Note: See TracBrowser for help on using the repository browser.