Commit 714af18c authored by Jason Schmidlapp's avatar Jason Schmidlapp

Added documentation.

parent 062c5bc4
1. Clean up compiler #defines
8. Check NP routines.
9. Check for printfs
10. Remove -Werror from Makefiles
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>PTE on DSP/BIOS</title></head><body><br><big><big><big><span style="font-weight: bold;">PTE on DSP/BIOS</span></big></big></big><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><title></title><meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)">
<style type="text/css">
<!--
@page { size: 8.5in 11in; margin: 0.79in }
P { margin-bottom: 0.08in }
H1 { margin-bottom: 0.08in }
H1.western { font-family: "Helvetica"; font-size: 16pt }
H1.cjk { font-family: "AR PL ShanHeiSun Uni"; font-size: 16pt }
H1.ctl { font-family: "Tahoma"; font-size: 16pt }
H2 { margin-bottom: 0.08in }
H2.western { font-family: "Helvetica"; font-size: 14pt; font-style: italic }
H2.cjk { font-family: "AR PL ShanHeiSun Uni"; font-size: 14pt; font-style: italic }
H2.ctl { font-size: 14pt; font-style: italic }
-->
</style>
<p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">The DSP/BIOS OSAL is relatively
straightforward and maps relatively cleanly to the DSP/BIOS API. For
instance, most mutex and semaphore operations are supported directly
using the LCK and SEM API's. Specific details and exceptions are
described below.</p>
<h1 class="western">Threads</h1>
<h2 class="western">Thread creation</h2>
<p>OsThreadCreate allocates a dspbiosThreadData structure that
contains semaphores used for joining to a thread, cancelling a thread
and the initial priority requested by the user. A pointer to this
structure is stored as a TLS value.
</p>
<p>OsThreadCreate must create threads in a suspended state. In
DSP/BIOS this is done by setting the initial priority to zero. The
initial priority is stored in the per thread control data. When
OsThreadStart is called, it retrieves the initial priority from the
control data attached to the thread and then sets the priority of the
thread, which starts execution.</p>
<h2 class="western">Thread termination</h2>
<p>In order for pthread_join to wait for a thread, OsThreadWaitForEnd
is called. Since DSP/BIOS doesn't have a explicit system call for
this, we emulate it using a semaphore that is posted to when the
thread exits. This semaphore is saved in the per thread control
structure.</p>
<h2 class="western">Thread cleanup</h2>
<p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">The PTE library calls <font face="Courier New, monospace">OsThreadDelete</font>
to signal to the OSAL that the resources for a task can be freed.
For DSP/BIOS, this means a call to TSK_delete (task resources are <i>not</i><span style="font-style: normal;">
automatically freed by DSP/BIOS when the thread exits).</span></p>
<p style="margin-bottom: 0in; font-style: normal;"><br>
</p>
<p style="margin-bottom: 0in;"><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadDelete</span></font><span style="font-style: normal;">
will be called at a number of points. For attached threads, it will
be called when </span><font face="Courier New, monospace"><span style="font-style: normal;">pthread_join</span></font><span style="font-style: normal;">
is called and returns or when </span><font face="Courier New, monospace"><span style="font-style: normal;">pthread_detach</span></font><span style="font-style: normal;">
is called for a terminated thread. For detached threads
</span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadDelete</span></font><span style="font-style: normal;">
will be called when the thread exits.</span></p>
<p style="margin-bottom: 0in; font-style: normal;"><br>
</p>
<p style="margin-bottom: 0in;"><span style="font-style: normal;">The
problem is that </span><font face="Courier New, monospace"><span style="font-style: normal;">TSK_delete</span></font><span style="font-style: normal;">
naturally can not be called from the same context as the thread that
we're trying to free. For the first two cases (</span><font face="Courier New, monospace"><span style="font-style: normal;">pthread_join</span></font><span style="font-style: normal;">
and </span><font face="Courier New, monospace"><span style="font-style: normal;">pthread_detach</span></font><span style="font-style: normal;">)
this is not a problem as these will always be called from another
thread. However, for detached threads </span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadDelete</span></font><span style="font-style: normal;">
will be called from the same context.</span></p>
<p style="margin-bottom: 0in; font-style: normal;"><br>
</p>
<p style="margin-bottom: 0in;"><span style="font-style: normal;">To
work around it, the DSP/BIOS OSAL includes a low priority that will
clean up detached threads. If </span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadDelete</span></font><span style="font-style: normal;">
detects that it is being called from the same context, it will post a
message to a mailbox that the garbage collector thread is waiting on.
The garbage collector thread will then call </span><font face="Courier New, monospace"><span style="font-style: normal;">TSK_delete</span></font><span style="font-style: normal;">
for that thread, as well as to clean up any resources that were
allocated when the thread was created.</span></p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Thread Local Storage</h1>
<p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">TLS is implemented using the
&#8220;environment&#8221; of DSP/BIOS threads. This allows a single value to
be associated with a thread. The TLS helper routines are used to
provide full TLS functionality; these routines allocate a structure
that holds multiple TLS keys and values. The DSP/BIOS environment is
used to hold a pointer to this structure.</p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Thread Cancellation</h1>
<p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">Since DSP/BIOS does not natively
provide a way to break out of blocked operations, this functionality
is emulated using a cancellation semaphore that is stored in the per
thread control data. When the user requests that a thread be
canceled (i.e. <font face="Courier New, monospace">OsThreadCancel</font>
is called) this semaphore is posted to. In
<font face="Courier New, monospace">OsSemaphoreCancellablePend</font>,
the cancellation semaphore as well as the user semaphore are polled
(rather than blocking) and the routine returns if the cancellation
semaphore is posted to.</p>
</body></html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>POSIX Threads for embedded systems (PTE)</title>
</head><body>
<font style="font-weight: bold;" size="+2"></font><br><big style="font-family: Helvetica,Arial,sans-serif; font-weight: bold;"><big><big>POSIX Threads for embedded systems (PTE)<br><br><span style="font-weight: bold;"><span style="font-weight: bold;"></span></span></big></big></big><big style="font-family: Helvetica,Arial,sans-serif;"><big><big><small><small>PTE is an open source implementation of the <a href="http://www.unix.org/version3/ieee_std.html">POSIX API</a>
for multithreaded applications (pthreads). &nbsp;It is intended to be
used to provide a pthreads API for&nbsp;embedded operating systems that
do not natively provide a pthreads API. PTE is designed to be easily
portable to such operating systems and only relies on basic primitives
(e.g. semaphores) that are widely supported on most embedded operating
systems.<br><br>Currently, PTE has been ported to Texas Instrument's DSP/BIOS and Sony's PSP OS.<br><br><a href="http://sourceforge.net/project/showfiles.php?group_id=213842">Download</a><br><a href="mailto:jschmidlapp@users.sourceforge.net">Contact</a><span style="font-weight: bold;"><br><br><big>Documentation</big><br></span><a href="pte_users_guide.html">User's Manual</a><span style="font-weight: bold;"><span style="font-weight: bold;"><span style="font-weight: bold;"><br></span></span></span><a href="pte_porting_guide.html">Porting Guide</a><br><a href="pte_dspbios.html">Notes on DSP/BIOS port</a><br><a href="pte_psp.html">Notes on PSP OS port</a><span style="font-weight: bold;"><span style="font-weight: bold;"><span style="font-weight: bold;"><br><br><br></span></span><br><br></span></small></small></big></big></big></body></html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>PTE Porting Guide</title></head><body>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><title></title><meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)"><meta name="CHANGEDBY" content="Jason"><meta name="CHANGEDBY" content="Jason"><meta name="CHANGEDBY" content="Jason"><meta name="CHANGEDBY" content="Jason">
<style type="text/css">
<!--
@page { size: 8.5in 11in; margin: 0.79in }
P { margin-bottom: 0.08in }
H1 { margin-bottom: 0.08in }
H1.western { font-family: "Helvetica"; font-size: 16pt }
H1.cjk { font-family: "AR PL ShanHeiSun Uni"; font-size: 16pt }
H1.ctl { font-family: "Tahoma"; font-size: 16pt }
H2 { margin-bottom: 0.08in }
H3 { margin-bottom: 0.08in }
P.code-western { font-family: "Courier New", monospace }
-->
</style>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western" align="center">Pthreads-Embedded (PTE) Porting
Guide</h1>
<p>The PTE library consists of both a platform independent component,
which contains the bulk of the pthreads functionality, and a platform
specific component which connects the platform independent component
to the underlying OS. Naturally, the platform specific layer is the
only layer that needs to be modified when porting PTE.</p>
<p>The OS adaptation layer (OSAL) must provide the following
functionality:</p>
<ol><li><p>Threads</p>
</li><li><p>Semaphores</p>
</li><li><p>Mutexes</p>
</li><li><p>Atomic operations</p>
</li><li><p>Thread local storage</p>
</li></ol>
<p>The underlying OS does not necessarily have to provide all of this
functionality &#8211; it is possible for the OSAL to emulate behavior.
For instance, mutexes can be emulated using semaphores provided by
the OS. The sections below present a high level of the required
functionality as well as how it fits into a &#8220;typical&#8221; embedded
OS. Specifics such as function parameters, etc are covered in the
OSAL API reference.</p>
<h2 align="center">Threads</h2>
<h3>Thread Initialization</h3>
<p class="code-western"><b>OsThreadCreate, OsThreadStart</b></p>
<p>Thread initialization is separated into two steps: create and
start. When <font face="Courier New, monospace">OSThreadCreate</font>
is called, the OS should create a new thread, but it must be started
in a suspended state. The thread should not start executing until
<font face="Courier New, monospace">OSThreadStart</font> is called.
This separation in functionality is due necessary to avoid race
condFor instance, if the target OS supports TLS but only allows a
single TLS value, this single value could contain a pointer to a
structure that contains multiple TLS values. The PTE distribution
includes a helper file to implement this functionality
(/platform/helper/tls-helper.c). See the DSP/BIOS port for an
example of using tls-helper.c.itions in the PTE library<span style="font-style: normal;">.</span></p>
<p><span style="font-style: normal;">Since the actual prototype of an
thread entry point varies between OS and thus will more than likely
</span><i>not</i> <span style="font-style: normal;">match that used by
</span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadCreate</span></font><span style="font-style: normal;">,
it will usually be necessary to create a stub function that matches
your OS's entry point prototype. This stub function simply calls the
entry point specified by </span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadCreate</span></font>
<span style="font-style: normal;">(see DSP/BIOS and PSP-OS ports).</span></p>
<p>Typically, OsThreadCreate will also perform other initialization;
for instance to initialize TLS structures, allocate other control
resources. This of course varies depending on the target OS.
</p>
<p>Some OS's require additional parameters to start a thread. For
instance, DSP/BIOS requires the priority in order to start the
thread. Rather than pass these parameters to both <font face="Courier New, monospace">OsThreadCreate</font>
and <font face="Courier New, monospace">OsThreadStart</font>, the
OSAL should store any necessary information as thread specific values
during <font face="Courier New, monospace">OsThreadCreate</font> and
then retrieve them as necessary in <font face="Courier New, monospace">OsThreadStart</font>.</p>
<p><br><br>
</p>
<h3>Thread Destruction</h3>
<p class="code-western"><b>OsThreadExit, OsThreadDelete,
OsThreadExitAndDelete, OsThreadWaitForEnd</b></p>
<p>Thread destruction is broken into three API calls to support the
different use cases of the pthreads API. <font face="Courier New, monospace">OsThreadExit</font>
should cause the currently executing thread to stop execution;
resources should not yet be freed. This is called when a thread
exits but the thread is not detached &#8211; resource deallocation must
wait until the user calls <font face="Courier New, monospace">pthread_join</font>
(or <font face="Courier New, monospace">pthread_detach</font>) at
which point <font face="Courier New, monospace">OsThreadDelete</font>
will be called.</p>
<p>Alternatively, if a detached thread exits, thread resource
deallocation and thread termination can occur simultaneously. In
this case, <font face="Courier New, monospace">OsThreadExitAndDelete</font>
will be called.</p>
<p><font face="Courier New, monospace">OsThreadWaitForEnd</font>
should block until the specified thread exists. For OS's that do not
directly support this functionality, a semaphore can be used to
emulate this behavior (see DSP/BIOS port). Note that this call
should be cancellable &#8211; that is, it should return (even if the
target thread has not exited) if <font face="Courier New, monospace">OsThreadCancel</font>
is called.</p>
<h3>Thread Priority</h3>
<p class="code-western"><b>OsThreadSetPriority, OsThreadGetPriority,
OsThreadGetMaxPriority, OsThreadGetMinPriority</b></p>
<p>The OSAL provides the upper and lower bounds of it's priority
range when <font face="Courier New, monospace">OsThreadGetMaxPriority</font>
and <font face="Courier New, monospace">OsThreadGetMinPriority</font>
are called. The PTE library will ensure that all priorities passed
to the OSAL (e.g. through <font face="Courier New, monospace">OsThreadCreate</font>)
are within these bounds.</p>
<h3>Thread Cancellation</h3>
<p class="code-western"><b>OsThreadCancel, OsThreadCheckCancel</b></p>
<p>Currently, the PTE library only supports deferred cancellation
(see PTE notes). While the PTE library handles most of the
complexities of cancellation, there are three hooks required from the
OSAL. When <font face="Courier New, monospace">OsThreadCancel</font>
is called, it must cause <font face="Courier New, monospace">OsSemaphorePendCancellable</font>
and <font face="Courier New, monospace">OsThreadWaitForEnd </font>to
return (this function is used by the PTE library to implement pthread
cancellation points). Since most embedded OS's do not support this
kind of functionality, it can be implemented using semaphores (see
DSP/BIOS and PSP-OS ports). <font face="Courier New, monospace">OsThreadCheckCancel</font>
simply returns whether <font face="Courier New, monospace">OsThreadCancel</font>
has been called for this thread.</p>
<h3>Miscellaneous Thread Functionality</h3>
<p class="code-western"><b>OsThreadGetHandle, OsThreadSleep,
OsThreadGetMaxPriority, OsThreadGetMinPriority,
OsThreadGetDefaultPriority</b><br><br>
</p>
<h2 align="center"></h2>
<h2 style="page-break-before: always;" align="center">Semaphores</h2>
<p align="center"><br><br>
</p>
<p class="code-western"><b>OsSemaphoreCreate, OsSemaphoreDelete,
OsSemaphorePend, OsSemaphorePort</b></p>
<p>This basic semaphore functionality should map directly to almost
all embedded OS's.
</p>
<p class="code-western"><b>OsSemaphoreCancellablePend</b></p>
<p>In order to implement deferred cancellation, a &#8220;cancellable&#8221;
pend (<font face="Courier New, monospace">OsSemaphorePendCancellable</font>)
must also be supported. As discussed above,
<font face="Courier New, monospace">OsSemaphorePendCancellable</font>
must return when <font face="Courier New, monospace">OsThreadCancel</font>
has been called on the thread that is currently pending, regardless
of whether the semaphore has been posted to or not. The way that this
is implemented in other ports (e.g. DSP/BIOS and PSP-OS) is to use an
additional semaphore, and then poll on both semaphores, as shown in
the pseudo-code below:</p>
<p><font face="Courier New, monospace">loop forever:</font></p>
<p><font face="Courier New, monospace">poll main semaphore</font></p>
<p><font face="Courier New, monospace">if semaphore was posted to,
return OK</font></p>
<p><font face="Courier New, monospace">else</font></p>
<p><font face="Courier New, monospace">check timeout</font></p>
<p><font face="Courier New, monospace">if timeout has expired, return
'timed out'</font></p>
<p><font face="Courier New, monospace">else</font></p>
<p><font face="Courier New, monospace">poll cancellation semaphore </font>
</p>
<p><font face="Courier New, monospace">if cancellation semaphore has
been posted to, return 'canceled'</font></p>
<p><font face="Courier New, monospace">else</font></p>
<p><font face="Courier New, monospace">sleep for small amount of time</font></p>
<p>For instance, if the target OS supports TLS but only allows a
single TLS value, this single value could contain a pointer to a
structure that contains multiple TLS values. The PTE distribution
includes a helper file to implement this functionality
(/platform/helper/tls-helper.c). See the DSP/BIOS port for an
example of using tls-helper.c.</p>
<h2 align="center">Mutexes</h2>
<p>Mutexes are only included as an optimization as some OS's mutex
operation is much faster than semaphore operations. If the target OS
does not support mutexes, they can easily be implemented using
semaphores.</p>
<p><br><br>
</p>
<h2 align="center">Atomic operations</h2>
<p class="code-western"><b>OsAtomicExchange, OsAtomicCompareExchange,
OsAtomicExchangeIncrement, OsAtomicDecrement, OsAtomicIncrement</b></p>
<p align="left">The PTE library requires five atomic operations to be
supplied by the OSAL. Macros are used in case the target platform
supports direct assembly instructions to perform some or all of these
operations. However, under most OS's these macros will simply refer
to functions that disable interrupts and then perform the required
operations.</p>
<p><br><br>
</p>
<h2 align="center">Thread local storage</h2>
<p class="code-western"><b>OsTlsInit, OsTlsAlloc, OsTlsFree,
OsTlsSetValue, OsTlsGetValue</b></p>
<p>The OSAL must be able to allocate and free TLS keys, and retrieve
thread specific data. If the target OS does not support this level
of TLS functionality, but does have limited TLS support, it is
possible to emulate the behavior required by the PTE library.</p>
<p>For instance, if the target OS supports TLS but only allows a
single TLS value, this single value could contain a pointer to a
structure that contains multiple TLS values. The PTE distribution
includes a helper file to implement this functionality
(/platform/helper/tls-helper.c). See the DSP/BIOS port for an
example of using tls-helper.c.</p>
<p>If the OS contains no TLS support, it might still be possible to
emulate TLS functionality. See the PSP-OS port for an example of how
this can be accomplished. Be warned &#8211; it is not a pretty solution,
but it works.</p>
<p>It is important to note that TLS functionality is <i>required </i><span style="font-style: normal;">by
the PTE library &#8211; it is used for more than just the pthread TLS
functions, but is used extensively throughout the library.</span></p>
<p style="font-style: normal;">One potentially tricky issue with TLS
is how to handle the case of when pthread TLS functions are called
from non-pthread threads (i.e. pure native threads that were not
created through pthread_create). Technically, according to the
pthread spec, this should work. However, it is problematic in that
OsTlsInit would not have been called for that thread, since it is
called in response to pthread_create(). Different ports handle this
differently &#8211; see the notes for a particular ports.</p>
<h2 align="center">Miscellaneous Functionality</h2>
<p class="code-western"><b>ftime</b></p>
<p>Since pthreads uses absolute time for timeouts, the PTE library
requires the OS to supply the current time. Note that this does not
have to be the actual world time, but can be an internal timebase
(for example, since the unit started up). However, the time source
should be the same one that the caller to pthread would use.</p>
<h2 align="center">Types and Constants</h2>
<p align="left">The OSAL layer must declare a number of types and
constants.
</p>
<p align="left">The following types must be defined to map to the
appropriate OS constructs:</p>
<p class="code-western">OsThreadHandle</p>
<p class="code-western">OsSemaphoreHandle</p>
<p class="code-western">OsMutexHandle<br><br><br>
</p>
<p>The following constants must be defined:</p>
<p align="left"><font face="Courier New, monospace">OS_DEFAULT_PRIO</font>
&#8211; default priority for a created thread.</p>
<p align="left"><font face="Courier New, monospace">OS_MIN_PRIO</font>
&#8211; minimum thread priority.</p>
<p align="left"><font face="Courier New, monospace">OS_MAX_PRIO</font>
&#8211; maximum thread priority.</p>
<p align="left"><font face="Courier New, monospace">OS_MAX_SIMUL_THREADS</font>
&#8211; maximum number of threads that may be active simultaneously.</p>
<p align="left"><br><br>
</p>
<p align="left">Each port must also include a file, pte_types.h, that
defines all of the following types. This may be done by explicitly
typedef'ing the structure (for OS's that do not natively support the
type) or simply by including the appropriate header file:</p>
<p align="left"><font face="Courier New, monospace">pid_t</font></p>
<p align="left"><font face="Courier New, monospace">struct timespec</font></p>
<p align="left"><font face="Courier New, monospace">mode_t</font></p>
<p align="left"><font face="Courier New, monospace">struct timeb</font></p>
<h2 align="center">File structure</h2>
<p align="left">The OSAL layer must include a file named pte_osal.h.
This file must include pte_generic_osal.h as well as the platform
specific header file (e.g. dspbios_osal.h).</p>
</body></html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>PTE on PSP OS</title></head><body>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><title></title><meta name="GENERATOR" content="OpenOffice.org 2.3 (Linux)">
<style type="text/css">
<!--
@page { size: 8.5in 11in; margin: 0.79in }
P { margin-bottom: 0.08in }
H1 { margin-bottom: 0.08in }
H1.western { font-family: "Helvetica"; font-size: 16pt }
H1.cjk { font-family: "AR PL ShanHeiSun Uni"; font-size: 16pt }
H1.ctl { font-family: "Tahoma"; font-size: 16pt }
-->
</style>
<p style="margin-bottom: 0in;"><big><big><big><span style="font-weight: bold;">PTE on PSP OS</span></big></big></big></p><p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">All PSP OS objects that are created
require a name to be associated with them. The name must be unique
among objects that currently exist. To accomplish this, any routines
that allocate OS objects (e.g. <font face="Courier New, monospace">OsMutexCreate</font>)
keep a static local variable that acts as a counter and is
incremented every time an object is created. This value is appended
to the name of the resource. For instance &#8220;mutex04&#8221; would be the
name of the fourth mutex created.</p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Thread creation</h1>
<p><font face="Courier New, monospace">OsThreadCreate</font>
allocates a <font face="Courier New, monospace">pspThreadData</font>
structure that contains a semaphore used for cancelling a thread, the
thread's entry point and parameters to the thread's entry point. A
pointer to this structure is stored as a TLS value.</p>
<p style="margin-bottom: 0in;"><font face="Courier New, monospace">OsThreadCreate</font>
calls <font face="Courier New, monospace">sceKernelCreateThread</font>
with a entry point of <font face="Courier New, monospace">pspStubThreadEntry</font>.
The stub entry point retrieves the per thread control structure
(allocated during <font face="Courier New, monospace">OsThreadCreate</font>)
and gets the thread's real entry point and parameters and then calls
the real entry point.</p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Thread Local Storage</h1>
<p style="margin-bottom: 0in;">Unfortunately, PSP OS does not include
<b>any</b> kind of thread local storage functionality. To emulate
TLS, when a new POSIX thread is created, a structure is allocated to
contain TLS keys and values. A pointer to this structure is appended
to the thread name. For instance, a new threads name might be
&#8220;pthread10_80001234&#8221;, where 0x80001234 is the address of the TLS
structure. When a thread wants to access TLS information, it
retrieves the thread's name from the OS, parses the name to extract
the pointer and then utilizes the TLS helper library to set or get
TLS values.
</p>
<p style="margin-bottom: 0in;"><br>
</p>
<p style="margin-bottom: 0in;">Unfortunately, this mechanism only
works for threads that are created through pthread_create; it does
not work for OS threads that are using pthread calls. To emulate
this (at this for one thread) we allocate a single TLS structure
(like the ones associated with each POSIX thread). This &#8220;global&#8221;
TLS structure is used when pthread is called from a non-POSIX OS
thread. This introduces the important limitation that pthread calls
can be made from ONLY ONE non-POSIX OS thread. Behavior when calling
from multiple different non-POSIX OS threads is undefined.</p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Mutexes</h1>
<p style="margin-bottom: 0in;">PSP OS does not supply routines for
mutexes. A counting semaphore initialized to 0 is used.</p>
<p style="margin-bottom: 0in;"><br>
</p>
<h1 class="western">Thread Cancellation</h1>
<p style="margin-bottom: 0in;">Since PSP OS does not natively provide
a way to break out of blocked operations, this functionality is
emulated using a cancellation semaphore that is stored in the per
thread control data. When the user requests that a thread be
cancelled (i.e. <font face="Courier New, monospace">OsThreadCancel</font>
is called) this semaphore is posted to. In
<font face="Courier New, monospace">OsSemaphoreCancellablePend</font>,
the cancellation semaphore as well as the user semaphore are polled
(rather than blocking) and the routine returns if the cancellation
semaphore is posted to. A similar technique is used for
<font face="Courier New, monospace">OsThreadWaitForEnd</font>.</p>
</body></html>
\ No newline at end of file
...@@ -75,7 +75,7 @@ type GlobalStatus { ...@@ -75,7 +75,7 @@ type GlobalStatus {
prop Visible :: 0 prop Visible :: 0
prop Writable :: 1 prop Writable :: 1
} }
global DATE :: "Fri Apr 04 06:42:26 2008" { global DATE :: "Fri Apr 04 15:41:02 2008" {
prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}" prop Type :: "{21455EA3-B96A-11cf-9BFE-0000C0AC14C7}"
prop Visible :: 0 prop Visible :: 0
prop Writable :: 0 prop Writable :: 0
......
...@@ -70,6 +70,7 @@ Source="..\..\..\tests\join0.c" ...@@ -70,6 +70,7 @@ Source="..\..\..\tests\join0.c"
Source="..\..\..\tests\join1.c" Source="..\..\..\tests\join1.c"
Source="..\..\..\tests\join2.c" Source="..\..\..\tests\join2.c"
Source="..\..\..\tests\join3.c" Source="..\..\..\tests\join3.c"
Source="..\..\..\tests\join4.c"
Source="..\..\..\tests\kill1.c" Source="..\..\..\tests\kill1.c"
Source="..\..\..\tests\mutex1.c" Source="..\..\..\tests\mutex1.c"
Source="..\..\..\tests\mutex1e.c" Source="..\..\..\tests\mutex1e.c"
...@@ -127,6 +128,8 @@ Source="..\..\..\tests\semaphore2.c" ...@@ -127,6 +128,8 @@ Source="..\..\..\tests\semaphore2.c"
Source="..\..\..\tests\semaphore3.c" Source="..\..\..\tests\semaphore3.c"
Source="..\..\..\tests\semaphore4.c" Source="..\..\..\tests\semaphore4.c"
Source="..\..\..\tests\semaphore4t.c" Source="..\..\..\tests\semaphore4t.c"
Source="..\..\..\tests\semaphore5.c"
Source="..\..\..\tests\semaphore6.c"
Source="..\..\..\tests\spin1.c" Source="..\..\..\tests\spin1.c"
Source="..\..\..\tests\spin2.c" Source="..\..\..\tests\spin2.c"
Source="..\..\..\tests\spin3.c" Source="..\..\..\tests\spin3.c"
......
/* config.h */ /* pte_types.h */
#ifndef PTE_CONFIG_H #ifndef PTE_TYPES_H
#define PTE_CONFIG_H #define PTE_TYPES_H
#include <time.h> #include <time.h>
/*********************************************************************
* Defaults: see target specific redefinitions below.
*********************************************************************/
/* We're building the pthreads-win32 library */
#define PTE_BUILD
#undef PTE_SUPPORT_ASYNC_CANCEL
typedef int pid_t; typedef int pid_t;
struct timespec struct timespec
...@@ -33,4 +24,4 @@ struct timeb ...@@ -33,4 +24,4 @@ struct timeb
short dstflag; short dstflag;
}; };
#endif #endif /* PTE_TYPES_H */
...@@ -162,7 +162,7 @@ OS_OBJS = \ ...@@ -162,7 +162,7 @@ OS_OBJS = \
OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS) OBJS = $(MUTEX_OBJS) $(MUTEXATTR_OBJS) $(THREAD_OBJS) $(SUPPORT_OBJS) $(TLS_OBJS) $(MISC_OBJS) $(SEM_OBJS) $(BARRIER_OBJS) $(SPIN_OBJS) $(CONDVAR_OBJS) $(RWLOCK_OBJS) $(CANCEL_OBJS) $(OS_OBJS)
INCDIR = INCDIR =
CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -Werror -I../.. -I../helper CFLAGS = $(GLOBAL_CFLAGS) -G0 -O2 -Wall -g -fno-strict-aliasing -I../.. -I../helper
CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX CXXFLAGS = $(CFLAGS) -fexceptions -fno-rtti -Werror -D__CLEANUP_CXX
ASFLAGS = $(CFLAGS) ASFLAGS = $(CFLAGS)
......
This diff is collapsed.
/* config.h */
#ifndef PTE_CONFIG_H
#define PTE_CONFIG_H
#include <errno.h>
#include <sys/types.h>
#include <sys/timeb.h>
#define PTE_STATIC_LIB
/*********************************************************************
* Defaults: see target specific redefinitions below.
*********************************************************************/
/* We're building the pthreads-win32 library */
#define PTE_BUILD
typedef int pid_t;
/* Define if you don't have Win32 errno. (eg. WinCE) */
//#undef NEED_ERRNO
/* Do we know about type mode_t? */
//#undef HAVE_MODE_T
//#undef HAVE_TIMEB
//#define HAVE_TIMEB
/* Define if you have the timespec struct */
//#undef HAVE_STRUCT_TIMESPEC
//#define HAVE_STRUCT_TIMESPEC
#endif
/* pte_types.h */
#ifndef PTE_TYPES_H
#define PTE_TYPES_H
#include <errno.h>
#include <sys/types.h>
#include <sys/timeb.h>
typedef int pid_t;