1 | Index: cpukit/score/include/rtems/score/percpu.h
|
---|
2 | ===================================================================
|
---|
3 | RCS file: /usr1/CVS/rtems/cpukit/score/include/rtems/score/percpu.h,v
|
---|
4 | retrieving revision 1.5
|
---|
5 | diff -u -r1.5 percpu.h
|
---|
6 | --- cpukit/score/include/rtems/score/percpu.h 16 Mar 2011 20:05:06 -0000 1.5
|
---|
7 | +++ cpukit/score/include/rtems/score/percpu.h 9 May 2011 16:24:57 -0000
|
---|
8 | @@ -84,18 +84,17 @@
|
---|
9 | typedef struct {
|
---|
10 | #if defined(RTEMS_SMP)
|
---|
11 | /** This element is used to lock this structure */
|
---|
12 | - SMP_lock_Control lock;
|
---|
13 | + SMP_lock_spinlock_simple_Control lock;
|
---|
14 |
|
---|
15 | /** This indicates that the CPU is online. */
|
---|
16 | - uint32_t state;
|
---|
17 | + uint32_t state;
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * This is the request for the interrupt.
|
---|
21 | *
|
---|
22 | * @note This may become a chain protected by atomic instructions.
|
---|
23 | */
|
---|
24 | - uint32_t message;
|
---|
25 | -
|
---|
26 | + uint32_t message;
|
---|
27 | #endif
|
---|
28 |
|
---|
29 | #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
|
---|
30 | Index: cpukit/score/include/rtems/score/smplock.h
|
---|
31 | ===================================================================
|
---|
32 | RCS file: /usr1/CVS/rtems/cpukit/score/include/rtems/score/smplock.h,v
|
---|
33 | retrieving revision 1.1
|
---|
34 | diff -u -r1.1 smplock.h
|
---|
35 | --- cpukit/score/include/rtems/score/smplock.h 16 Mar 2011 20:05:06 -0000 1.1
|
---|
36 | +++ cpukit/score/include/rtems/score/smplock.h 9 May 2011 16:24:57 -0000
|
---|
37 | @@ -34,10 +34,23 @@
|
---|
38 |
|
---|
39 | /**
|
---|
40 | * This type is used to lock elements for atomic access.
|
---|
41 | - *
|
---|
42 | - * @note This type may move to RTEMS.
|
---|
43 | + * This spinlock is a simple non-nesting spinlock, and
|
---|
44 | + * may be used for short non-nesting accesses.
|
---|
45 | */
|
---|
46 | -typedef volatile uint32_t SMP_lock_Control;
|
---|
47 | +typedef int SMP_lock_spinlock_simple_Control;
|
---|
48 | +
|
---|
49 | +/**
|
---|
50 | + * This type is used to lock elements for atomic access.
|
---|
51 | + * This spinlock supports nesting, but is slightly more
|
---|
52 | + * complicated to use. Please see the descriptions of
|
---|
53 | + * obtain and release prior to using in order to understand
|
---|
54 | + * the callers responsibilty of managing short interupt disable
|
---|
55 | + * times.
|
---|
56 | + */
|
---|
57 | +typedef struct {
|
---|
58 | + uint32_t count;
|
---|
59 | + int cpu_id;
|
---|
60 | +} SMP_lock_spinlock_nested_Control;
|
---|
61 |
|
---|
62 | /**
|
---|
63 | * @brief Initialize a Lock
|
---|
64 | @@ -45,12 +58,9 @@
|
---|
65 | * This method is used to initialize the lock at @a lock.
|
---|
66 | *
|
---|
67 | * @param [in] lock is the address of the lock to obtain.
|
---|
68 | - *
|
---|
69 | - * @note This lock may be "too low" here. It may need to move
|
---|
70 | - * out of the BSP area.
|
---|
71 | */
|
---|
72 | -void _SMP_lock_Spinlock_Initialize(
|
---|
73 | - SMP_lock_Control *lock
|
---|
74 | +void _SMP_lock_spinlock_simple_Initialize(
|
---|
75 | + SMP_lock_spinlock_simple_Control *lock
|
---|
76 | );
|
---|
77 |
|
---|
78 | /**
|
---|
79 | @@ -62,12 +72,9 @@
|
---|
80 | *
|
---|
81 | * @return This method returns with processor interrupts disabled.
|
---|
82 | * The previous level is returned.
|
---|
83 | - *
|
---|
84 | - * @note This lock may be "too low" here. It may need to move
|
---|
85 | - * out of the BSP area.
|
---|
86 | */
|
---|
87 | -ISR_Level _SMP_lock_Spinlock_Obtain(
|
---|
88 | - SMP_lock_Control *lock
|
---|
89 | +ISR_Level _SMP_lock_spinlock_simple_Obtain(
|
---|
90 | + SMP_lock_spinlock_simple_Control *lock
|
---|
91 | );
|
---|
92 |
|
---|
93 | /**
|
---|
94 | @@ -76,13 +83,55 @@
|
---|
95 | * This method is used to release the lock at @a lock.
|
---|
96 | *
|
---|
97 | * @param [in] lock is the address of the lock to obtain.
|
---|
98 | + */
|
---|
99 | +void _SMP_lock_spinlock_simple_Release(
|
---|
100 | + SMP_lock_spinlock_simple_Control *lock,
|
---|
101 | + ISR_Level level
|
---|
102 | +);
|
---|
103 | +
|
---|
104 | +/**
|
---|
105 | + * @brief Initialize a Lock
|
---|
106 | + *
|
---|
107 | + * This method is used to initialize the lock at @a lock.
|
---|
108 | *
|
---|
109 | - * @note This lock may be "too low" here. It may need to move
|
---|
110 | - * out of the BSP area.
|
---|
111 | + * @param [in] lock is the address of the lock to obtain.
|
---|
112 | + */
|
---|
113 | +void _SMP_lock_spinlock_nested_Spinlock_Initialize(
|
---|
114 | + SMP_lock_spinlock_nested_Control *lock
|
---|
115 | +);
|
---|
116 | +
|
---|
117 | +/**
|
---|
118 | + * @brief Obtain a Lock
|
---|
119 | + *
|
---|
120 | + * This method is used to obtain the lock at @a lock. ISR's are
|
---|
121 | + * disabled when this routine returns and it is the callers responsibility
|
---|
122 | + * to either:
|
---|
123 | + * 1) Do something very short and then call
|
---|
124 | + * _SMP_lock_spinlock_nested_Spinlock_Release or
|
---|
125 | + * 2) Do something very sort, call isr enable, then when ready
|
---|
126 | + * call isr_disable and _SMP_lock_spinlock_nested_Spinlock_Release
|
---|
127 | + *
|
---|
128 | + * @param [in] lock is the address of the lock to obtain.
|
---|
129 | + *
|
---|
130 | + * @return This method returns with processor interrupts disabled.
|
---|
131 | + * The previous level is returned.
|
---|
132 | + */
|
---|
133 | +ISR_Level _SMP_lock_spinlock_nested_Spinlock_Obtain(
|
---|
134 | + SMP_lock_spinlock_nested_Control *lock
|
---|
135 | +);
|
---|
136 | +
|
---|
137 | +/**
|
---|
138 | + * @brief Release a Lock
|
---|
139 | + *
|
---|
140 | + * This method is used to release the lock at @a lock. Note:
|
---|
141 | + * ISR's are reenabled by this method and are expected to be
|
---|
142 | + * disabled upon entry to the method.
|
---|
143 | + *
|
---|
144 | + * @param [in] lock is the address of the lock to obtain.
|
---|
145 | */
|
---|
146 | -void _SMP_lock_Spinlock_Release(
|
---|
147 | - SMP_lock_Control *lock,
|
---|
148 | - ISR_Level level
|
---|
149 | +void _SMP_lock_spinlock_nested_Spinlock_Release(
|
---|
150 | + SMP_lock_spinlock_nested_Control *lock,
|
---|
151 | + ISR_Level level
|
---|
152 | );
|
---|
153 |
|
---|
154 | #ifdef __cplusplus
|
---|
155 | Index: cpukit/score/src/smp.c
|
---|
156 | ===================================================================
|
---|
157 | RCS file: /usr1/CVS/rtems/cpukit/score/src/smp.c,v
|
---|
158 | retrieving revision 1.3
|
---|
159 | diff -u -r1.3 smp.c
|
---|
160 | --- cpukit/score/src/smp.c 27 Apr 2011 17:18:59 -0000 1.3
|
---|
161 | +++ cpukit/score/src/smp.c 9 May 2011 16:24:57 -0000
|
---|
162 | @@ -80,10 +80,10 @@
|
---|
163 |
|
---|
164 | cpu = bsp_smp_processor_id();
|
---|
165 |
|
---|
166 | - level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
167 | + level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
168 | message = _Per_CPU_Information[cpu].message;
|
---|
169 | _Per_CPU_Information[cpu].message &= ~message;
|
---|
170 | - _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
171 | + _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
172 |
|
---|
173 | #if defined(SMP_DEBUG)
|
---|
174 | {
|
---|
175 | @@ -126,9 +126,9 @@
|
---|
176 | {
|
---|
177 | ISR_Level level;
|
---|
178 |
|
---|
179 | - level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
180 | + level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
181 | _Per_CPU_Information[cpu].message |= message;
|
---|
182 | - _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
183 | + _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
184 | bsp_smp_interrupt_cpu( cpu );
|
---|
185 | }
|
---|
186 |
|
---|
187 | @@ -145,9 +145,9 @@
|
---|
188 | for ( dest_cpu=0 ; dest_cpu < _SMP_Processor_count; dest_cpu++ ) {
|
---|
189 | if ( cpu == dest_cpu )
|
---|
190 | continue;
|
---|
191 | - level = _SMP_lock_Spinlock_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
192 | + level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
|
---|
193 | _Per_CPU_Information[dest_cpu].message |= message;
|
---|
194 | - _SMP_lock_Spinlock_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
195 | + _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
|
---|
196 | }
|
---|
197 | bsp_smp_broadcast_interrupt();
|
---|
198 | }
|
---|
199 | Index: cpukit/score/src/smplock.c
|
---|
200 | ===================================================================
|
---|
201 | RCS file: /usr1/CVS/rtems/cpukit/score/src/smplock.c,v
|
---|
202 | retrieving revision 1.1
|
---|
203 | diff -u -r1.1 smplock.c
|
---|
204 | --- cpukit/score/src/smplock.c 16 Mar 2011 20:05:06 -0000 1.1
|
---|
205 | +++ cpukit/score/src/smplock.c 9 May 2011 16:24:57 -0000
|
---|
206 | @@ -15,35 +15,95 @@
|
---|
207 |
|
---|
208 | #include <rtems/system.h>
|
---|
209 | #include <rtems/score/smplock.h>
|
---|
210 | +#include <rtems/score/smp.h>
|
---|
211 |
|
---|
212 | -void _SMP_lock_Spinlock_Initialize(
|
---|
213 | - SMP_lock_Control *lock
|
---|
214 | +#define SMPLOCK_DEBUG
|
---|
215 | +
|
---|
216 | +#if defined(SMPLOCK_DEBUG)
|
---|
217 | + #include <rtems/bspIo.h>
|
---|
218 | +#endif
|
---|
219 | +
|
---|
220 | +void _SMP_lock_spinlock_simple_Initialize(
|
---|
221 | + SMP_lock_spinlock_simple_Control *lock
|
---|
222 | )
|
---|
223 | {
|
---|
224 | *lock = 0;
|
---|
225 | }
|
---|
226 |
|
---|
227 | -ISR_Level _SMP_lock_Spinlock_Obtain(
|
---|
228 | - SMP_lock_Control *lock
|
---|
229 | +ISR_Level _SMP_lock_spinlock_simple_Obtain(
|
---|
230 | + SMP_lock_spinlock_simple_Control *lock
|
---|
231 | +)
|
---|
232 | +{
|
---|
233 | + ISR_Level level;
|
---|
234 | + uint32_t value = 1;
|
---|
235 | + uint32_t previous;
|
---|
236 | +
|
---|
237 | + /* Note: Disable provides an implicit memory barrier. */
|
---|
238 | + _ISR_Disable( level );
|
---|
239 | + do {
|
---|
240 | + SMP_CPU_SWAP( lock, value, previous );
|
---|
241 | + } while (previous == 1);
|
---|
242 | +
|
---|
243 | + return level;
|
---|
244 | +}
|
---|
245 | +
|
---|
246 | +void _SMP_lock_spinlock_simple_Release(
|
---|
247 | + SMP_lock_spinlock_simple_Control *lock,
|
---|
248 | + ISR_Level level
|
---|
249 | )
|
---|
250 | {
|
---|
251 | - ISR_Level level;
|
---|
252 | + *lock = 0;
|
---|
253 | + _ISR_Enable( level );
|
---|
254 | +}
|
---|
255 | +
|
---|
256 | +void _SMP_lock_spinlock_nested_Spinlock_Initialize(
|
---|
257 | + SMP_lock_spinlock_nested_Control *lock
|
---|
258 | +)
|
---|
259 | +{
|
---|
260 | + lock->count = 0;
|
---|
261 | + lock->cpu_id = 0;
|
---|
262 | +}
|
---|
263 | +
|
---|
264 | +ISR_Level _SMP_lock_spinlock_nested_Spinlock_Obtain(
|
---|
265 | + SMP_lock_spinlock_nested_Control *lock
|
---|
266 | +)
|
---|
267 | +{
|
---|
268 | + ISR_Level level = 0;
|
---|
269 | uint32_t value = 1;
|
---|
270 | uint32_t previous;
|
---|
271 | + int cpu_id;
|
---|
272 |
|
---|
273 | /* Note: Disable provides an implicit memory barrier. */
|
---|
274 | - _ISR_Disable( level );
|
---|
275 | - do {
|
---|
276 | - SMP_CPU_SWAP( lock, value, previous );
|
---|
277 | - } while (previous == 1);
|
---|
278 | + _ISR_Disable( level );
|
---|
279 | +
|
---|
280 | + cpu_id = bsp_smp_processor_id();
|
---|
281 | +
|
---|
282 | + /* Deal with nested calls from one cpu */
|
---|
283 | + if ( (lock->count > 0) && (cpu_id == lock->cpu_id) ) {
|
---|
284 | + lock->count++;
|
---|
285 | + return level;
|
---|
286 | + }
|
---|
287 | +
|
---|
288 | + do {
|
---|
289 | + SMP_CPU_SWAP( lock, value, previous );
|
---|
290 | + } while (previous == 1);
|
---|
291 | +
|
---|
292 | + lock->count++;
|
---|
293 | + lock->cpu_id = cpu_id;
|
---|
294 | +
|
---|
295 | return level;
|
---|
296 | }
|
---|
297 |
|
---|
298 | -void _SMP_lock_Spinlock_Release(
|
---|
299 | - SMP_lock_Control *lock,
|
---|
300 | - ISR_Level level
|
---|
301 | +void _SMP_lock_spinlock_nested_Spinlock_Release(
|
---|
302 | + SMP_lock_spinlock_nested_Control *lock,
|
---|
303 | + ISR_Level level
|
---|
304 | )
|
---|
305 | {
|
---|
306 | - *lock = 0;
|
---|
307 | - _ISR_Enable( level );
|
---|
308 | +#if defined(SMPLOCK_DEBUG)
|
---|
309 | + if ( lock->count == 0 )
|
---|
310 | + printk ("Releasing spinlock when count is already zero?!?!\n");
|
---|
311 | +#endif
|
---|
312 | + lock->count--;
|
---|
313 | +
|
---|
314 | + _ISR_Enable( level );
|
---|
315 | }
|
---|