<!-- Copyright (C) 2003 Red Hat, Inc. -->
|
<!-- Copyright (C) 2003 Red Hat, Inc. -->
|
<!-- This material may be distributed only subject to the terms -->
|
<!-- This material may be distributed only subject to the terms -->
|
<!-- and conditions set forth in the Open Publication License, v1.0 -->
|
<!-- and conditions set forth in the Open Publication License, v1.0 -->
|
<!-- or later (the latest version is presently available at -->
|
<!-- or later (the latest version is presently available at -->
|
<!-- http://www.opencontent.org/openpub/). -->
|
<!-- http://www.opencontent.org/openpub/). -->
|
<!-- Distribution of the work or derivative of the work in any -->
|
<!-- Distribution of the work or derivative of the work in any -->
|
<!-- standard (paper) book form is prohibited unless prior -->
|
<!-- standard (paper) book form is prohibited unless prior -->
|
<!-- permission is obtained from the copyright holder. -->
|
<!-- permission is obtained from the copyright holder. -->
|
<HTML
|
<HTML
|
><HEAD
|
><HEAD
|
><TITLE
|
><TITLE
|
>Thread control</TITLE
|
>Thread control</TITLE
|
><meta name="MSSmartTagsPreventParsing" content="TRUE">
|
><meta name="MSSmartTagsPreventParsing" content="TRUE">
|
<META
|
<META
|
NAME="GENERATOR"
|
NAME="GENERATOR"
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
"><LINK
|
"><LINK
|
REL="HOME"
|
REL="HOME"
|
TITLE="eCos Reference Manual"
|
TITLE="eCos Reference Manual"
|
HREF="ecos-ref.html"><LINK
|
HREF="ecos-ref.html"><LINK
|
REL="UP"
|
REL="UP"
|
TITLE="The eCos Kernel"
|
TITLE="The eCos Kernel"
|
HREF="kernel.html"><LINK
|
HREF="kernel.html"><LINK
|
REL="PREVIOUS"
|
REL="PREVIOUS"
|
TITLE="Thread information"
|
TITLE="Thread information"
|
HREF="kernel-thread-info.html"><LINK
|
HREF="kernel-thread-info.html"><LINK
|
REL="NEXT"
|
REL="NEXT"
|
TITLE="Thread termination"
|
TITLE="Thread termination"
|
HREF="kernel-thread-termination.html"></HEAD
|
HREF="kernel-thread-termination.html"></HEAD
|
><BODY
|
><BODY
|
CLASS="REFENTRY"
|
CLASS="REFENTRY"
|
BGCOLOR="#FFFFFF"
|
BGCOLOR="#FFFFFF"
|
TEXT="#000000"
|
TEXT="#000000"
|
LINK="#0000FF"
|
LINK="#0000FF"
|
VLINK="#840084"
|
VLINK="#840084"
|
ALINK="#0000FF"
|
ALINK="#0000FF"
|
><DIV
|
><DIV
|
CLASS="NAVHEADER"
|
CLASS="NAVHEADER"
|
><TABLE
|
><TABLE
|
SUMMARY="Header navigation table"
|
SUMMARY="Header navigation table"
|
WIDTH="100%"
|
WIDTH="100%"
|
BORDER="0"
|
BORDER="0"
|
CELLPADDING="0"
|
CELLPADDING="0"
|
CELLSPACING="0"
|
CELLSPACING="0"
|
><TR
|
><TR
|
><TH
|
><TH
|
COLSPAN="3"
|
COLSPAN="3"
|
ALIGN="center"
|
ALIGN="center"
|
>eCos Reference Manual</TH
|
>eCos Reference Manual</TH
|
></TR
|
></TR
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="10%"
|
WIDTH="10%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
><A
|
><A
|
HREF="kernel-thread-info.html"
|
HREF="kernel-thread-info.html"
|
ACCESSKEY="P"
|
ACCESSKEY="P"
|
>Prev</A
|
>Prev</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="80%"
|
WIDTH="80%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="10%"
|
WIDTH="10%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="bottom"
|
VALIGN="bottom"
|
><A
|
><A
|
HREF="kernel-thread-termination.html"
|
HREF="kernel-thread-termination.html"
|
ACCESSKEY="N"
|
ACCESSKEY="N"
|
>Next</A
|
>Next</A
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><HR
|
><HR
|
ALIGN="LEFT"
|
ALIGN="LEFT"
|
WIDTH="100%"></DIV
|
WIDTH="100%"></DIV
|
><H1
|
><H1
|
><A
|
><A
|
NAME="KERNEL-THREAD-CONTROL">Thread control</H1
|
NAME="KERNEL-THREAD-CONTROL">Thread control</H1
|
><DIV
|
><DIV
|
CLASS="REFNAMEDIV"
|
CLASS="REFNAMEDIV"
|
><A
|
><A
|
NAME="AEN482"
|
NAME="AEN482"
|
></A
|
></A
|
><H2
|
><H2
|
>Name</H2
|
>Name</H2
|
>cyg_thread_yield, cyg_thread_delay, cyg_thread_suspend, cyg_thread_resume, cyg_thread_release -- Control whether or not a thread is running</DIV
|
>cyg_thread_yield, cyg_thread_delay, cyg_thread_suspend, cyg_thread_resume, cyg_thread_release -- Control whether or not a thread is running</DIV
|
><DIV
|
><DIV
|
CLASS="REFSYNOPSISDIV"
|
CLASS="REFSYNOPSISDIV"
|
><A
|
><A
|
NAME="AEN489"><H2
|
NAME="AEN489"><H2
|
>Synopsis</H2
|
>Synopsis</H2
|
><DIV
|
><DIV
|
CLASS="FUNCSYNOPSIS"
|
CLASS="FUNCSYNOPSIS"
|
><A
|
><A
|
NAME="AEN490"><P
|
NAME="AEN490"><P
|
></P
|
></P
|
><TABLE
|
><TABLE
|
BORDER="5"
|
BORDER="5"
|
BGCOLOR="#E0E0F0"
|
BGCOLOR="#E0E0F0"
|
WIDTH="70%"
|
WIDTH="70%"
|
><TR
|
><TR
|
><TD
|
><TD
|
><PRE
|
><PRE
|
CLASS="FUNCSYNOPSISINFO"
|
CLASS="FUNCSYNOPSISINFO"
|
>#include <cyg/kernel/kapi.h>
|
>#include <cyg/kernel/kapi.h>
|
</PRE
|
</PRE
|
></TD
|
></TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
><P
|
><P
|
><CODE
|
><CODE
|
><CODE
|
><CODE
|
CLASS="FUNCDEF"
|
CLASS="FUNCDEF"
|
>void cyg_thread_yield</CODE
|
>void cyg_thread_yield</CODE
|
>(void);</CODE
|
>(void);</CODE
|
></P
|
></P
|
><P
|
><P
|
><CODE
|
><CODE
|
><CODE
|
><CODE
|
CLASS="FUNCDEF"
|
CLASS="FUNCDEF"
|
>void cyg_thread_delay</CODE
|
>void cyg_thread_delay</CODE
|
>(cyg_tick_count_t delay);</CODE
|
>(cyg_tick_count_t delay);</CODE
|
></P
|
></P
|
><P
|
><P
|
><CODE
|
><CODE
|
><CODE
|
><CODE
|
CLASS="FUNCDEF"
|
CLASS="FUNCDEF"
|
>void cyg_thread_suspend</CODE
|
>void cyg_thread_suspend</CODE
|
>(cyg_handle_t thread);</CODE
|
>(cyg_handle_t thread);</CODE
|
></P
|
></P
|
><P
|
><P
|
><CODE
|
><CODE
|
><CODE
|
><CODE
|
CLASS="FUNCDEF"
|
CLASS="FUNCDEF"
|
>void cyg_thread_resume</CODE
|
>void cyg_thread_resume</CODE
|
>(cyg_handle_t thread);</CODE
|
>(cyg_handle_t thread);</CODE
|
></P
|
></P
|
><P
|
><P
|
><CODE
|
><CODE
|
><CODE
|
><CODE
|
CLASS="FUNCDEF"
|
CLASS="FUNCDEF"
|
>void cyg_thread_release</CODE
|
>void cyg_thread_release</CODE
|
>(cyg_handle_t thread);</CODE
|
>(cyg_handle_t thread);</CODE
|
></P
|
></P
|
><P
|
><P
|
></P
|
></P
|
></DIV
|
></DIV
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="AEN516"
|
NAME="AEN516"
|
></A
|
></A
|
><H2
|
><H2
|
>Description</H2
|
>Description</H2
|
><P
|
><P
|
>These functions provide some control over whether or not a particular
|
>These functions provide some control over whether or not a particular
|
thread can run. Apart from the required use of
|
thread can run. Apart from the required use of
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_resume</TT
|
>cyg_thread_resume</TT
|
> to start a newly-created
|
> to start a newly-created
|
thread, application code should normally use proper synchronization
|
thread, application code should normally use proper synchronization
|
primitives such as condition variables or mail boxes.
|
primitives such as condition variables or mail boxes.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="AEN520"
|
NAME="AEN520"
|
></A
|
></A
|
><H2
|
><H2
|
>Yield</H2
|
>Yield</H2
|
><P
|
><P
|
><TT
|
><TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_yield</TT
|
>cyg_thread_yield</TT
|
> allows a thread to relinquish
|
> allows a thread to relinquish
|
control of the processor to some other runnable thread which has the
|
control of the processor to some other runnable thread which has the
|
same priority. This can have no effect on any higher-priority thread
|
same priority. This can have no effect on any higher-priority thread
|
since, if such a thread were runnable, the current thread would have
|
since, if such a thread were runnable, the current thread would have
|
been preempted in its favour. Similarly it can have no effect on any
|
been preempted in its favour. Similarly it can have no effect on any
|
lower-priority thread because the current thread will always be run in
|
lower-priority thread because the current thread will always be run in
|
preference to those. As a consequence this function is only useful
|
preference to those. As a consequence this function is only useful
|
in configurations with a scheduler that allows multiple threads to run
|
in configurations with a scheduler that allows multiple threads to run
|
at the same priority, for example the mlqueue scheduler. If instead
|
at the same priority, for example the mlqueue scheduler. If instead
|
the bitmap scheduler was being used then
|
the bitmap scheduler was being used then
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_yield()</TT
|
>cyg_thread_yield()</TT
|
> would serve no purpose.
|
> would serve no purpose.
|
</P
|
</P
|
><P
|
><P
|
>Even if a suitable scheduler such as the mlqueue scheduler has been
|
>Even if a suitable scheduler such as the mlqueue scheduler has been
|
configured, <TT
|
configured, <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_yield</TT
|
>cyg_thread_yield</TT
|
> will still rarely
|
> will still rarely
|
prove useful: instead timeslicing will be used to ensure that all
|
prove useful: instead timeslicing will be used to ensure that all
|
threads of a given priority get a fair slice of the available
|
threads of a given priority get a fair slice of the available
|
processor time. However it is possible to disable timeslicing via the
|
processor time. However it is possible to disable timeslicing via the
|
configuration option <TT
|
configuration option <TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>CYGSEM_KERNEL_SCHED_TIMESLICE</TT
|
>CYGSEM_KERNEL_SCHED_TIMESLICE</TT
|
>,
|
>,
|
in which case <TT
|
in which case <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_yield</TT
|
>cyg_thread_yield</TT
|
> can be used to
|
> can be used to
|
implement a form of cooperative multitasking.
|
implement a form of cooperative multitasking.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="AEN529"
|
NAME="AEN529"
|
></A
|
></A
|
><H2
|
><H2
|
>Delay</H2
|
>Delay</H2
|
><P
|
><P
|
><TT
|
><TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_delay</TT
|
>cyg_thread_delay</TT
|
> allows a thread to suspend until
|
> allows a thread to suspend until
|
the specified number of clock ticks have occurred. For example, if a
|
the specified number of clock ticks have occurred. For example, if a
|
value of 1 is used and the system clock runs at a frequency of 100Hz
|
value of 1 is used and the system clock runs at a frequency of 100Hz
|
then the thread will sleep for up to 10 milliseconds. This
|
then the thread will sleep for up to 10 milliseconds. This
|
functionality depends on the presence of a real-time system clock, as
|
functionality depends on the presence of a real-time system clock, as
|
controlled by the configuration option
|
controlled by the configuration option
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>CYGVAR_KERNEL_COUNTERS_CLOCK</TT
|
>CYGVAR_KERNEL_COUNTERS_CLOCK</TT
|
>.
|
>.
|
</P
|
</P
|
><P
|
><P
|
>If the application requires delays measured in milliseconds or similar
|
>If the application requires delays measured in milliseconds or similar
|
units rather than in clock ticks, some calculations are needed to
|
units rather than in clock ticks, some calculations are needed to
|
convert between these units as described in <A
|
convert between these units as described in <A
|
HREF="kernel-clocks.html"
|
HREF="kernel-clocks.html"
|
>Clocks</A
|
>Clocks</A
|
>. Usually these calculations can be done by
|
>. Usually these calculations can be done by
|
the application developer, or at compile-time. Performing such
|
the application developer, or at compile-time. Performing such
|
calculations prior to every call to
|
calculations prior to every call to
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_delay</TT
|
>cyg_thread_delay</TT
|
> adds unnecessary overhead to the
|
> adds unnecessary overhead to the
|
system.
|
system.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="AEN537"
|
NAME="AEN537"
|
></A
|
></A
|
><H2
|
><H2
|
>Suspend and Resume</H2
|
>Suspend and Resume</H2
|
><P
|
><P
|
>Associated with each thread is a suspend counter. When a thread is
|
>Associated with each thread is a suspend counter. When a thread is
|
first created this counter is initialized to 1.
|
first created this counter is initialized to 1.
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_suspend</TT
|
>cyg_thread_suspend</TT
|
> can be used to increment the
|
> can be used to increment the
|
suspend counter, and <TT
|
suspend counter, and <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_resume</TT
|
>cyg_thread_resume</TT
|
> decrements
|
> decrements
|
it. The scheduler will never run a thread with a non-zero suspend
|
it. The scheduler will never run a thread with a non-zero suspend
|
counter. Therefore a newly created thread will not run until it has
|
counter. Therefore a newly created thread will not run until it has
|
been resumed.
|
been resumed.
|
</P
|
</P
|
><P
|
><P
|
>An occasional problem with the use of suspend and resume functionality
|
>An occasional problem with the use of suspend and resume functionality
|
is that a thread gets suspended more times than it is resumed and
|
is that a thread gets suspended more times than it is resumed and
|
hence never becomes runnable again. This can lead to very confusing
|
hence never becomes runnable again. This can lead to very confusing
|
behaviour. To help with debugging such problems the kernel provides a
|
behaviour. To help with debugging such problems the kernel provides a
|
configuration option
|
configuration option
|
<TT
|
<TT
|
CLASS="VARNAME"
|
CLASS="VARNAME"
|
>CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT</TT
|
>CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT</TT
|
> which
|
> which
|
imposes an upper bound on the number of suspend calls without matching
|
imposes an upper bound on the number of suspend calls without matching
|
resumes, with a reasonable default value. This functionality depends
|
resumes, with a reasonable default value. This functionality depends
|
on infrastructure assertions being enabled.
|
on infrastructure assertions being enabled.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="AEN544"
|
NAME="AEN544"
|
></A
|
></A
|
><H2
|
><H2
|
>Releasing a Blocked Thread</H2
|
>Releasing a Blocked Thread</H2
|
><P
|
><P
|
>When a thread is blocked on a synchronization primitive such as a
|
>When a thread is blocked on a synchronization primitive such as a
|
semaphore or a mutex, or when it is waiting for an alarm to trigger,
|
semaphore or a mutex, or when it is waiting for an alarm to trigger,
|
it can be forcibly woken up using
|
it can be forcibly woken up using
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_release</TT
|
>cyg_thread_release</TT
|
>. Typically this will call the
|
>. Typically this will call the
|
affected synchronization primitive to return false, indicating that
|
affected synchronization primitive to return false, indicating that
|
the operation was not completed successfully. This function has to be
|
the operation was not completed successfully. This function has to be
|
used with great care, and in particular it should only be used on
|
used with great care, and in particular it should only be used on
|
threads that have been designed appropriately and check all return
|
threads that have been designed appropriately and check all return
|
codes. If instead it were to be used on, say, an arbitrary thread that
|
codes. If instead it were to be used on, say, an arbitrary thread that
|
is attempting to claim a mutex then that thread might not bother to
|
is attempting to claim a mutex then that thread might not bother to
|
check the result of the mutex lock operation - usually there would be
|
check the result of the mutex lock operation - usually there would be
|
no reason to do so. Therefore the thread will now continue running in
|
no reason to do so. Therefore the thread will now continue running in
|
the false belief that it has successfully claimed a mutex lock, and
|
the false belief that it has successfully claimed a mutex lock, and
|
the resulting behaviour is undefined. If the system has been built
|
the resulting behaviour is undefined. If the system has been built
|
with assertions enabled then it is possible that an assertion will
|
with assertions enabled then it is possible that an assertion will
|
trigger when the thread tries to release the mutex it does not
|
trigger when the thread tries to release the mutex it does not
|
actually own.
|
actually own.
|
</P
|
</P
|
><P
|
><P
|
>The main use of <TT
|
>The main use of <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_release</TT
|
>cyg_thread_release</TT
|
> is in the
|
> is in the
|
POSIX compatibility layer, where it is used in the implementation of
|
POSIX compatibility layer, where it is used in the implementation of
|
per-thread signals and cancellation handlers.
|
per-thread signals and cancellation handlers.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="REFSECT1"
|
CLASS="REFSECT1"
|
><A
|
><A
|
NAME="KERNEL-THREAD-CONTROL-CONTEXT"
|
NAME="KERNEL-THREAD-CONTROL-CONTEXT"
|
></A
|
></A
|
><H2
|
><H2
|
>Valid contexts</H2
|
>Valid contexts</H2
|
><P
|
><P
|
><TT
|
><TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_yield</TT
|
>cyg_thread_yield</TT
|
> can only be called from thread
|
> can only be called from thread
|
context, A DSR must always run to completion and cannot yield the
|
context, A DSR must always run to completion and cannot yield the
|
processor to some thread. <TT
|
processor to some thread. <TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_suspend</TT
|
>cyg_thread_suspend</TT
|
>,
|
>,
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_resume</TT
|
>cyg_thread_resume</TT
|
>, and
|
>, and
|
<TT
|
<TT
|
CLASS="FUNCTION"
|
CLASS="FUNCTION"
|
>cyg_thread_release</TT
|
>cyg_thread_release</TT
|
> may be called from thread or
|
> may be called from thread or
|
DSR context.
|
DSR context.
|
</P
|
</P
|
></DIV
|
></DIV
|
><DIV
|
><DIV
|
CLASS="NAVFOOTER"
|
CLASS="NAVFOOTER"
|
><HR
|
><HR
|
ALIGN="LEFT"
|
ALIGN="LEFT"
|
WIDTH="100%"><TABLE
|
WIDTH="100%"><TABLE
|
SUMMARY="Footer navigation table"
|
SUMMARY="Footer navigation table"
|
WIDTH="100%"
|
WIDTH="100%"
|
BORDER="0"
|
BORDER="0"
|
CELLPADDING="0"
|
CELLPADDING="0"
|
CELLSPACING="0"
|
CELLSPACING="0"
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="kernel-thread-info.html"
|
HREF="kernel-thread-info.html"
|
ACCESSKEY="P"
|
ACCESSKEY="P"
|
>Prev</A
|
>Prev</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="34%"
|
WIDTH="34%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="ecos-ref.html"
|
HREF="ecos-ref.html"
|
ACCESSKEY="H"
|
ACCESSKEY="H"
|
>Home</A
|
>Home</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="kernel-thread-termination.html"
|
HREF="kernel-thread-termination.html"
|
ACCESSKEY="N"
|
ACCESSKEY="N"
|
>Next</A
|
>Next</A
|
></TD
|
></TD
|
></TR
|
></TR
|
><TR
|
><TR
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="left"
|
ALIGN="left"
|
VALIGN="top"
|
VALIGN="top"
|
>Thread information</TD
|
>Thread information</TD
|
><TD
|
><TD
|
WIDTH="34%"
|
WIDTH="34%"
|
ALIGN="center"
|
ALIGN="center"
|
VALIGN="top"
|
VALIGN="top"
|
><A
|
><A
|
HREF="kernel.html"
|
HREF="kernel.html"
|
ACCESSKEY="U"
|
ACCESSKEY="U"
|
>Up</A
|
>Up</A
|
></TD
|
></TD
|
><TD
|
><TD
|
WIDTH="33%"
|
WIDTH="33%"
|
ALIGN="right"
|
ALIGN="right"
|
VALIGN="top"
|
VALIGN="top"
|
>Thread termination</TD
|
>Thread termination</TD
|
></TR
|
></TR
|
></TABLE
|
></TABLE
|
></DIV
|
></DIV
|
></BODY
|
></BODY
|
></HTML
|
></HTML
|
|
|