source: rtems/cpukit/score/src/threaddispatchdisablelevel.c @ 25f5730f

4.115
Last change on this file since 25f5730f was 3380ee8, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/14 at 05:46:53

score: Use common names for per-CPU variables

Use "cpu" for an arbitrary Per_CPU_Control variable.

Use "cpu_self" for the Per_CPU_Control of the current processor.

Use "cpu_index" for an arbitrary processor index.

Use "cpu_index_self" for the processor index of the current processor.

Use "cpu_count" for the processor count obtained via
_SMP_Get_processor_count().

Use "cpu_max" for the processor maximum obtained by
rtems_configuration_get_maximum_processors().

  • 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.org/license/LICENSE.
16 */
17
18#include <rtems/score/threaddispatch.h>
19#include <rtems/score/assert.h>
20#include <rtems/score/profiling.h>
21#include <rtems/score/sysstate.h>
22
23#define NO_OWNER_CPU NULL
24
25typedef struct {
26  SMP_lock_Control lock;
27  Per_CPU_Control *owner_cpu;
28  uint32_t nest_level;
29} Giant_Control;
30
31static Giant_Control _Giant = {
32  .lock = SMP_LOCK_INITIALIZER("Giant"),
33  .owner_cpu = NO_OWNER_CPU,
34  .nest_level = 0
35};
36
37static void _Giant_Do_acquire( Per_CPU_Control *cpu_self )
38{
39  Giant_Control *giant = &_Giant;
40
41  if ( giant->owner_cpu != cpu_self ) {
42    _SMP_lock_Acquire( &giant->lock, &cpu_self->Giant_lock_context );
43    giant->owner_cpu = cpu_self;
44    giant->nest_level = 1;
45  } else {
46    ++giant->nest_level;
47  }
48}
49
50static void _Giant_Do_release( Per_CPU_Control *cpu_self )
51{
52  Giant_Control *giant = &_Giant;
53
54  --giant->nest_level;
55  if ( giant->nest_level == 0 ) {
56    giant->owner_cpu = NO_OWNER_CPU;
57    _SMP_lock_Release( &giant->lock, &cpu_self->Giant_lock_context );
58  }
59}
60
61void _Giant_Drop( Per_CPU_Control *cpu_self )
62{
63  Giant_Control *giant = &_Giant;
64
65  _Assert( _ISR_Get_level() != 0 );
66
67  if ( giant->owner_cpu == cpu_self ) {
68    giant->nest_level = 0;
69    giant->owner_cpu = NO_OWNER_CPU;
70    _SMP_lock_Release( &giant->lock, &cpu_self->Giant_lock_context );
71  }
72}
73
74uint32_t _Thread_Dispatch_increment_disable_level( void )
75{
76  ISR_Level isr_level;
77  uint32_t disable_level;
78  Per_CPU_Control *cpu_self;
79
80  _ISR_Disable_without_giant( isr_level );
81
82  /*
83   * We must obtain the processor after interrupts are disabled to prevent
84   * thread migration.
85   */
86  cpu_self = _Per_CPU_Get();
87
88  _Giant_Do_acquire( cpu_self );
89
90  disable_level = cpu_self->thread_dispatch_disable_level;
91  _Profiling_Thread_dispatch_disable( cpu_self, disable_level );
92  ++disable_level;
93  cpu_self->thread_dispatch_disable_level = disable_level;
94
95  _ISR_Enable_without_giant( isr_level );
96
97  return disable_level;
98}
99
100uint32_t _Thread_Dispatch_decrement_disable_level( void )
101{
102  ISR_Level isr_level;
103  uint32_t disable_level;
104  Per_CPU_Control *cpu_self;
105
106  _ISR_Disable_without_giant( isr_level );
107
108  cpu_self = _Per_CPU_Get();
109  disable_level = cpu_self->thread_dispatch_disable_level;
110  --disable_level;
111  cpu_self->thread_dispatch_disable_level = disable_level;
112
113  _Giant_Do_release( cpu_self );
114  _Assert( disable_level != 0 || _Giant.owner_cpu != cpu_self );
115
116  _Profiling_Thread_dispatch_enable( cpu_self, disable_level );
117  _ISR_Enable_without_giant( isr_level );
118
119  return disable_level;
120}
121
122void _Giant_Acquire( void )
123{
124  ISR_Level isr_level;
125
126  _ISR_Disable_without_giant( isr_level );
127  _Assert( _Thread_Dispatch_disable_level != 0 );
128  _Giant_Do_acquire( _Per_CPU_Get() );
129  _ISR_Enable_without_giant( isr_level );
130}
131
132void _Giant_Release( void )
133{
134  ISR_Level isr_level;
135
136  _ISR_Disable_without_giant( isr_level );
137  _Assert( _Thread_Dispatch_disable_level != 0 );
138  _Giant_Do_release( _Per_CPU_Get() );
139  _ISR_Enable_without_giant( isr_level );
140}
141
142#if defined( RTEMS_DEBUG )
143bool _Debug_Is_owner_of_giant( void )
144{
145  Giant_Control *giant = &_Giant;
146
147  return giant->owner_cpu == _Per_CPU_Get_snapshot()
148    || !_System_state_Is_up( _System_state_Get() );
149}
150#endif
Note: See TracBrowser for help on using the repository browser.