source: rtems/cpukit/score/src/threaddispatchdisablelevel.c @ a2e3f33

4.115
Last change on this file since a2e3f33 was a2e3f33, checked in by Sebastian Huber <sebastian.huber@…>, on 07/24/13 at 11:50:54

score: Create object implementation header

Move implementation specific parts of object.h and object.inl into new
header file objectimpl.h. The object.h contains now only the
application visible API.

  • 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_on_this_core( 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_on_this_core( 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_on_this_core( 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_on_this_core( 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.