pte_porting_guide.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>PTE Porting Guide</title></head><body>
  3. <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">
  4. <style type="text/css">
  5. <!--
  6. @page { size: 8.5in 11in; margin: 0.79in }
  7. P { margin-bottom: 0.08in }
  8. H1 { margin-bottom: 0.08in }
  9. H1.western { font-family: "Helvetica"; font-size: 16pt }
  10. H1.cjk { font-family: "AR PL ShanHeiSun Uni"; font-size: 16pt }
  11. H1.ctl { font-family: "Tahoma"; font-size: 16pt }
  12. H2 { margin-bottom: 0.08in }
  13. H3 { margin-bottom: 0.08in }
  14. P.code-western { font-family: "Courier New", monospace }
  15. -->
  16. </style>
  17. <p style="margin-bottom: 0in;"><br>
  18. </p>
  19. <h1 class="western" align="center">Pthreads-Embedded (PTE) Porting
  20. Guide</h1>
  21. <p>The PTE library consists of both a platform independent component,
  22. which contains the bulk of the pthreads functionality, and a platform
  23. specific component which connects the platform independent component
  24. to the underlying OS. Naturally, the platform specific layer is the
  25. only layer that needs to be modified when porting PTE.</p>
  26. <p>The OS adaptation layer (OSAL) must provide the following
  27. functionality:</p>
  28. <ol><li><p>Threads</p>
  29. </li><li><p>Semaphores</p>
  30. </li><li><p>Mutexes</p>
  31. </li><li><p>Atomic operations</p>
  32. </li><li><p>Thread local storage</p>
  33. </li></ol>
  34. <p>The underlying OS does not necessarily have to provide all of this
  35. functionality &#8211; it is possible for the OSAL to emulate behavior.
  36. For instance, mutexes can be emulated using semaphores provided by
  37. the OS. The sections below present a high level of the required
  38. functionality as well as how it fits into a &#8220;typical&#8221; embedded
  39. OS. Specifics such as function parameters, etc are covered in the
  40. OSAL API reference.</p>
  41. <h2 align="center">Threads</h2>
  42. <h3>Thread Initialization</h3>
  43. <p class="code-western"><b>OsThreadCreate, OsThreadStart</b></p>
  44. <p>Thread initialization is separated into two steps: create and
  45. start. When <font face="Courier New, monospace">OSThreadCreate</font>
  46. is called, the OS should create a new thread, but it must be started
  47. in a suspended state. The thread should not start executing until
  48. <font face="Courier New, monospace">OSThreadStart</font> is called.
  49. This separation in functionality is due necessary to avoid race
  50. condFor instance, if the target OS supports TLS but only allows a
  51. single TLS value, this single value could contain a pointer to a
  52. structure that contains multiple TLS values. The PTE distribution
  53. includes a helper file to implement this functionality
  54. (/platform/helper/tls-helper.c). See the DSP/BIOS port for an
  55. example of using tls-helper.c.itions in the PTE library<span style="font-style: normal;">.</span></p>
  56. <p><span style="font-style: normal;">Since the actual prototype of an
  57. thread entry point varies between OS and thus will more than likely
  58. </span><i>not</i> <span style="font-style: normal;">match that used by
  59. </span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadCreate</span></font><span style="font-style: normal;">,
  60. it will usually be necessary to create a stub function that matches
  61. your OS's entry point prototype. This stub function simply calls the
  62. entry point specified by </span><font face="Courier New, monospace"><span style="font-style: normal;">OsThreadCreate</span></font>
  63. <span style="font-style: normal;">(see DSP/BIOS and PSP-OS ports).</span></p>
  64. <p>Typically, OsThreadCreate will also perform other initialization;
  65. for instance to initialize TLS structures, allocate other control
  66. resources. This of course varies depending on the target OS.
  67. </p>
  68. <p>Some OS's require additional parameters to start a thread. For
  69. instance, DSP/BIOS requires the priority in order to start the
  70. thread. Rather than pass these parameters to both <font face="Courier New, monospace">OsThreadCreate</font>
  71. and <font face="Courier New, monospace">OsThreadStart</font>, the
  72. OSAL should store any necessary information as thread specific values
  73. during <font face="Courier New, monospace">OsThreadCreate</font> and
  74. then retrieve them as necessary in <font face="Courier New, monospace">OsThreadStart</font>.</p>
  75. <p><br><br>
  76. </p>
  77. <h3>Thread Destruction</h3>
  78. <p class="code-western"><b>OsThreadExit, OsThreadDelete,
  79. OsThreadExitAndDelete, OsThreadWaitForEnd</b></p>
  80. <p>Thread destruction is broken into three API calls to support the
  81. different use cases of the pthreads API. <font face="Courier New, monospace">OsThreadExit</font>
  82. should cause the currently executing thread to stop execution;
  83. resources should not yet be freed. This is called when a thread
  84. exits but the thread is not detached &#8211; resource deallocation must
  85. wait until the user calls <font face="Courier New, monospace">pthread_join</font>
  86. (or <font face="Courier New, monospace">pthread_detach</font>) at
  87. which point <font face="Courier New, monospace">OsThreadDelete</font>
  88. will be called.</p>
  89. <p>Alternatively, if a detached thread exits, thread resource
  90. deallocation and thread termination can occur simultaneously. In
  91. this case, <font face="Courier New, monospace">OsThreadExitAndDelete</font>
  92. will be called.</p>
  93. <p><font face="Courier New, monospace">OsThreadWaitForEnd</font>
  94. should block until the specified thread exists. For OS's that do not
  95. directly support this functionality, a semaphore can be used to
  96. emulate this behavior (see DSP/BIOS port). Note that this call
  97. should be cancellable &#8211; that is, it should return (even if the
  98. target thread has not exited) if <font face="Courier New, monospace">OsThreadCancel</font>
  99. is called.</p>
  100. <h3>Thread Priority</h3>
  101. <p class="code-western"><b>OsThreadSetPriority, OsThreadGetPriority,
  102. OsThreadGetMaxPriority, OsThreadGetMinPriority</b></p>
  103. <p>The OSAL provides the upper and lower bounds of it's priority
  104. range when <font face="Courier New, monospace">OsThreadGetMaxPriority</font>
  105. and <font face="Courier New, monospace">OsThreadGetMinPriority</font>
  106. are called. The PTE library will ensure that all priorities passed
  107. to the OSAL (e.g. through <font face="Courier New, monospace">OsThreadCreate</font>)
  108. are within these bounds.</p>
  109. <h3>Thread Cancellation</h3>
  110. <p class="code-western"><b>OsThreadCancel, OsThreadCheckCancel</b></p>
  111. <p>Currently, the PTE library only supports deferred cancellation
  112. (see PTE notes). While the PTE library handles most of the
  113. complexities of cancellation, there are three hooks required from the
  114. OSAL. When <font face="Courier New, monospace">OsThreadCancel</font>
  115. is called, it must cause <font face="Courier New, monospace">OsSemaphorePendCancellable</font>
  116. and <font face="Courier New, monospace">OsThreadWaitForEnd </font>to
  117. return (this function is used by the PTE library to implement pthread
  118. cancellation points). Since most embedded OS's do not support this
  119. kind of functionality, it can be implemented using semaphores (see
  120. DSP/BIOS and PSP-OS ports). <font face="Courier New, monospace">OsThreadCheckCancel</font>
  121. simply returns whether <font face="Courier New, monospace">OsThreadCancel</font>
  122. has been called for this thread.</p>
  123. <h3>Miscellaneous Thread Functionality</h3>
  124. <p class="code-western"><b>OsThreadGetHandle, OsThreadSleep,
  125. OsThreadGetMaxPriority, OsThreadGetMinPriority,
  126. OsThreadGetDefaultPriority</b><br><br>
  127. </p>
  128. <h2 align="center"></h2>
  129. <h2 style="page-break-before: always;" align="center">Semaphores</h2>
  130. <p align="center"><br><br>
  131. </p>
  132. <p class="code-western"><b>OsSemaphoreCreate, OsSemaphoreDelete,
  133. OsSemaphorePend, OsSemaphorePort</b></p>
  134. <p>This basic semaphore functionality should map directly to almost
  135. all embedded OS's.
  136. </p>
  137. <p class="code-western"><b>OsSemaphoreCancellablePend</b></p>
  138. <p>In order to implement deferred cancellation, a &#8220;cancellable&#8221;
  139. pend (<font face="Courier New, monospace">OsSemaphorePendCancellable</font>)
  140. must also be supported. As discussed above,
  141. <font face="Courier New, monospace">OsSemaphorePendCancellable</font>
  142. must return when <font face="Courier New, monospace">OsThreadCancel</font>
  143. has been called on the thread that is currently pending, regardless
  144. of whether the semaphore has been posted to or not. The way that this
  145. is implemented in other ports (e.g. DSP/BIOS and PSP-OS) is to use an
  146. additional semaphore, and then poll on both semaphores, as shown in
  147. the pseudo-code below:</p>
  148. <p><font face="Courier New, monospace">loop forever:</font></p>
  149. <p><font face="Courier New, monospace">poll main semaphore</font></p>
  150. <p><font face="Courier New, monospace">if semaphore was posted to,
  151. return OK</font></p>
  152. <p><font face="Courier New, monospace">else</font></p>
  153. <p><font face="Courier New, monospace">check timeout</font></p>
  154. <p><font face="Courier New, monospace">if timeout has expired, return
  155. 'timed out'</font></p>
  156. <p><font face="Courier New, monospace">else</font></p>
  157. <p><font face="Courier New, monospace">poll cancellation semaphore </font>
  158. </p>
  159. <p><font face="Courier New, monospace">if cancellation semaphore has
  160. been posted to, return 'canceled'</font></p>
  161. <p><font face="Courier New, monospace">else</font></p>
  162. <p><font face="Courier New, monospace">sleep for small amount of time</font></p>
  163. <p>For instance, if the target OS supports TLS but only allows a
  164. single TLS value, this single value could contain a pointer to a
  165. structure that contains multiple TLS values. The PTE distribution
  166. includes a helper file to implement this functionality
  167. (/platform/helper/tls-helper.c). See the DSP/BIOS port for an
  168. example of using tls-helper.c.</p>
  169. <h2 align="center">Mutexes</h2>
  170. <p>Mutexes are only included as an optimization as some OS's mutex
  171. operation is much faster than semaphore operations. If the target OS
  172. does not support mutexes, they can easily be implemented using
  173. semaphores.</p>
  174. <p><br><br>
  175. </p>
  176. <h2 align="center">Atomic operations</h2>
  177. <p class="code-western"><b>OsAtomicExchange, OsAtomicCompareExchange,
  178. OsAtomicExchangeIncrement, OsAtomicDecrement, OsAtomicIncrement</b></p>
  179. <p align="left">The PTE library requires five atomic operations to be
  180. supplied by the OSAL. Macros are used in case the target platform
  181. supports direct assembly instructions to perform some or all of these
  182. operations. However, under most OS's these macros will simply refer
  183. to functions that disable interrupts and then perform the required
  184. operations.</p>
  185. <p><br><br>
  186. </p>
  187. <h2 align="center">Thread local storage</h2>
  188. <p class="code-western"><b>OsTlsInit, OsTlsAlloc, OsTlsFree,
  189. OsTlsSetValue, OsTlsGetValue</b></p>
  190. <p>The OSAL must be able to allocate and free TLS keys, and retrieve
  191. thread specific data. If the target OS does not support this level
  192. of TLS functionality, but does have limited TLS support, it is
  193. possible to emulate the behavior required by the PTE library.</p>
  194. <p>For instance, if the target OS supports TLS but only allows a
  195. single TLS value, this single value could contain a pointer to a
  196. structure that contains multiple TLS values. The PTE distribution
  197. includes a helper file to implement this functionality
  198. (/platform/helper/tls-helper.c). See the DSP/BIOS port for an
  199. example of using tls-helper.c.</p>
  200. <p>If the OS contains no TLS support, it might still be possible to
  201. emulate TLS functionality. See the PSP-OS port for an example of how
  202. this can be accomplished. Be warned &#8211; it is not a pretty solution,
  203. but it works.</p>
  204. <p>It is important to note that TLS functionality is <i>required </i><span style="font-style: normal;">by
  205. the PTE library &#8211; it is used for more than just the pthread TLS
  206. functions, but is used extensively throughout the library.</span></p>
  207. <p style="font-style: normal;">One potentially tricky issue with TLS
  208. is how to handle the case of when pthread TLS functions are called
  209. from non-pthread threads (i.e. pure native threads that were not
  210. created through pthread_create). Technically, according to the
  211. pthread spec, this should work. However, it is problematic in that
  212. OsTlsInit would not have been called for that thread, since it is
  213. called in response to pthread_create(). Different ports handle this
  214. differently &#8211; see the notes for a particular ports.</p>
  215. <h2 align="center">Miscellaneous Functionality</h2>
  216. <p class="code-western"><b>ftime</b></p>
  217. <p>Since pthreads uses absolute time for timeouts, the PTE library
  218. requires the OS to supply the current time. Note that this does not
  219. have to be the actual world time, but can be an internal timebase
  220. (for example, since the unit started up). However, the time source
  221. should be the same one that the caller to pthread would use.</p>
  222. <h2 align="center">Types and Constants</h2>
  223. <p align="left">The OSAL layer must declare a number of types and
  224. constants.
  225. </p>
  226. <p align="left">The following types must be defined to map to the
  227. appropriate OS constructs:</p>
  228. <p class="code-western">OsThreadHandle</p>
  229. <p class="code-western">OsSemaphoreHandle</p>
  230. <p class="code-western">OsMutexHandle<br><br><br>
  231. </p>
  232. <p>The following constants must be defined:</p>
  233. <p align="left"><font face="Courier New, monospace">OS_DEFAULT_PRIO</font>
  234. &#8211; default priority for a created thread.</p>
  235. <p align="left"><font face="Courier New, monospace">OS_MIN_PRIO</font>
  236. &#8211; minimum thread priority.</p>
  237. <p align="left"><font face="Courier New, monospace">OS_MAX_PRIO</font>
  238. &#8211; maximum thread priority.</p>
  239. <p align="left"><font face="Courier New, monospace">OS_MAX_SIMUL_THREADS</font>
  240. &#8211; maximum number of threads that may be active simultaneously.</p>
  241. <p align="left"><br><br>
  242. </p>
  243. <p align="left">Each port must also include a file, pte_types.h, that
  244. defines all of the following types. This may be done by explicitly
  245. typedef'ing the structure (for OS's that do not natively support the
  246. type) or simply by including the appropriate header file:</p>
  247. <p align="left"><font face="Courier New, monospace">pid_t</font></p>
  248. <p align="left"><font face="Courier New, monospace">struct timespec</font></p>
  249. <p align="left"><font face="Courier New, monospace">mode_t</font></p>
  250. <p align="left"><font face="Courier New, monospace">struct timeb</font></p>
  251. <h2 align="center">File structure</h2>
  252. <p align="left">The OSAL layer must include a file named pte_osal.h.
  253. This file must include pte_generic_osal.h as well as the platform
  254. specific header file (e.g. dspbios_osal.h).</p>
  255. </body></html>