OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [kernel-spinlocks.html] - Blame information for rev 582

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 28 unneback
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2
<!-- This material may be distributed only subject to the terms      -->
3
<!-- and conditions set forth in the Open Publication License, v1.0  -->
4
<!-- or later (the latest version is presently available at          -->
5
<!-- http://www.opencontent.org/openpub/).                           -->
6
<!-- Distribution of the work or derivative of the work in any       -->
7
<!-- standard (paper) book form is prohibited unless prior           -->
8
<!-- permission is obtained from the copyright holder.               -->
9
<HTML
10
><HEAD
11
><TITLE
12
>Spinlocks</TITLE
13
><meta name="MSSmartTagsPreventParsing" content="TRUE">
14
<META
15
NAME="GENERATOR"
16
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17
"><LINK
18
REL="HOME"
19
TITLE="eCos Reference Manual"
20
HREF="ecos-ref.html"><LINK
21
REL="UP"
22
TITLE="The eCos Kernel"
23
HREF="kernel.html"><LINK
24
REL="PREVIOUS"
25
TITLE="Event Flags"
26
HREF="kernel-flags.html"><LINK
27
REL="NEXT"
28
TITLE="Scheduler Control"
29
HREF="kernel-schedcontrol.html"></HEAD
30
><BODY
31
CLASS="REFENTRY"
32
BGCOLOR="#FFFFFF"
33
TEXT="#000000"
34
LINK="#0000FF"
35
VLINK="#840084"
36
ALINK="#0000FF"
37
><DIV
38
CLASS="NAVHEADER"
39
><TABLE
40
SUMMARY="Header navigation table"
41
WIDTH="100%"
42
BORDER="0"
43
CELLPADDING="0"
44
CELLSPACING="0"
45
><TR
46
><TH
47
COLSPAN="3"
48
ALIGN="center"
49
>eCos Reference Manual</TH
50
></TR
51
><TR
52
><TD
53
WIDTH="10%"
54
ALIGN="left"
55
VALIGN="bottom"
56
><A
57
HREF="kernel-flags.html"
58
ACCESSKEY="P"
59
>Prev</A
60
></TD
61
><TD
62
WIDTH="80%"
63
ALIGN="center"
64
VALIGN="bottom"
65
></TD
66
><TD
67
WIDTH="10%"
68
ALIGN="right"
69
VALIGN="bottom"
70
><A
71
HREF="kernel-schedcontrol.html"
72
ACCESSKEY="N"
73
>Next</A
74
></TD
75
></TR
76
></TABLE
77
><HR
78
ALIGN="LEFT"
79
WIDTH="100%"></DIV
80
><H1
81
><A
82
NAME="KERNEL-SPINLOCKS">Spinlocks</H1
83
><DIV
84
CLASS="REFNAMEDIV"
85
><A
86
NAME="AEN1693"
87
></A
88
><H2
89
>Name</H2
90
>cyg_spinlock_create, cyg_spinlock_destroy, cyg_spinlock_spin, cyg_spinlock_clear, cyg_spinlock_test, cyg_spinlock_spin_intsave, cyg_spinlock_clear_intsave&nbsp;--&nbsp;Low-level Synchronization Primitive</DIV
91
><DIV
92
CLASS="REFSYNOPSISDIV"
93
><A
94
NAME="AEN1702"><H2
95
>Synopsis</H2
96
><DIV
97
CLASS="FUNCSYNOPSIS"
98
><A
99
NAME="AEN1703"><P
100
></P
101
><TABLE
102
BORDER="5"
103
BGCOLOR="#E0E0F0"
104
WIDTH="70%"
105
><TR
106
><TD
107
><PRE
108
CLASS="FUNCSYNOPSISINFO"
109
>#include &lt;cyg/kernel/kapi.h&gt;
110
        </PRE
111
></TD
112
></TR
113
></TABLE
114
><P
115
><CODE
116
><CODE
117
CLASS="FUNCDEF"
118
>void cyg_spinlock_init</CODE
119
>(cyg_spinlock_t* lock, cyg_bool_t locked);</CODE
120
></P
121
><P
122
><CODE
123
><CODE
124
CLASS="FUNCDEF"
125
>void cyg_spinlock_destroy</CODE
126
>(cyg_spinlock_t* lock);</CODE
127
></P
128
><P
129
><CODE
130
><CODE
131
CLASS="FUNCDEF"
132
>void cyg_spinlock_spin</CODE
133
>(cyg_spinlock_t* lock);</CODE
134
></P
135
><P
136
><CODE
137
><CODE
138
CLASS="FUNCDEF"
139
>void cyg_spinlock_clear</CODE
140
>(cyg_spinlock_t* lock);</CODE
141
></P
142
><P
143
><CODE
144
><CODE
145
CLASS="FUNCDEF"
146
>cyg_bool_t cyg_spinlock_try</CODE
147
>(cyg_spinlock_t* lock);</CODE
148
></P
149
><P
150
><CODE
151
><CODE
152
CLASS="FUNCDEF"
153
>cyg_bool_t cyg_spinlock_test</CODE
154
>(cyg_spinlock_t* lock);</CODE
155
></P
156
><P
157
><CODE
158
><CODE
159
CLASS="FUNCDEF"
160
>void cyg_spinlock_spin_intsave</CODE
161
>(cyg_spinlock_t* lock, cyg_addrword_t* istate);</CODE
162
></P
163
><P
164
><CODE
165
><CODE
166
CLASS="FUNCDEF"
167
>void cyg_spinlock_clear_intsave</CODE
168
>(cyg_spinlock_t* lock, cyg_addrword_t istate);</CODE
169
></P
170
><P
171
></P
172
></DIV
173
></DIV
174
><DIV
175
CLASS="REFSECT1"
176
><A
177
NAME="KERNEL-SPINLOCKS-DESCRIPTION"
178
></A
179
><H2
180
>Description</H2
181
><P
182
>Spinlocks provide an additional synchronization primitive for
183
applications running on SMP systems. They operate at a lower level
184
than the other primitives such as mutexes, and for most purposes the
185
higher-level primitives should be preferred. However there are some
186
circumstances where a spinlock is appropriate, especially when
187
interrupt handlers and threads need to share access to hardware, and
188
on SMP systems the kernel implementation itself depends on spinlocks.
189
      </P
190
><P
191
>Essentially a spinlock is just a simple flag. When code tries to claim
192
a spinlock it checks whether or not the flag is already set. If not
193
then the flag is set and the operation succeeds immediately. The exact
194
implementation of this is hardware-specific, for example it may use a
195
test-and-set instruction to guarantee the desired behaviour even if
196
several processors try to access the spinlock at the exact same time.
197
If it is not possible to claim a spinlock then the current thead spins
198
in a tight loop, repeatedly checking the flag until it is clear. This
199
behaviour is very different from other synchronization primitives such
200
as mutexes, where contention would cause a thread to be suspended. The
201
assumption is that a spinlock will only be held for a very short time.
202
If claiming a spinlock could cause the current thread to be suspended
203
then spinlocks could not be used inside interrupt handlers, which is
204
not acceptable.
205
      </P
206
><P
207
>This does impose a constraint on any code which uses spinlocks.
208
Specifically it is important that spinlocks are held only for a short
209
period of time, typically just some dozens of instructions. Otherwise
210
another processor could be blocked on the spinlock for a long time,
211
unable to do any useful work. It is also important that a thread which
212
owns a spinlock does not get preempted because that might cause
213
another processor to spin for a whole timeslice period, or longer. One
214
way of achieving this is to disable interrupts on the current
215
processor, and the function
216
<TT
217
CLASS="FUNCTION"
218
>cyg_spinlock_spin_intsave</TT
219
> is provided to
220
facilitate this.
221
      </P
222
><P
223
>Spinlocks should not be used on single-processor systems. Consider a
224
high priority thread which attempts to claim a spinlock already held
225
by a lower priority thread: it will just loop forever and the lower
226
priority thread will never get another chance to run and release the
227
spinlock. Even if the two threads were running at the same priority,
228
the one attempting to claim the spinlock would spin until it was
229
timesliced and a lot of cpu time would be wasted. If an interrupt
230
handler tried to claim a spinlock owned by a thread, the interrupt
231
handler would loop forever. Therefore spinlocks are only appropriate
232
for SMP systems where the current owner of a spinlock can continue
233
running on a different processor.
234
      </P
235
><P
236
>Before a spinlock can be used it must be initialized by a call to
237
<TT
238
CLASS="FUNCTION"
239
>cyg_spinlock_init</TT
240
>. This takes two arguments, a
241
pointer to a <TT
242
CLASS="FUNCTION"
243
>cyg_spinlock_t</TT
244
> data structure, and
245
a flag to specify whether the spinlock starts off locked or unlocked.
246
If a spinlock is no longer required then it can be destroyed by a call
247
to <TT
248
CLASS="FUNCTION"
249
>cyg_spinlock_destroy</TT
250
>.
251
      </P
252
><P
253
>There are two routines for claiming a spinlock:
254
<TT
255
CLASS="FUNCTION"
256
>cyg_spinlock_spin</TT
257
> and
258
<TT
259
CLASS="FUNCTION"
260
>cyg_spinlock_spin_intsave</TT
261
>. The former can be used
262
when it is known the current code will not be preempted, for example
263
because it is running in an interrupt handler or because interrupts
264
are disabled. The latter will disable interrupts in addition to
265
claiming the spinlock, so is safe to use in all circumstances. The
266
previous interrupt state is returned via the second argument, and
267
should be used in a subsequent call to
268
<TT
269
CLASS="FUNCTION"
270
>cyg_spinlock_clear_intsave</TT
271
>.
272
      </P
273
><P
274
>Similarly there are two routines for releasing a spinlock:
275
<TT
276
CLASS="FUNCTION"
277
>cyg_spinlock_clear</TT
278
> and
279
<TT
280
CLASS="FUNCTION"
281
>cyg_spinlock_clear_intsave</TT
282
>. Typically
283
the former will be used if the spinlock was claimed by a call to
284
<TT
285
CLASS="FUNCTION"
286
>cyg_spinlock_spin</TT
287
>, and the latter when
288
<TT
289
CLASS="FUNCTION"
290
>cyg_spinlock_intsave</TT
291
> was used.
292
      </P
293
><P
294
>There are two additional routines.
295
<TT
296
CLASS="FUNCTION"
297
>cyg_spinlock_try</TT
298
> is a non-blocking version of
299
<TT
300
CLASS="FUNCTION"
301
>cyg_spinlock_spin</TT
302
>: if possible the lock will be
303
claimed and the function will return <TT
304
CLASS="LITERAL"
305
>true</TT
306
>; otherwise the function
307
will return immediately with failure.
308
<TT
309
CLASS="FUNCTION"
310
>cyg_spinlock_test</TT
311
> can be used to find out whether
312
or not the spinlock is currently locked. This function must be used
313
with care because, especially on a multiprocessor system, the state of
314
the spinlock can change at any time.
315
      </P
316
><P
317
>Spinlocks should only be held for a short period of time, and
318
attempting to claim a spinlock will never cause a thread to be
319
suspended. This means that there is no need to worry about priority
320
inversion problems, and concepts such as priority ceilings and
321
inheritance do not apply.
322
      </P
323
></DIV
324
><DIV
325
CLASS="REFSECT1"
326
><A
327
NAME="KERNEL-SPINLOCKS-CONTEXT"
328
></A
329
><H2
330
>Valid contexts</H2
331
><P
332
>All of the spinlock functions can be called from any context,
333
including ISR and DSR context. Typically
334
<TT
335
CLASS="FUNCTION"
336
>cyg_spinlock_init</TT
337
> is only called during system
338
initialization.
339
      </P
340
></DIV
341
><DIV
342
CLASS="NAVFOOTER"
343
><HR
344
ALIGN="LEFT"
345
WIDTH="100%"><TABLE
346
SUMMARY="Footer navigation table"
347
WIDTH="100%"
348
BORDER="0"
349
CELLPADDING="0"
350
CELLSPACING="0"
351
><TR
352
><TD
353
WIDTH="33%"
354
ALIGN="left"
355
VALIGN="top"
356
><A
357
HREF="kernel-flags.html"
358
ACCESSKEY="P"
359
>Prev</A
360
></TD
361
><TD
362
WIDTH="34%"
363
ALIGN="center"
364
VALIGN="top"
365
><A
366
HREF="ecos-ref.html"
367
ACCESSKEY="H"
368
>Home</A
369
></TD
370
><TD
371
WIDTH="33%"
372
ALIGN="right"
373
VALIGN="top"
374
><A
375
HREF="kernel-schedcontrol.html"
376
ACCESSKEY="N"
377
>Next</A
378
></TD
379
></TR
380
><TR
381
><TD
382
WIDTH="33%"
383
ALIGN="left"
384
VALIGN="top"
385
>Event Flags</TD
386
><TD
387
WIDTH="34%"
388
ALIGN="center"
389
VALIGN="top"
390
><A
391
HREF="kernel.html"
392
ACCESSKEY="U"
393
>Up</A
394
></TD
395
><TD
396
WIDTH="33%"
397
ALIGN="right"
398
VALIGN="top"
399
>Scheduler Control</TD
400
></TR
401
></TABLE
402
></DIV
403
></BODY
404
></HTML
405
>

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.