1 <!-- 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. -->
12 >Scheduler Control</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
22 TITLE="The eCos Kernel"
23 HREF="kernel.html"><LINK
26 HREF="kernel-spinlocks.html"><LINK
28 TITLE="Interrupt Handling"
29 HREF="kernel-interrupts.html"></HEAD
40 SUMMARY="Header navigation table"
49 >eCos Reference Manual</TH
57 HREF="kernel-spinlocks.html"
71 HREF="kernel-interrupts.html"
82 NAME="KERNEL-SCHEDCONTROL">Scheduler Control</H1
90 >cyg_scheduler_start, cyg_scheduler_lock, cyg_scheduler_unlock, cyg_scheduler_safe_lock, cyg_scheduler_read_lock -- Control the state of the scheduler</DIV
92 CLASS="REFSYNOPSISDIV"
108 CLASS="FUNCSYNOPSISINFO"
109 >#include <cyg/kernel/kapi.h>
118 >void cyg_scheduler_start</CODE
125 >void cyg_scheduler_lock</CODE
132 >void cyg_scheduler_unlock</CODE
139 >cyg_ucount32 cyg_scheduler_read_lock</CODE
149 NAME="KERNEL-SCHEDCONTROL-DESCRIPTION"
156 >cyg_scheduler_start</TT
157 > should only be called once,
158 to mark the end of system initialization. In typical configurations it
159 is called automatically by the system startup, but some applications
160 may bypass the standard startup in which case
163 >cyg_scheduler_start</TT
164 > will have to be called
165 explicitly. The call will enable system interrupts, allowing I/O
166 operations to commence. Then the scheduler will be invoked and control
167 will be transferred to the highest priority runnable thread. The call
171 >The various data structures inside the eCos kernel must be protected
172 against concurrent updates. Consider a call to
175 >cyg_semaphore_post</TT
176 > which causes a thread to be
177 woken up: the semaphore data structure must be updated to remove the
178 thread from its queue; the scheduler data structure must also be
179 updated to mark the thread as runnable; it is possible that the newly
180 runnable thread has a higher priority than the current one, in which
181 case preemption is required. If in the middle of the semaphore post
182 call an interrupt occurred and the interrupt handler tried to
183 manipulate the same data structures, for example by making another
184 thread runnable, then it is likely that the structures will be left in
185 an inconsistent state and the system will fail.
188 >To prevent such problems the kernel contains a special lock known as
189 the scheduler lock. A typical kernel function such as
192 >cyg_semaphore_post</TT
193 > will claim the scheduler lock,
194 do all its manipulation of kernel data structures, and then release
195 the scheduler lock. The current thread cannot be preempted while it
196 holds the scheduler lock. If an interrupt occurs and a DSR is supposed
197 to run to signal that some event has occurred, that DSR is postponed
198 until the scheduler unlock operation. This prevents concurrent updates
199 of kernel data structures.
202 >The kernel exports three routines for manipulating the scheduler lock.
205 >cyg_scheduler_lock</TT
206 > can be called to claim the
207 lock. On return it is guaranteed that the current thread will not be
208 preempted, and that no other code is manipulating any kernel data
211 >cyg_scheduler_unlock</TT
213 release the lock, which may cause the current thread to be preempted.
216 >cyg_scheduler_read_lock</TT
217 > can be used to query the
218 current state of the scheduler lock. This function should never be
219 needed because well-written code should always know whether or not the
220 scheduler is currently locked, but may prove useful during debugging.
223 >The implementation of the scheduler lock involves a simple counter.
226 >cyg_scheduler_lock</TT
228 causing the counter to be incremented each time, as long as
231 >cyg_scheduler_unlock</TT
232 > is called the same number of
233 times. This behaviour is different from mutexes where an attempt by a
234 thread to lock a mutex multiple times will result in deadlock or an
238 >Typical application code should not use the scheduler lock. Instead
239 other synchronization primitives such as mutexes and semaphores should
240 be used. While the scheduler is locked the current thread cannot be
241 preempted, so any higher priority threads will not be able to run.
242 Also no DSRs can run, so device drivers may not be able to service
243 I/O requests. However there is one situation where locking the
244 scheduler is appropriate: if some data structure needs to be shared
245 between an application thread and a DSR associated with some interrupt
246 source, the thread can use the scheduler lock to prevent concurrent
247 invocations of the DSR and then safely manipulate the structure. It is
248 desirable that the scheduler lock is held for only a short period of
249 time, typically some tens of instructions. In exceptional cases there
250 may also be some performance-critical code where it is more
251 appropriate to use the scheduler lock rather than a mutex, because the
252 former is more efficient.
258 NAME="KERNEL-SCHEDCONTROL-CONTEXT"
265 >cyg_scheduler_start</TT
266 > can only be called during
267 system initialization, since it marks the end of that phase. The
268 remaining functions may be called from thread or DSR context. Locking
269 the scheduler from inside the DSR has no practical effect because the
270 lock is claimed automatically by the interrupt subsystem before
271 running DSRs, but allows functions to be shared between normal thread
280 SUMMARY="Footer navigation table"
291 HREF="kernel-spinlocks.html"
309 HREF="kernel-interrupts.html"
333 >Interrupt Handling</TD