Anonymous avatar Anonymous committed cb33328

Included fenv.h. Updated documentation.

Comments (0)

Files changed (35)

 # use glob syntax.
 syntax: glob
 
+*.pdf
 
 *.pyc
 *~
-.DS_Store
+.DS_Store
+

CS360 Lecture notes -- Setjmp and Longjmp.html

+<title>CS360 Lecture notes -- Setjmp and Longjmp</title>
+<body bgcolor=ffffff>
+<h1>CS360 Lecture notes -- Setjmp</h1>
+<UL>
+<LI><a href=http://www.cs.utk.edu/~plank>Jim Plank</a>
+<LI>Directory: <b>/home/plank/cs360/notes/Setjmp</b>
+<LI>Lecture notes:
+    <a href=http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Setjmp/lecture.html>
+    <b>
+ http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Setjmp/lecture.html
+</b></a>
+<LI> Latest revision:
+Wed Apr 28 08:40:37 EDT 2010
+</UL>
+<hr>
+
+<font color=red>
+<b>Make sure you use the makefile in the lecture note directory when 
+compiling the programs in this lecture.
+In particular, compile with compiler optimizations <i>off</i>.  I'll show some 
+of the problems that come about with optimzation at the end of the lecture notes.
+</b></font><hr>
+
+<h1>setjmp()/longjmp()</h1>
+
+<b>Setjmp()</b> and <b>longjmp()</b> are subroutines that let you 
+perform complex flow-of-control in C/Unix.  
+
+<p>One of the keys to understanding <b>setjmp()</b> and
+<b>longjmp()</b> is to understand machine layout, as
+described in the assembler and <b>malloc</b> lectures 
+of the past few weeks.
+The state of a program depends completely on the
+contents of its memory (i.e.  the code, globals,
+heap, and stack), and the contents of its
+registers.  The contents of the registers
+includes the stack pointer (<b>sp</b>), frame pointer
+(<b>fp</b>), and program counter (<b>pc</b>).  What <b>setjmp()</b> does
+is save the contents of the registers so that
+<b>longjmp()</b> can restore them later.  In this way, <b>longjmp()</b>
+``returns'' to the state of the program when <b>setjmp()</b>
+was called.  
+
+<p>Specifically:
+
+<pre>
+#include &lt;setjmp.h&gt;
+int setjmp(jmp_buf env);
+</pre>
+
+This says to save the current state of the
+registers into <b>env</b>.  If you look in
+<a href=file:/usr/include/setjmp.h><b>/usr/include/setjmp.h</b></a>,
+you'll see that
+<b>jmp_buf</b> is defined as: 
+
+<pre>
+#define _JBLEN  9
+typedef struct { int _jb[_JBLEN + 1]; } jmp_buf[1];
+</pre>
+This is an irritating way of saying that <b>jmp_buf</b> is an 
+array of <b>_JBLEN+1</b> integers.
+
+<p>So, when you call <b>setjmp()</b>, you pass it the address
+of an array of integers, and it stores the value of the
+registers in that array.  <b>Setjmp()</b> returns 0 when
+you call it in this way.  
+
+<pre>
+longjmp(jmp_buf env, int val);
+</pre>
+
+<b>Longjmp()</b> resets the registers to
+the values saved in <b>env</b>.  <i>This includes the <b>sp</b>,
+<b>fp</b> and <b>pc</b></i>.  What this means is that <b>longjmp()</b>
+doesn't return.   Instead, when you call it, you
+return as if you have just called the <b>setjmp()</b> call
+that saved <b>env</b>.  This is because the <b>pc</b> is
+restored along with the other registers.
+<b>Setjmp()</b> returns the <b>val</b> argument of <b>longjmp()</b>,
+which is not allowed to be zero (read the man
+page).  Thus, you know when <b>setjmp()</b> returns a
+non-zero value that <b>longjmp()</b> was called, and is
+returning to <b>setjmp()</b>.  
+
+<p>As an example, look at the following code (in 
+<a href=sj1.c><b>sj1.c</b></a>):
+
+<p><center><table border=3 cellpadding=3><td><pre>
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;setjmp.h&gt;
+
+main()
+{
+  jmp_buf env;
+  int i;
+
+  i = setjmp(env);
+  printf("i = %d\n", i);
+
+  if (i != 0) exit(0);
+
+  longjmp(env, 2);
+  printf("Does this line get printed?\n");
+
+}
+
+</pre></td></table></center><p>
+
+When we run this, we get:
+
+<pre>
+UNIX> <font color=darkred><b>sj1</b></font>
+i = 0
+i = 2
+UNIX>
+</pre>
+
+So, first, we call <b>setjmp()</b>, and it returns 0.
+Then we call <b>longjmp()</b> with a value of 2, which
+causes the code to return from <b>setjmp()</b> with a
+value of 2.  That value is printed out, and the
+code exits. 
+
+<p><b>Setjmp()</b> and <b>longjmp()</b> are usually used so that
+if an error is detected within a long string of
+procedure calls, the error may be dealt with
+efficiently by longjmp-ing out of the procedure that catches
+the error.  This avoids having to return from each procedure can 
+test return values.   It is basically the C way of doing for example,
+"try/catch" clauses in C++.
+<p>
+For an example,
+look at 
+<a href=sj2.c><b>sj2.c</b></a>.
+It looks to be complicated, but
+really isn't.  What happens is that there is a
+complicated series of procedure calls -- <b>proc_1</b>
+through <b>proc_4</b>.  If <b>proc_4</b>'s argument is zero,
+then it flags the error by calling <b>longjmp()</b>.
+Otherwise, things proceed normally.  As you can
+see, if you call <b>sj2</b> with all positive arguments,
+then everything is ok.  However, if you call it
+with all zeros, it will make the <b>longjmp()</b> call,
+and flag an error: 
+
+<pre>
+UNIX> <font color=darkred><b>sj2 1 2 3 4</b></font>
+proc_1(1, 2, 3, 4) = 4
+UNIX> <font color=darkred><b>sj2 0 0 0 0</b></font>
+Error -- bad value of i (0), j (0), k (0), l (0)
+UNIX>
+</pre>
+
+<hr>
+Now, <b>setjmp()</b> saves all the registers, including the <b>sp</b>
+and <b>fp</b>.
+What this means is that if you return from a procedure that 
+calls <b>setjmp()</b>, then the <b>env</b> buffer of that
+<b>setjmp()</b> will no longer be valid.  Why?  Because
+that <b>env</b> buffer contains the <b>sp</b> and <b>fp</b> of the
+calling procedure.  If that procedure returns,
+then when you restore the <b>sp</b> and <b>fp</b>, the stack
+will be in a different state than before, and you
+will have an error.  For example, look at 
+<a href=sj3.c><b>sj3.c</b></a>:
+
+<p><center><table border=3 cellpadding=3><td><pre>
+int a(char *s, jmp_buf env)
+{
+  int i;
+
+  i = setjmp(env);
+  printf("Setjmp returned -- i = %d, 0x%x\n", i, s);
+  
+  printf("s = %s\n", s);
+  return i;
+}
+
+int b(int i, jmp_buf env)
+{
+  printf("In B: i=%d.  Calling longjmp(env, i)\n", i);
+
+  longjmp(env, i);
+}
+
+main(int argc, char **argv)
+{
+  jmp_buf env;
+
+  if (a("Jim", env) != 0) exit(0);
+  b(3, env);
+}
+</pre></td></table></center><p>
+<p>When we execute it, we get the following:
+
+<pre>
+UNIX> <font color=darkred><b>sj3</b></font>
+Setjmp() returned -- i = 0
+s = Jim
+In B: i=3.  Calling longjmp(env, i)
+Setjmp() returned -- i = 3
+Segmentation fault (core dumped)
+UNIX>
+</pre>
+
+So, exactly what is happening?  When the <b>main()</b> routine is first called,
+the stack looks as follows:
+
+<pre>
+              Stack        
+        |----------------|
+        |                |
+        |                |
+        |                |
+        |                |
+        |                |
+        |                | <-------- sp
+        | env[0]         |
+        | env[1]         |
+        | env[2]         |               pc = main
+        | env[3]         |
+        | ....           |
+        | env[8]         |
+        | other stuff    | <------- fp
+        |--------------- |
+</pre>
+
+Now, <b>main()</b> calls <b>a()</b>.  First it pushes the
+arguments on the stack in reverse order, and then
+<b>jsr</b> is called, which pushes the return <b>pc</b> on the
+stack, and the old <b>fp</b>.  The <b>fp</b> and <b>sp</b> are changed
+to make an empty stack frame for <b>a()</b>: 
+
+<pre>
+                                     Stack        
+                               |----------------|
+                               |                |
+                               |                | <--------- sp, fp
+                /------------- | old fp in main |
+                |              | old pc in main |
+                |   "Jim" <--- | s = "Jim"      |
+                |         /--- | pointer to env | 
+                |         \--> | env[0]         |
+                |              | env[1]         |
+                |              | env[2]         |               pc = a
+                |              | env[3]         |
+                |              | ....           |
+                |              | env[8]         |
+                \------------> | other stuff    | 
+                               |--------------- |
+</pre>
+                    
+<p>The first thing that a() does is allocate room its local variable i:
+                    
+<pre>
+                                     Stack        
+                               |----------------|
+                               |                | <--------- sp
+                               |      i         | <--------- fp
+                /------------- | old fp in main |
+                |              | old pc in main |
+                |   "Jim" <--- | s = "Jim"      |
+                |         /--- | pointer to env | 
+                |         \--> | env[0]         |
+                |              | env[1]         |
+                |              | env[2]         |               pc = a
+                |              | env[3]         |
+                |              | ....           |
+                |              | env[8]         |
+                \------------> | other stuff    | 
+                               |--------------- |
+</pre>
+                    
+Then it calls <b>setjmp()</b>.  This saves the current state of the registers.
+In other words, it saves the current values of
+<b>sp</b>, <b>fp</b>, and <b>pc</b>.  Now, <b>a()</b> prints "<b>i = 0</b>", 
+and "<b>s = Jim</b>", and then returns to <b>main()</b>.  Now the stack
+looks as before, except that <b>env</b> is initialized
+to the state of the machine when <b>a()</b> was called: 
+
+<pre>
+                                     Stack        
+                               |----------------|
+                               |                |
+                               |                | 
+                               |                |
+                               |                |
+                               |                |
+                               |                | <----------- sp
+                               | env[0]         |
+                               | env[1]         |
+                               | env[2]         |               pc = main
+                               | env[3]         |
+                               | ....           |
+                               | env[8]         |
+                               | other stuff    | <------------ fp
+                               |--------------- |
+</pre>
+
+Now, <b>main()</b> calls <b>b()</b>, and the stack looks as follows:
+
+<pre>
+                                     Stack        
+                               |----------------|
+                               |                |
+                               |                | <--------- sp, fp
+                /------------- | old fp in main |
+                |              | old pc in main |
+                |              | i = 3          |
+                |         /--- | pointer to env | 
+                |         \--> | env[0]         |
+                |              | env[1]         |
+                |              | env[2]         |               pc = b
+                |              | env[3]         |
+                |              | ....           |
+                |              | env[8]         |
+                \------------> | other stuff    | 
+                               |--------------- |
+</pre>
+
+Then <b>longjmp()</b> is called.  The registers
+are restored to their values when <b>a()</b> called
+<b>setjmp()</b>, and the <b>pc</b> returns from <b>setjmp()</b> in <b>a()</b>.
+However, the values in the stack are the same as
+they were for <b>b()</b>: 
+
+<pre>
+                                     Stack        
+                               |----------------|
+                               |                | <--------- sp
+                               | i = 2          | <--------- fp
+                /------------- | old fp in main |
+                |              | old pc in main |
+                |              | s??    = 3     |
+                |         /--- | pointer to env | 
+                |         \--> | env[0]         |
+                |              | env[1]         |
+                |              | env[2]         |               pc = a
+                |              | env[3]         |
+                |              | ....           |
+                |              | env[8]         |
+                \------------> | other stuff    | 
+                               |--------------- |
+</pre>
+
+
+You should see the problem.  The stack is in a bad state.  In particular, 
+<b>a()</b> expects there to be a <b>(char *)</b> where <b>s</b> is,
+and instead, there is the integer value 3.  Thus,
+when it tries to print out <b>s</b>, it tries to find a 
+string at memory location 3, and dumps core.  
+
+<p>This is a very common bug with <b>setjmp()</b> and
+<b>longjmp()</b> -- to use them properly, you <i>CANNOT
+RETURN FROM THE PROCEDURE THAT CALLS <b>setjmp()</b></i>.  
+This is sometimes called "longjmp-ing up the stack."
+As you can see, this bug is subtle -- the stack
+frame for <b>b()</b> looks a lot like the stack frame
+for <b>a()</b>, and thus this bug might slip by
+unnoticed for a while.  
+
+<hr>
+
+<h1>Setjmp() and signals</h1>
+
+One of the nice things about <b>setjmp()</b> and <b>longjmp()</b> is
+that you can <b>longjmp()</b> out of a signal handler, and
+back into your program.  To do this, you should This lets you catch
+those signals again. 
+
+<p>Look at <a href=sh4.c><b>sh4.c</b></a>
+
+<p><center><table border=3 cellpadding=3><td><pre>
+int i, j;
+long T0;
+jmp_buf Env;
+
+void alarm_handler(int dummy)
+{
+  long t1;
+
+  t1 = time(0) - T0;
+  printf("%d second%s %s passed: j = %d.  i = %d\n", t1,
+     (t1 == 1) ? "" : "s", 
+     (t1 == 1) ? "has" : "have", j, i);
+  if (t1 == 8) {
+    printf("Giving up\n");
+    longjmp(Env, 1);
+  }
+  alarm(1);
+  signal(SIGALRM, alarm_handler);
+}
+
+main()
+{
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  if (setjmp(Env) != 0) {
+    printf("Gave up:  j = %d, i = %d\n", j, i);
+    exit(1);
+  }
+
+  T0 = time(0);
+
+  for (j = 0; j &lt; 10000; j++) {
+    for (i = 0; i &lt; 1000000; i++);
+  }
+}
+</pre></td></table></center><p>
+
+<p>This program <b>longjmps</b> out of
+<b>alarm_handler</b> after 8 seconds have passed, and
+then prints "<b>Gave up</b>".  Be sure you can trace
+through this program:
+<pre>
+UNIX> <font color=darkred><b>sh4</b></font>
+1 second has passed: j = 482.  i = 549695
+2 seconds have passed: j = 964.  i = 948276
+3 seconds have passed: j = 1447.  i = 322623
+4 seconds have passed: j = 1927.  i = 801765
+5 seconds have passed: j = 2410.  i = 22333
+6 seconds have passed: j = 2889.  i = 39442
+7 seconds have passed: j = 3372.  i = 219445
+8 seconds have passed: j = 3852.  i = 857985
+Giving up
+Gave up:  j = 3852, i = 857985
+UNIX> <font color=darkred><b></b></font>
+</pre>
+
+<p>
+One issue about calling <b>longjmp()</b> from a signal handler is that
+the operating system may not realize that you have left the signal handler.
+Specifically, when you are in an alarm handler, you cannot catch SIGALRM,
+
+ecause the operating system has disabled the signal.  For example, 
+<b><a href=two_alarm.c>two_alarm.c</a></b> modifies <b>sh4.c</b> to 
+put a <b>while(1)</b> loop in the alarm handler:
+<p><center><table border=3 cellpadding=3><td><pre>
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;signal.h&gt;
+#include &lt;setjmp.h&gt;
+
+int i, j;
+long T0;
+jmp_buf Env;
+
+void alarm_handler(int dummy)
+{
+  long t1;
+
+  alarm(1);
+  signal(SIGALRM, alarm_handler);
+  t1 = time(0) - T0;
+  printf("%d second%s %s passed: j = %d.  i = %d\n", t1,
+     (t1 == 1) ? "" : "s", 
+     (t1 == 1) ? "has" : "have", j, i);
+  while(1);
+}
+
+main()
+{
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  if (setjmp(Env) != 0) {
+    printf("Gave up:  j = %d, i = %d\n", j, i);
+    exit(1);
+  }
+
+  T0 = time(0);
+
+  for (j = 0; j &lt; 10000; j++) {
+    for (i = 0; i &lt; 1000000; i++);
+  }
+}
+</pre></td></table></center><p>
+
+When we run this, we only get one line of text because the operating system
+will not generate SIGALRM while it is in the alarm handler.
+<p>
+This has an interesting effect on <b>longjmp</b>.  If we <b>longjmp</b> out
+of the alarm handler, as we did in <b>sh4.c</b>, does the operating system
+know to re-enable SIGALRM?  Take a look at 
+<b><a href=two_alarm_setjmp_1.c>two_alarm_setjmp_1.c</a></b>:
+
+<p><center><table border=3 cellpadding=3><td><pre>
+int i, j;
+long T0;
+jmp_buf Env;
+
+void alarm_handler(int dummy)
+{
+  long t1;
+
+  alarm(1);
+  signal(SIGALRM, alarm_handler);
+  t1 = time(0) - T0;
+  printf("%d second%s %s passed: j = %d.  i = %d\n", t1, 
+     (t1 == 1) ? "" : "s", 
+     (t1 == 1) ? "has" : "have", j, i);
+  longjmp(Env, t1);
+}
+
+main()
+{
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  T0 = time(0);
+  j = 0;
+  i = 0;
+
+  if (setjmp(Env) == 8) {
+    printf("Gave up\n");
+    exit(0);
+  };
+
+  for (; j &lt; 10000; j++) {
+    for (; i &lt; 1000000; i++) {
+    }
+    i = 0;
+  }
+  printf("Done: Time = %d\n", time(0)-T0);
+
+}
+</pre></td></table></center><p>
+
+This is similar to <b>two_alarm.c</b>, except we <b>longjmp</b> out of the alarm
+handler, and then continue running the code.  Its output depends on the 
+implementation of the operating system.  Here it is on <b>mamba</b> (a 
+Linux box) in 2010:
+
+<pre>
+UNIX> <font color=darkred><b>two_alarm_setjmp_1</b></font>
+1 second has passed: j = 476.  i = 27986
+Done: Time = 21
+UNIX> <font color=darkred><b></b></font>
+</pre>
+
+As you can see, the operating system does not re-enable SIGALRM when we <b>longjmp()</b>
+out of the handler.  Here it is on my Macintosh (again in 2010):
+
+<pre>
+UNIX> <font color=darkred><b>two_alarm_setjmp_1</b></font>
+1 second has passed: j = 357.  i = 652488
+2 seconds have passed: j = 719.  i = 160936
+3 seconds have passed: j = 1079.  i = 682336
+4 seconds have passed: j = 1438.  i = 479525
+5 seconds have passed: j = 1797.  i = 62895
+6 seconds have passed: j = 2153.  i = 660999
+7 seconds have passed: j = 2508.  i = 813449
+8 seconds have passed: j = 2874.  i = 267243
+Gave up
+UNIX> <font color=darkred><b></b></font>
+</pre>
+
+Well, that's confusing.  In its laconic way, the <b>setjmp()</b> man page helps to clear up the
+confusion:
+
+<pre>
+NOTES
+       POSIX  does  not specify whether setjmp() will save the signal context.
+       (In System V it will not.  In 4.3BSD it will, and there is  a  function
+       _setjmp  that  will  not.)   If  you  want  to  save  signal masks, use
+       sigsetjmp().
+</pre>
+
+What this means is that the operating system maintains "signal context" for your
+process.  These are the signals that are enabled or disabled.  On some operating
+systems (like my Macintosh), this is saved in the <b>setjmp()</b> call, and on some
+(like mamba) it is not.  For consistency, there are procedures
+<b>sigsetjmp()</b> and
+<b>siglongjmp()</b>:
+
+</pre></td></table></center><p>
+int sigsetjmp(sigjmp_buf env, int savesigs);
+void siglongjmp(sigjmp_buf env, int val);
+</pre>
+
+If you call <b>sigsetjmp()</b> with <b>savesig</b> equal to one, it will save 
+the signal context and restore it on a <b>longjmp</b> call.  That allows
+you to <b>longjmp</b> out of the alarm handler.  
+<b><a href=two_alarm_setjmp_2.c>two_alarm_setjmp_2.c</a></b>
+does this and works properly on both machines:
+
+<p><center><table border=3 cellpadding=3><td><pre>
+On mamba:<hr>
+UNIX> <font color=darkred><b>two_alarm_setjmp_2</b></font>
+1 second has passed: j = 482.  i = 490170
+2 seconds have passed: j = 965.  i = 904496
+3 seconds have passed: j = 1448.  i = 956563
+4 seconds have passed: j = 1932.  i = 66736
+5 seconds have passed: j = 2415.  i = 161513
+6 seconds have passed: j = 2898.  i = 252556
+7 seconds have passed: j = 3381.  i = 157970
+8 seconds have passed: j = 3864.  i = 264384
+Gave up
+UNIX> 
+</pre></td>
+<td><pre>
+On my Macintosh:<hr>
+UNIX> <font color=darkred><b>two_alarm_setjmp_2</b></font>
+1 second has passed: j = 360.  i = 856876
+2 seconds have passed: j = 726.  i = 709024
+3 seconds have passed: j = 1086.  i = 962320
+4 seconds have passed: j = 1450.  i = 690055
+5 seconds have passed: j = 1808.  i = 32123
+6 seconds have passed: j = 2171.  i = 476472
+7 seconds have passed: j = 2533.  i = 270373
+8 seconds have passed: j = 2899.  i = 428252
+Gave up
+UNIX>
+</pre></td>
+</table></center><p>
+
+Here, mamba is faster than my Macintosh.
+
+<hr>
+<h1>Poor-man's Multithreading</h1>
+
+This example shows how to use <b>sigsetjmp()</b>/<b>siglongjmp</b>
+to implement a primitive kind of multithreading.  I include it 
+as a way to help you understand <b>sigsetjmp()</b>/<b>siglongjmp</b>.
+I don't recommend that you program this way.  In fact, I recommend
+that you do not program this way.  However, it's a nice way to 
+help you understand the calls.
+
+First, look at -- 
+<b><a href=prime_1.c>prime_1.c</a></b>:  This enumerates prime
+numbers using a very simple technique: It tests for prime number
+number <i>p</i> by checking to see if <i>p</i> is divisible by all
+numbers less than or equal to <i>sqrt(p)</i>.  If not, it is
+prime.  
+<p>
+The code is written in a "re-entrant" way -- when it is
+interrupted by SIGALRM, the alarm handler <b>siglongjmp</b>'s
+back into main, which prints out the current state of the
+generation, and then calls <b>enumerate_primes1()</b> again with
+current values.  
+
+<p><center><table border=3 cellpadding=3><td><pre>
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;signal.h&gt;
+#include &lt;setjmp.h&gt;
+
+sigjmp_buf Env;
+void alarm_handler(int dummy)
+{
+  alarm(1);
+  signal(SIGALRM, alarm_handler);
+  siglongjmp(Env, 1);
+}
+  
+void enumerate_primes1(int *current_test, int *largest_prime)
+{
+  int i;
+
+  while(1) {
+    for(i = 2; i*i &lt;= *current_test && *current_test % i != 0; i++) ;
+    if (*current_test % i != 0) *largest_prime = *current_test;
+    *current_test = *current_test + 1;
+  }
+}
+    
+main()
+{
+  int test, largest_prime;
+  int time;
+
+  test = 2;
+  largest_prime = 2;
+  
+  time = 0;
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  time += sigsetjmp(Env, 1);
+  printf("%4d   Largest Prime: %10d\n", time, largest_prime);
+  enumerate_primes1(&test, &largest_prime);
+}
+</pre></td></table></center><p>
+
+Once again, make sure you can trace through the code.  Here it is running.
+
+<pre>
+UNIX> <font color=darkred><b>prime_1</b></font>
+   0   Largest Prime:          2
+   1   Largest Prime:    1052287
+   2   Largest Prime:    1729841
+   3   Largest Prime:    2310593
+   4   Largest Prime:    2836727
+   5   Largest Prime:    3326567
+   6   Largest Prime:    3787877
+...
+</pre>
+
+A second program generates primes a little more efficiently.  It maintains a Dllist
+of all primes less than <i>p</i>, and then traverses that Dllist to see if <i>p</i>
+is divisible by any prime numbers that are less than or equal to <i>sqrt(p)</i>.
+The code is in 
+<b><a href=prime_2.c>prime_2.c</a></b>
+
+<p><center><table border=3 cellpadding=3><td><pre>
+sigjmp_buf Env;
+
+void alarm_handler(int dummy)
+{
+  alarm(1);
+  signal(SIGALRM, alarm_handler);
+  siglongjmp(Env, 1);
+}
+  
+int is_prime(int p, Dllist l)
+{
+  Dllist tmp;
+  int i;
+
+  dll_traverse(tmp, l) {
+    i = tmp-&gt;val.i;
+    if (i*i &gt; p) return 1;
+    if (p % i == 0) return 0;
+  }
+  return 1;
+}
+
+void enumerate_primes2(int *current_test, int *largest_prime, Dllist l)
+{
+
+  while(1) {
+    if (is_prime(*current_test, l)) {
+      dll_append(l, new_jval_i(*current_test));
+      *largest_prime = *current_test;
+    }
+    *current_test = *current_test + 1;
+  }
+}
+    
+main()
+{
+  int test, largest_prime;
+  int time;
+  Dllist l;
+
+  test = 2;
+  largest_prime = 2;
+  l = new_dllist();
+  
+  time = 0;
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  time += sigsetjmp(Env, 1);
+  printf("%4d   Largest Prime: %10d\n", time, largest_prime);
+  enumerate_primes2(&test, &largest_prime, l);
+}
+</pre></td></table></center><p>
+
+It generates more primes than the first program:
+
+<pre>
+UNIX> <font color=darkred><b>prime_2</b></font>
+   0   Largest Prime:          2
+   1   Largest Prime:    3262639
+   2   Largest Prime:    5595433
+   3   Largest Prime:    7650317
+   4   Largest Prime:    9531449
+   5   Largest Prime:   11299507
+   6   Largest Prime:   12981097
+....
+</pre>
+
+Finally, the program 
+<b><a href=prime_12.c>prime_12.c</a></b>
+alternates between the two prime number generators, giving
+each one second of time and printing out how many primes
+each generates at two second intervals.  Here's the 
+<b>main()</b>:
+<p><center><table border=3 cellpadding=3><td><pre>
+main()
+{
+  int test1, largest_prime1;
+  int test2, largest_prime2;
+  int time;
+  Dllist l;
+
+  test1 = 2; largest_prime1 = 2;
+  test2 = 2; largest_prime2 = 2;
+  l = new_dllist();
+  
+  time = 0;
+  signal(SIGALRM, alarm_handler);
+  alarm(1);
+
+  time += sigsetjmp(Env, 1);
+  if (time%2 == 0) {
+    printf("%4d   EP1: %10d  EP2: %10d\n", time/2, largest_prime1, largest_prime2);
+    enumerate_primes1(&test1, &largest_prime1);
+  } else {
+    enumerate_primes2(&test2, &largest_prime2, l);
+  }
+}
+</pre></td></table></center><p>
+
+When we run it, we see the the second one whups up on the first one:
+
+<pre>
+UNIX> <font color=darkred><b>prime_12</b></font>
+   0   EP1:          2  EP2:          2
+   1   EP1:    1052561  EP2:    3265061
+   2   EP1:    1729757  EP2:    5602151
+   3   EP1:    2311819  EP2:    7663367
+   4   EP1:    2839519  EP2:    9369739
+   5   EP1:    3329453  EP2:   11159677
+...
+</pre>
+
+<hr>
+<h1>There's a bug in prime_2.c and prime_12.c</h1>
+
+There's a potential bug in <b>prime_2.c</b> and <b>prime_12.c</b>.  What 
+happens if SIGALRM is generated in the middle of the <b>dll_append()</b> 
+call?  Then the list may be compromised.  While it doesn't happen in the
+examples above, it certainly can.  Just thought you should know....
+
+<hr>
+<h1>The hell of compiler optimization</h1>
+
+Try the following:
+
+<pre>
+UNIX> <font color=darkred><b>gcc -O -o sh4_opt sh4.c</b></font>
+UNIX> <font color=darkred><b>sh4_opt</b></font>
+UNIX> <font color=darkred><b></b></font>
+</pre>
+
+The compiler analyzed the main loop and decided that since it
+did nothing, it could be eliminated: 
+
+<p><center><table border=3 cellpadding=3><td><pre>
+  for (j = 0; j &lt; 10000; j++) {
+    for (i = 0; i &lt; 1000000; i++);
+  }
+</pre></td></table></center><p>
+
+While that's not a particularly bad thing, you need to be aware that 
+when the compiler optimizes, it doesn't really care about your 
+<b>setjmp()/longjmp()</b> call.s
+<p>
+Let's take a pathelogical example (one that drove me crazy during my 2010
+lecture, as I had optimization on by default and was not using the makefile):
+
+<pre>
+UNIX> <font color=darkred><b>make prime_12_opt</b></font>
+gcc -I/home/plank/cs360/include -O -o prime_12_opt prime_12.c /home/plank/cs360/objs/libfdr.a 
+UNIX> <font color=darkred><b>prime_12_opt</b></font>
+   0   EP1:          2  EP2:          2
+
+</pre>
+
+It hangs?  Let's explore: If we print out the value of <b>time</b> after the <b>setjmp</b>, we see something
+strange:
+
+<pre>
+UNIX> <font color=darkred><b>prime_12_opt</b></font>
+Time = 0
+   0   EP1:          2  EP2:          2
+Time = 1
+Time = 1
+Time = 1
+Time = 1
+...
+</pre>
+
+What????  There is an explanation.  When it optimizes, the compiler is happy to store certain 
+frequently-used variables in registers rather than on the stack.  That's where it is storing
+<b>time</b>, which means that <b>time</b> is saved during <b>setjmp()</b>, when its value is
+zero, and restored to zero at every <b>longjmp()</b> call.  Is there anything you can do about
+this?  Well, perhaps you should heed the advice of the <b>setjmp()</b> man page:
+<p>
+<pre>
+       setjmp() and sigsetjmp() make programs hard to understand and maintain.
+       If possible an alternative should be used.
+</pre>
+<p>
+So why do I teach you <b>setjmp()</b>/<b>longjmp()</b>?    First, just because you shouldn't 
+use something doesn't mean that others won't.  You should be prepared to understand <b>setjmp()</b>/<b>longjmp()</b>
+code.  Second, it's a great way to understand the interaction of registers and program state.  
+Third, it makes great dinner-time conversation.  You can thank me later....
+
     CR_ERROR_CR_EXITING = 0 /*!< Used in asserts for clarity */
 };
 
-jmp_buf             cr_g_reg_func_env;
+jmp_buf                 cr_g_reg_func_env;
 
 /** \brief Pointer to the user defined array of coroutine contexts
  *  \note For internal use only.
  */
-CR_CONTEXT*         cr_g_context        = 0;
+CR_CONTEXT*             cr_g_context        = 0;
 
 /** \brief The number of elements in the coroutine context array
  *  \note For internal use only.
  */
-uint32_t            cr_g_context_cnt    = 0;
+uint32_t                cr_g_context_cnt    = 0;
 
 /** \brief Holds the ID of the coroutine to be activated - by cr_idle
  */
-cr_id_t             cr_g_activate_id    = CR_IDLE_THREAD_ID;
+cr_id_t                 cr_g_activate_id    = CR_IDLE_THREAD_ID;
 
 /** \brief Flag that's set when CR_START is called
  *  \note For internal use only.
  */
-int32_t             cr_g_sys_started    = false;
+int32_t                 cr_g_sys_started    = false;
 
 /** \brief The ID of the coroutine that's active
  *  \note For internal use only.
  */
-cr_id_t             cr_g_current_cr_id  = CR_IDLE_THREAD_ID;
+cr_id_t                 cr_g_current_cr_id  = CR_IDLE_THREAD_ID;
 
 /** \brief The ID of the previously active coroutine
  *  \note For internal use only.
  */
-cr_id_t             cr_g_previous_cr_id  = CR_IDLE_THREAD_ID;
+cr_id_t                 cr_g_previous_cr_id  = CR_IDLE_THREAD_ID;
 
 /** \brief The total number of registered coroutines
  *  \note For internal use only.
  */
-static int32_t      cr_g_thread_cnt      = CR_THREAD_CNT_INIT;
+static int32_t          cr_g_thread_cnt      = CR_THREAD_CNT_INIT;
 
 /** \brief Find the ID of a coroutine.
  *
 #include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <fenv.h>
 #include <assert.h>
 
 #ifdef __INTEL_COMPILER
 enum {
     SETJMP_DFLT_RET_VAL         =  1,                   /*!< longjmp's required second paramter, which is setjmp's return value */
     CR_IDLE_THREAD_ID           =  0,                   /*!< ID of the system's cr_idle coroutine */
-    CR_SYSTEM_STARTED           = -1,                   /*!< Sentinal flag used internall */
+    CR_SYSTEM_STARTED           = -1,                   /*!< Sentinal flag used internally */
     CR_INVALID_ID               = -1,                   /*!< Returned by cr_get_id when an ID is not found */
     CR_THREAD_CNT_INIT          = -1                    /*!< Internal initialization value */
 };
  *  \attention This macro should be placed at the start of the function being
  *  registered as a coroutine. Also, a coroutine should never return normally.
  */
-#define CR_THREAD_INIT( )                                         	\
-            static cr_id_t this_id__;                             	\
-            this_id__ = cr_g_current_cr_id;                      	\
-            if ( !setjmp( cr_g_context[ this_id__ ].env ) ) {		\
-                longjmp( cr_g_reg_func_env, SETJMP_DFLT_RET_VAL );	\
+#define CR_THREAD_INIT( )                                               \
+            static cr_id_t this_id__;                                   \
+            this_id__ = cr_g_current_cr_id;                             \
+            if ( !setjmp( cr_g_context[ this_id__ ].env ) ) {           \
+                longjmp( cr_g_reg_func_env, SETJMP_DFLT_RET_VAL );      \
             } else { /* explicit block for the longjmp */ ; }
 
 /** \brief Starts the cr_lib system
  *  \hideinitializer
  *  \attention cr_init must have been called and coroutine registration completed
  */
-#define CR_START( func_name )                                                                           		\
-            cr_g_previous_cr_id = CR_INVALID_ID;                                                        		\
-            cr_g_current_cr_id = cr_get_id( func_name );                                                		\
-            assert( ( cr_g_current_cr_id != CR_INVALID_ID ) && "CR_START:  CR_INVALID_ID!\n" );					\
-            assert( ( ( uint32_t ) cr_g_current_cr_id < cr_g_context_cnt ) && "CR_START: ID out of bounds!\n" );\
-            cr_g_sys_started = CR_SYSTEM_STARTED;                                                       		\
+#define CR_START( func_name )                                                                                           \
+            cr_g_previous_cr_id = CR_INVALID_ID;                                                                        \
+            cr_g_current_cr_id = cr_get_id( func_name );                                                                \
+            assert( ( cr_g_current_cr_id != CR_INVALID_ID ) && "CR_START:  CR_INVALID_ID!\n" );                         \
+            assert( ( ( uint32_t ) cr_g_current_cr_id < cr_g_context_cnt ) && "CR_START: ID out of bounds!\n" );        \
+            cr_g_sys_started = CR_SYSTEM_STARTED;                                                                       \
             longjmp( cr_g_context[ cr_g_current_cr_id ].env, SETJMP_DFLT_RET_VAL )
 
 /** \brief Explicitly yields to a coroutine
  *  \param func_name the name of a user coroutine or cr_idle
  *  \hideinitializer
  */
-#define CR_YIELD( func_name )                                                                           		\
-            cr_g_current_cr_id = cr_get_id( func_name );                                                		\
-            assert( ( cr_g_current_cr_id != CR_INVALID_ID ) && "CR_YIELD: CR_INVALID_ID!\n" );          		\
-            assert( ( ( uint32_t ) cr_g_current_cr_id < cr_g_context_cnt) && "CR_YIELD: ID out of bounds!\n" );	\
-            assert( ( cr_g_current_cr_id != this_id__ ) && "CR_YIELD: recursive coroutine call!\n" );   		\
-            cr_g_previous_cr_id = this_id__;                                                            		\
-            if ( !setjmp( cr_g_context[ this_id__ ].env ) ) {                                           		\
-                longjmp( cr_g_context[ cr_g_current_cr_id ].env, SETJMP_DFLT_RET_VAL );                 		\
+#define CR_YIELD( func_name )                                                                                   \
+            cr_g_current_cr_id = cr_get_id( func_name );                                                        \
+            assert( ( cr_g_current_cr_id != CR_INVALID_ID ) && "CR_YIELD: CR_INVALID_ID!\n" );                  \
+            assert( ( ( uint32_t ) cr_g_current_cr_id < cr_g_context_cnt) && "CR_YIELD: ID out of bounds!\n" ); \
+            assert( ( cr_g_current_cr_id != this_id__ ) && "CR_YIELD: recursive coroutine call!\n" );           \
+            cr_g_previous_cr_id = this_id__;                                                                    \
+            if ( !setjmp( cr_g_context[ this_id__ ].env ) ) {                                                   \
+                longjmp( cr_g_context[ cr_g_current_cr_id ].env, SETJMP_DFLT_RET_VAL );                         \
             } else {  /* explicit block for the longjmp */ ; }
 
 
 #ifndef __cplusplus
     #if !defined( __DMC__ ) && !defined( _MSC_VER )
         #ifndef PREDEF_STANDARD_C_1999
-            #error "ISO C99 compiler is required for this code to compile and work properly"
+            #error "ISO C99 compiler is required for this code to compile"
         #endif
     #endif
 #endif

doxygen/html/cr_8c__incl.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  Node1 [label="cr.c",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="stdlib.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node3 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="string.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node4 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node4 [label="stdio.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node5 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node5 [label="stdbool.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node6 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node6 [label="signal.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node7 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node7 [label="cr_config.h",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr__config_8h.html"];
+  Node1 -> Node8 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node8 [label="cr.h",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html"];
+  Node8 -> Node9 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node9 [label="setjmp.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node8 -> Node10 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node10 [label="stddef.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node8 -> Node11 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node11 [label="stdint.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node8 -> Node5 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node8 -> Node12 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node12 [label="assert.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+}

doxygen/html/cr_8c__incl.md5

+e18e926639ebcc8d284bd551f534f52f

doxygen/html/cr_8c_ca6b87323f9ce0bf21b3f06209a97989_cgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#ccd73b48023970380bfdecb56483976c",tooltip="The internal system&#39;s coroutine thread."];
+  Node1 -> Node3 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#e30bdb4ef569c0678e4cb49829f11bbb",tooltip="Register a function as a coroutine thread."];
+  Node3 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+}

doxygen/html/cr_8c_ca6b87323f9ce0bf21b3f06209a97989_cgraph.md5

+03f68eb7d3bb4b729401191636a6c814

doxygen/html/cr_8c_ccd73b48023970380bfdecb56483976c_icgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#ca6b87323f9ce0bf21b3f06209a97989",tooltip="cr_lib&#39;s initialization function."];
+  Node1 -> Node3 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#e30bdb4ef569c0678e4cb49829f11bbb",tooltip="Register a function as a coroutine thread."];
+  Node3 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+}

doxygen/html/cr_8c_ccd73b48023970380bfdecb56483976c_icgraph.md5

+6ea510ba7495fde33fd014c4fa298f08

doxygen/html/cr_8c_e30bdb4ef569c0678e4cb49829f11bbb_cgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#ccd73b48023970380bfdecb56483976c",tooltip="The internal system&#39;s coroutine thread."];
+}

doxygen/html/cr_8c_e30bdb4ef569c0678e4cb49829f11bbb_cgraph.md5

+657becfcec5624c65ade75e7eb2c30f3

doxygen/html/cr_8c_e30bdb4ef569c0678e4cb49829f11bbb_icgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#ca6b87323f9ce0bf21b3f06209a97989",tooltip="cr_lib&#39;s initialization function."];
+}

doxygen/html/cr_8c_e30bdb4ef569c0678e4cb49829f11bbb_icgraph.md5

+78001acbad214ddac6bfa09a8154644b

doxygen/html/cr_8h__dep__incl.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  Node1 [label="cr.h",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr.c",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html"];
+}

doxygen/html/cr_8h__dep__incl.md5

+ed363a7538e8d84d96a18605db7a3e95

doxygen/html/cr_8h__incl.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  Node1 [label="cr.h",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="setjmp.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node3 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="stddef.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node4 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node4 [label="stdint.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node5 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node5 [label="stdbool.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+  Node1 -> Node6 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node6 [label="assert.h",height=0.2,width=0.4,color="grey75", fillcolor="white", style="filled"];
+}

doxygen/html/cr_8h__incl.md5

+18a13e88e997c8152c1beb313c5e50ed

doxygen/html/cr_8h_ca6b87323f9ce0bf21b3f06209a97989_cgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#ccd73b48023970380bfdecb56483976c",tooltip="The internal system&#39;s coroutine thread."];
+  Node1 -> Node3 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#e30bdb4ef569c0678e4cb49829f11bbb",tooltip="Register a function as a coroutine thread."];
+  Node3 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+}

doxygen/html/cr_8h_ca6b87323f9ce0bf21b3f06209a97989_cgraph.md5

+03f68eb7d3bb4b729401191636a6c814

doxygen/html/cr_8h_ccd73b48023970380bfdecb56483976c_icgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#ca6b87323f9ce0bf21b3f06209a97989",tooltip="cr_lib&#39;s initialization function."];
+  Node1 -> Node3 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node3 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#e30bdb4ef569c0678e4cb49829f11bbb",tooltip="Register a function as a coroutine thread."];
+  Node3 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+}

doxygen/html/cr_8h_ccd73b48023970380bfdecb56483976c_icgraph.md5

+6ea510ba7495fde33fd014c4fa298f08

doxygen/html/cr_8h_e30bdb4ef569c0678e4cb49829f11bbb_cgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_idle",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html#ccd73b48023970380bfdecb56483976c",tooltip="The internal system&#39;s coroutine thread."];
+}

doxygen/html/cr_8h_e30bdb4ef569c0678e4cb49829f11bbb_cgraph.md5

+657becfcec5624c65ade75e7eb2c30f3

doxygen/html/cr_8h_e30bdb4ef569c0678e4cb49829f11bbb_icgraph.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  rankdir=LR;
+  Node1 [label="cr_register_thread",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr_init",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8h.html#ca6b87323f9ce0bf21b3f06209a97989",tooltip="cr_lib&#39;s initialization function."];
+}

doxygen/html/cr_8h_e30bdb4ef569c0678e4cb49829f11bbb_icgraph.md5

+78001acbad214ddac6bfa09a8154644b

doxygen/html/cr__config_8h__dep__incl.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  Node1 [label="cr_config.h",height=0.2,width=0.4,color="black", fillcolor="grey75", style="filled" fontcolor="black"];
+  Node1 -> Node2 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node2 [label="cr.c",height=0.2,width=0.4,color="black", fillcolor="white", style="filled",URL="$cr_8c.html"];
+}

doxygen/html/cr__config_8h__dep__incl.md5

+659e8e383a442569d56365ebb143f5f6

doxygen/html/graph_legend.dot

+digraph G
+{
+  edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"];
+  node [fontname="FreeSans",fontsize="10",shape=record];
+  Node9 [shape="box",label="Inherited",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",fillcolor="grey75",style="filled" fontcolor="black"];
+  Node10 -> Node9 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node10 [shape="box",label="PublicBase",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classPublicBase.html"];
+  Node11 -> Node10 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node11 [shape="box",label="Truncated",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="red",URL="$classTruncated.html"];
+  Node13 -> Node9 [dir=back,color="darkgreen",fontsize="10",style="solid",fontname="FreeSans"];
+  Node13 [shape="box",label="ProtectedBase",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classProtectedBase.html"];
+  Node14 -> Node9 [dir=back,color="firebrick4",fontsize="10",style="solid",fontname="FreeSans"];
+  Node14 [shape="box",label="PrivateBase",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classPrivateBase.html"];
+  Node15 -> Node9 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node15 [shape="box",label="Undocumented",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="grey75"];
+  Node16 -> Node9 [dir=back,color="midnightblue",fontsize="10",style="solid",fontname="FreeSans"];
+  Node16 [shape="box",label="Templ< int >",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classTempl.html"];
+  Node17 -> Node16 [dir=back,color="orange",fontsize="10",style="dashed",label="< int >",fontname="FreeSans"];
+  Node17 [shape="box",label="Templ< T >",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classTempl.html"];
+  Node18 -> Node9 [dir=back,color="darkorchid3",fontsize="10",style="dashed",label="m_usedClass",fontname="FreeSans"];
+  Node18 [shape="box",label="Used",fontsize="10",height=0.2,width=0.4,fontname="FreeSans",color="black",URL="$classUsed.html"];
+}

doxygen/html/graph_legend.html

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+<title>cr_lib: Graph Legend</title>
+<link href="tabs.css" rel="stylesheet" type="text/css">
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.5.8 -->
+<div class="navigation" id="top">
+  <div class="tabs">
+    <ul>
+      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
+      <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+      <li><a href="files.html"><span>Files</span></a></li>
+      <li><a href="examples.html"><span>Examples</span></a></li>
+    </ul>
+  </div>
+</div>
+<div class="contents">
+<h1>Graph Legend</h1>This page explains how to interpret the graphs that are generated by doxygen.<p>
+Consider the following example: <div class="fragment"><pre class="fragment"><span class="comment">/*! Invisible class because of truncation */</span>
+<span class="keyword">class </span>Invisible { };
+<span class="comment"></span>
+<span class="comment">/*! Truncated class, inheritance relation is hidden */</span>
+<span class="keyword">class </span>Truncated : <span class="keyword">public</span> Invisible { };
+
+<span class="comment">/* Class not documented with doxygen comments */</span>
+<span class="keyword">class </span>Undocumented { };
+<span class="comment"></span>
+<span class="comment">/*! Class that is inherited using public inheritance */</span>
+<span class="keyword">class </span>PublicBase : <span class="keyword">public</span> Truncated { };
+<span class="comment"></span>
+<span class="comment">/*! A template class */</span>
+<span class="keyword">template</span>&lt;<span class="keyword">class</span> T&gt; <span class="keyword">class </span>Templ { };
+<span class="comment"></span>
+<span class="comment">/*! Class that is inherited using protected inheritance */</span>
+<span class="keyword">class </span>ProtectedBase { };
+<span class="comment"></span>
+<span class="comment">/*! Class that is inherited using private inheritance */</span>
+<span class="keyword">class </span>PrivateBase { };
+<span class="comment"></span>
+<span class="comment">/*! Class that is used by the Inherited class */</span>
+<span class="keyword">class </span>Used { };
+<span class="comment"></span>
+<span class="comment">/*! Super class that inherits a number of other classes */</span>
+<span class="keyword">class </span>Inherited : <span class="keyword">public</span> PublicBase,
+                  <span class="keyword">protected</span> ProtectedBase,
+                  <span class="keyword">private</span> PrivateBase,
+                  <span class="keyword">public</span> Undocumented,
+                  <span class="keyword">public</span> Templ&lt;int&gt;
+{
+  <span class="keyword">private</span>:
+    Used *m_usedClass;
+};
+</pre></div> This will result in the following graph:<p>
+<center><div align="center">
+<img src="graph_legend.png" alt="graph_legend.png">
+</div>
+</center> <p>
+The boxes in the above graph have the following meaning: <ul>
+<li>
+A filled gray box represents the struct or class for which the graph is generated. </li>
+<li>
+A box with a black border denotes a documented struct or class. </li>
+<li>
+A box with a grey border denotes an undocumented struct or class. </li>
+<li>
+A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries. </li>
+</ul>
+The arrows have the following meaning: <ul>
+<li>
+A dark blue arrow is used to visualize a public inheritance relation between two classes. </li>
+<li>
+A dark green arrow is used for protected inheritance. </li>
+<li>
+A dark red arrow is used for private inheritance. </li>
+<li>
+A purple dashed arrow is used if a class is contained or used by another class. The arrow is labeled with the variable(s) through which the pointed class or struct is accessible. </li>
+<li>
+A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labeled with the template parameters of the instance. </li>
+</ul>
+</div>
+<hr size="1"><address style="text-align: right;"><small>Generated on Fri May 28 09:13:09 2010 for cr_lib by&nbsp;
+<a href="http://www.doxygen.org/index.html">
+<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.8 </small></address>
+</body>
+</html>

doxygen/html/pthread_8h-source.html

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+<title>cr_lib: pthread.h Source File</title>
+<link href="tabs.css" rel="stylesheet" type="text/css">
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+</head><body>
+<!-- Generated by Doxygen 1.5.8 -->
+<div class="navigation" id="top">
+  <div class="tabs">
+    <ul>
+      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
+      <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
+      <li class="current"><a href="files.html"><span>Files</span></a></li>
+      <li><a href="examples.html"><span>Examples</span></a></li>
+    </ul>
+  </div>
+  <div class="tabs">
+    <ul>
+      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
+      <li><a href="globals.html"><span>Globals</span></a></li>
+    </ul>
+  </div>
+<h1>pthread.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/* This is an implementation of the threads API of POSIX 1003.1-2001.</span>
+<a name="l00002"></a>00002 <span class="comment"> *</span>
+<a name="l00003"></a>00003 <span class="comment"> * --------------------------------------------------------------------------</span>
+<a name="l00004"></a>00004 <span class="comment"> *</span>
+<a name="l00005"></a>00005 <span class="comment"> *      Pthreads-win32 - POSIX Threads Library for Win32</span>
+<a name="l00006"></a>00006 <span class="comment"> *      Copyright(C) 1998 John E. Bossom</span>
+<a name="l00007"></a>00007 <span class="comment"> *      Copyright(C) 1999,2005 Pthreads-win32 contributors</span>
+<a name="l00008"></a>00008 <span class="comment"> * </span>
+<a name="l00009"></a>00009 <span class="comment"> *      Contact Email: rpj@callisto.canberra.edu.au</span>
+<a name="l00010"></a>00010 <span class="comment"> * </span>
+<a name="l00011"></a>00011 <span class="comment"> *      The current list of contributors is contained</span>
+<a name="l00012"></a>00012 <span class="comment"> *      in the file CONTRIBUTORS included with the source</span>
+<a name="l00013"></a>00013 <span class="comment"> *      code distribution. The list can also be seen at the</span>
+<a name="l00014"></a>00014 <span class="comment"> *      following World Wide Web location:</span>
+<a name="l00015"></a>00015 <span class="comment"> *      http://sources.redhat.com/pthreads-win32/contributors.html</span>
+<a name="l00016"></a>00016 <span class="comment"> * </span>
+<a name="l00017"></a>00017 <span class="comment"> *      This library is free software; you can redistribute it and/or</span>
+<a name="l00018"></a>00018 <span class="comment"> *      modify it under the terms of the GNU Lesser General Public</span>
+<a name="l00019"></a>00019 <span class="comment"> *      License as published by the Free Software Foundation; either</span>
+<a name="l00020"></a>00020 <span class="comment"> *      version 2 of the License, or (at your option) any later version.</span>
+<a name="l00021"></a>00021 <span class="comment"> * </span>
+<a name="l00022"></a>00022 <span class="comment"> *      This library is distributed in the hope that it will be useful,</span>
+<a name="l00023"></a>00023 <span class="comment"> *      but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<a name="l00024"></a>00024 <span class="comment"> *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span>
+<a name="l00025"></a>00025 <span class="comment"> *      Lesser General Public License for more details.</span>
+<a name="l00026"></a>00026 <span class="comment"> * </span>
+<a name="l00027"></a>00027 <span class="comment"> *      You should have received a copy of the GNU Lesser General Public</span>
+<a name="l00028"></a>00028 <span class="comment"> *      License along with this library in the file COPYING.LIB;</span>
+<a name="l00029"></a>00029 <span class="comment"> *      if not, write to the Free Software Foundation, Inc.,</span>
+<a name="l00030"></a>00030 <span class="comment"> *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA</span>
+<a name="l00031"></a>00031 <span class="comment"> */</span>
+<a name="l00032"></a>00032 
+<a name="l00033"></a>00033 <span class="preprocessor">#if !defined( PTHREAD_H )</span>
+<a name="l00034"></a>00034 <span class="preprocessor"></span><span class="preprocessor">#define PTHREAD_H</span>
+<a name="l00035"></a>00035 <span class="preprocessor"></span>
+<a name="l00036"></a>00036 <span class="comment">/*</span>
+<a name="l00037"></a>00037 <span class="comment"> * See the README file for an explanation of the pthreads-win32 version</span>
+<a name="l00038"></a>00038 <span class="comment"> * numbering scheme and how the DLL is named etc.</span>
+<a name="l00039"></a>00039 <span class="comment"> */</span>
+<a name="l00040"></a>00040 <span class="preprocessor">#define PTW32_VERSION 2,8,0,0</span>
+<a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_VERSION_STRING "2, 8, 0, 0\0"</span>
+<a name="l00042"></a>00042 <span class="preprocessor"></span>
+<a name="l00043"></a>00043 <span class="comment">/* There are three implementations of cancel cleanup.</span>
+<a name="l00044"></a>00044 <span class="comment"> * Note that pthread.h is included in both application</span>
+<a name="l00045"></a>00045 <span class="comment"> * compilation units and also internally for the library.</span>
+<a name="l00046"></a>00046 <span class="comment"> * The code here and within the library aims to work</span>
+<a name="l00047"></a>00047 <span class="comment"> * for all reasonable combinations of environments.</span>
+<a name="l00048"></a>00048 <span class="comment"> *</span>
+<a name="l00049"></a>00049 <span class="comment"> * The three implementations are:</span>
+<a name="l00050"></a>00050 <span class="comment"> *</span>
+<a name="l00051"></a>00051 <span class="comment"> *   WIN32 SEH</span>
+<a name="l00052"></a>00052 <span class="comment"> *   C</span>
+<a name="l00053"></a>00053 <span class="comment"> *   C++</span>
+<a name="l00054"></a>00054 <span class="comment"> *</span>
+<a name="l00055"></a>00055 <span class="comment"> * Please note that exiting a push/pop block via</span>
+<a name="l00056"></a>00056 <span class="comment"> * "return", "exit", "break", or "continue" will</span>
+<a name="l00057"></a>00057 <span class="comment"> * lead to different behaviour amongst applications</span>
+<a name="l00058"></a>00058 <span class="comment"> * depending upon whether the library was built</span>
+<a name="l00059"></a>00059 <span class="comment"> * using SEH, C++, or C. For example, a library built</span>
+<a name="l00060"></a>00060 <span class="comment"> * with SEH will call the cleanup routine, while both</span>
+<a name="l00061"></a>00061 <span class="comment"> * C++ and C built versions will not.</span>
+<a name="l00062"></a>00062 <span class="comment"> */</span>
+<a name="l00063"></a>00063 
+<a name="l00064"></a>00064 <span class="comment">/*</span>
+<a name="l00065"></a>00065 <span class="comment"> * Define defaults for cleanup code.</span>
+<a name="l00066"></a>00066 <span class="comment"> * Note: Unless the build explicitly defines one of the following, then</span>
+<a name="l00067"></a>00067 <span class="comment"> * we default to standard C style cleanup. This style uses setjmp/longjmp</span>
+<a name="l00068"></a>00068 <span class="comment"> * in the cancelation and thread exit implementations and therefore won't</span>
+<a name="l00069"></a>00069 <span class="comment"> * do stack unwinding if linked to applications that have it (e.g.</span>
+<a name="l00070"></a>00070 <span class="comment"> * C++ apps). This is currently consistent with most/all commercial Unix</span>
+<a name="l00071"></a>00071 <span class="comment"> * POSIX threads implementations.</span>
+<a name="l00072"></a>00072 <span class="comment"> */</span>
+<a name="l00073"></a>00073 <span class="preprocessor">#if !defined( __CLEANUP_SEH ) &amp;&amp; !defined( __CLEANUP_CXX ) &amp;&amp; !defined( __CLEANUP_C )</span>
+<a name="l00074"></a>00074 <span class="preprocessor"></span><span class="preprocessor"># define __CLEANUP_C</span>
+<a name="l00075"></a>00075 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00076"></a>00076 <span class="preprocessor"></span>
+<a name="l00077"></a>00077 <span class="preprocessor">#if defined( __CLEANUP_SEH ) &amp;&amp; ( !defined( _MSC_VER ) &amp;&amp; !defined(PTW32_RC_MSC))</span>
+<a name="l00078"></a>00078 <span class="preprocessor"></span><span class="preprocessor">#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.</span>
+<a name="l00079"></a>00079 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00080"></a>00080 <span class="preprocessor"></span>
+<a name="l00081"></a>00081 <span class="comment">/*</span>
+<a name="l00082"></a>00082 <span class="comment"> * Stop here if we are being included by the resource compiler.</span>
+<a name="l00083"></a>00083 <span class="comment"> */</span>
+<a name="l00084"></a>00084 <span class="preprocessor">#ifndef RC_INVOKED</span>
+<a name="l00085"></a>00085 <span class="preprocessor"></span>
+<a name="l00086"></a>00086 <span class="preprocessor">#undef PTW32_LEVEL</span>
+<a name="l00087"></a>00087 <span class="preprocessor"></span>
+<a name="l00088"></a>00088 <span class="preprocessor">#if defined(_POSIX_SOURCE)</span>
+<a name="l00089"></a>00089 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_LEVEL 0</span>
+<a name="l00090"></a>00090 <span class="preprocessor"></span><span class="comment">/* Early POSIX */</span>
+<a name="l00091"></a>00091 <span class="preprocessor">#endif</span>
+<a name="l00092"></a>00092 <span class="preprocessor"></span>
+<a name="l00093"></a>00093 <span class="preprocessor">#if defined(_POSIX_C_SOURCE) &amp;&amp; _POSIX_C_SOURCE &gt;= 199309</span>
+<a name="l00094"></a>00094 <span class="preprocessor"></span><span class="preprocessor">#undef PTW32_LEVEL</span>
+<a name="l00095"></a>00095 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_LEVEL 1</span>
+<a name="l00096"></a>00096 <span class="preprocessor"></span><span class="comment">/* Include 1b, 1c and 1d */</span>
+<a name="l00097"></a>00097 <span class="preprocessor">#endif</span>
+<a name="l00098"></a>00098 <span class="preprocessor"></span>
+<a name="l00099"></a>00099 <span class="preprocessor">#if defined(INCLUDE_NP)</span>
+<a name="l00100"></a>00100 <span class="preprocessor"></span><span class="preprocessor">#undef PTW32_LEVEL</span>
+<a name="l00101"></a>00101 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_LEVEL 2</span>
+<a name="l00102"></a>00102 <span class="preprocessor"></span><span class="comment">/* Include Non-Portable extensions */</span>
+<a name="l00103"></a>00103 <span class="preprocessor">#endif</span>
+<a name="l00104"></a>00104 <span class="preprocessor"></span>
+<a name="l00105"></a>00105 <span class="preprocessor">#define PTW32_LEVEL_MAX 3</span>
+<a name="l00106"></a>00106 <span class="preprocessor"></span>
+<a name="l00107"></a>00107 <span class="preprocessor">#if !defined(PTW32_LEVEL)</span>
+<a name="l00108"></a>00108 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_LEVEL PTW32_LEVEL_MAX</span>
+<a name="l00109"></a>00109 <span class="preprocessor"></span><span class="comment">/* Include everything */</span>
+<a name="l00110"></a>00110 <span class="preprocessor">#endif</span>
+<a name="l00111"></a>00111 <span class="preprocessor"></span>
+<a name="l00112"></a>00112 <span class="preprocessor">#ifdef _UWIN</span>
+<a name="l00113"></a>00113 <span class="preprocessor"></span><span class="preprocessor">#   define HAVE_STRUCT_TIMESPEC 1</span>
+<a name="l00114"></a>00114 <span class="preprocessor"></span><span class="preprocessor">#   define HAVE_SIGNAL_H        1</span>
+<a name="l00115"></a>00115 <span class="preprocessor"></span><span class="preprocessor">#   undef HAVE_CONFIG_H</span>
+<a name="l00116"></a>00116 <span class="preprocessor"></span><span class="preprocessor">#   pragma comment(lib, "pthread")</span>
+<a name="l00117"></a>00117 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00118"></a>00118 <span class="preprocessor"></span>
+<a name="l00119"></a>00119 <span class="comment">/*</span>
+<a name="l00120"></a>00120 <span class="comment"> * -------------------------------------------------------------</span>
+<a name="l00121"></a>00121 <span class="comment"> *</span>
+<a name="l00122"></a>00122 <span class="comment"> *</span>
+<a name="l00123"></a>00123 <span class="comment"> * Module: pthread.h</span>
+<a name="l00124"></a>00124 <span class="comment"> *</span>
+<a name="l00125"></a>00125 <span class="comment"> * Purpose:</span>
+<a name="l00126"></a>00126 <span class="comment"> *      Provides an implementation of PThreads based upon the</span>
+<a name="l00127"></a>00127 <span class="comment"> *      standard:</span>
+<a name="l00128"></a>00128 <span class="comment"> *</span>
+<a name="l00129"></a>00129 <span class="comment"> *              POSIX 1003.1-2001</span>
+<a name="l00130"></a>00130 <span class="comment"> *  and</span>
+<a name="l00131"></a>00131 <span class="comment"> *    The Single Unix Specification version 3</span>
+<a name="l00132"></a>00132 <span class="comment"> *</span>
+<a name="l00133"></a>00133 <span class="comment"> *    (these two are equivalent)</span>
+<a name="l00134"></a>00134 <span class="comment"> *</span>
+<a name="l00135"></a>00135 <span class="comment"> *      in order to enhance code portability between Windows,</span>
+<a name="l00136"></a>00136 <span class="comment"> *  various commercial Unix implementations, and Linux.</span>
+<a name="l00137"></a>00137 <span class="comment"> *</span>
+<a name="l00138"></a>00138 <span class="comment"> *      See the ANNOUNCE file for a full list of conforming</span>
+<a name="l00139"></a>00139 <span class="comment"> *      routines and defined constants, and a list of missing</span>
+<a name="l00140"></a>00140 <span class="comment"> *      routines and constants not defined in this implementation.</span>
+<a name="l00141"></a>00141 <span class="comment"> *</span>
+<a name="l00142"></a>00142 <span class="comment"> * Authors:</span>
+<a name="l00143"></a>00143 <span class="comment"> *      There have been many contributors to this library.</span>
+<a name="l00144"></a>00144 <span class="comment"> *      The initial implementation was contributed by</span>
+<a name="l00145"></a>00145 <span class="comment"> *      John Bossom, and several others have provided major</span>
+<a name="l00146"></a>00146 <span class="comment"> *      sections or revisions of parts of the implementation.</span>
+<a name="l00147"></a>00147 <span class="comment"> *      Often significant effort has been contributed to</span>
+<a name="l00148"></a>00148 <span class="comment"> *      find and fix important bugs and other problems to</span>
+<a name="l00149"></a>00149 <span class="comment"> *      improve the reliability of the library, which sometimes</span>
+<a name="l00150"></a>00150 <span class="comment"> *      is not reflected in the amount of code which changed as</span>
+<a name="l00151"></a>00151 <span class="comment"> *      result.</span>
+<a name="l00152"></a>00152 <span class="comment"> *      As much as possible, the contributors are acknowledged</span>
+<a name="l00153"></a>00153 <span class="comment"> *      in the ChangeLog file in the source code distribution</span>
+<a name="l00154"></a>00154 <span class="comment"> *      where their changes are noted in detail.</span>
+<a name="l00155"></a>00155 <span class="comment"> *</span>
+<a name="l00156"></a>00156 <span class="comment"> *      Contributors are listed in the CONTRIBUTORS file.</span>
+<a name="l00157"></a>00157 <span class="comment"> *</span>
+<a name="l00158"></a>00158 <span class="comment"> *      As usual, all bouquets go to the contributors, and all</span>
+<a name="l00159"></a>00159 <span class="comment"> *      brickbats go to the project maintainer.</span>
+<a name="l00160"></a>00160 <span class="comment"> *</span>
+<a name="l00161"></a>00161 <span class="comment"> * Maintainer:</span>
+<a name="l00162"></a>00162 <span class="comment"> *      The code base for this project is coordinated and</span>
+<a name="l00163"></a>00163 <span class="comment"> *      eventually pre-tested, packaged, and made available by</span>
+<a name="l00164"></a>00164 <span class="comment"> *</span>
+<a name="l00165"></a>00165 <span class="comment"> *              Ross Johnson &lt;rpj@callisto.canberra.edu.au&gt;</span>
+<a name="l00166"></a>00166 <span class="comment"> *</span>
+<a name="l00167"></a>00167 <span class="comment"> * QA Testers:</span>
+<a name="l00168"></a>00168 <span class="comment"> *      Ultimately, the library is tested in the real world by</span>
+<a name="l00169"></a>00169 <span class="comment"> *      a host of competent and demanding scientists and</span>
+<a name="l00170"></a>00170 <span class="comment"> *      engineers who report bugs and/or provide solutions</span>
+<a name="l00171"></a>00171 <span class="comment"> *      which are then fixed or incorporated into subsequent</span>
+<a name="l00172"></a>00172 <span class="comment"> *      versions of the library. Each time a bug is fixed, a</span>
+<a name="l00173"></a>00173 <span class="comment"> *      test case is written to prove the fix and ensure</span>
+<a name="l00174"></a>00174 <span class="comment"> *      that later changes to the code don't reintroduce the</span>
+<a name="l00175"></a>00175 <span class="comment"> *      same error. The number of test cases is slowly growing</span>
+<a name="l00176"></a>00176 <span class="comment"> *      and therefore so is the code reliability.</span>
+<a name="l00177"></a>00177 <span class="comment"> *</span>
+<a name="l00178"></a>00178 <span class="comment"> * Compliance:</span>
+<a name="l00179"></a>00179 <span class="comment"> *      See the file ANNOUNCE for the list of implemented</span>
+<a name="l00180"></a>00180 <span class="comment"> *      and not-implemented routines and defined options.</span>
+<a name="l00181"></a>00181 <span class="comment"> *      Of course, these are all defined is this file as well.</span>
+<a name="l00182"></a>00182 <span class="comment"> *</span>
+<a name="l00183"></a>00183 <span class="comment"> * Web site:</span>
+<a name="l00184"></a>00184 <span class="comment"> *      The source code and other information about this library</span>
+<a name="l00185"></a>00185 <span class="comment"> *      are available from</span>
+<a name="l00186"></a>00186 <span class="comment"> *</span>
+<a name="l00187"></a>00187 <span class="comment"> *              http://sources.redhat.com/pthreads-win32/</span>
+<a name="l00188"></a>00188 <span class="comment"> *</span>
+<a name="l00189"></a>00189 <span class="comment"> * -------------------------------------------------------------</span>
+<a name="l00190"></a>00190 <span class="comment"> */</span>
+<a name="l00191"></a>00191 
+<a name="l00192"></a>00192 <span class="comment">/* Try to avoid including windows.h */</span>
+<a name="l00193"></a>00193 <span class="preprocessor">#if defined(__MINGW32__) &amp;&amp; defined(__cplusplus)</span>
+<a name="l00194"></a>00194 <span class="preprocessor"></span><span class="preprocessor">#define PTW32_INCLUDE_WINDOWS_H</span>
+<a name="l00195"></a>00195 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00196"></a>00196 <span class="preprocessor"></span>
+<a name="l00197"></a>00197 <span class="preprocessor">#ifdef PTW32_INCLUDE_WINDOWS_H</span>
+<a name="l00198"></a>00198 <span class="preprocessor"></span><span class="preprocessor">#include &lt;windows.h&gt;</span>
+<a name="l00199"></a>00199 <span class="preprocessor">#endif</span>
+<a name="l00200"></a>00200 <span class="preprocessor"></span>
+<a name="l00201"></a>00201 <span class="preprocessor">#if defined(_MSC_VER) &amp;&amp; _MSC_VER &lt; 1300 || defined(__DMC__)</span>
+<a name="l00202"></a>00202 <span class="preprocessor"></span><span class="comment">/*</span>
+<a name="l00203"></a>00203 <span class="comment"> * VC++6.0 or early compiler's header has no DWORD_PTR type.</span>
+<a name="l00204"></a>00204 <span class="comment"> */</span>
+<a name="l00205"></a>00205 <span class="keyword">typedef</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> DWORD_PTR;
+<a name="l00206"></a>00206 <span class="preprocessor">#endif</span>
+<a name="l00207"></a>00207 <span class="preprocessor"></span><span class="comment">/*</span>
+<a name="l00208"></a>00208 <span class="comment"> * -----------------</span>
+<a name="l00209"></a>00209 <span class="comment"> * autoconf switches</span>
+<a name="l00210"></a>00210 <span class="comment"> * -----------------</span>
+<a name="l00211"></a>00211 <span class="comment"> */</span>
+<a name="l00212"></a>00212 
+<a name="l00213"></a>00213 <span class="preprocessor">#if HAVE_CONFIG_H</span>
+<a name="l00214"></a>00214 <span class="preprocessor"></span><span class="preprocessor">#include "config.h"</span>
+<a name="l00215"></a>00215 <span class="preprocessor">#endif </span><span class="comment">/* HAVE_CONFIG_H */</span>
+<a name="l00216"></a>00216 
+<a name="l00217"></a>00217 <span class="preprocessor">#ifndef NEED_FTIME</span>
+<a name="l00218"></a>00218 <span class="preprocessor"></span><span class="preprocessor">#include &lt;time.h&gt;</span>
+<a name="l00219"></a>00219 <span class="preprocessor">#else </span><span class="comment">/* NEED_FTIME */</span>
+<a name="l00220"></a>00220 <span class="comment">/* use native WIN32 time API */</span>
+<a name="l00221"></a>00221 <span class="preprocessor">#endif </span><span class="comment">/* NEED_FTIME */</span>
+<a name="l00222"></a>00222 
+<a name="l00223"></a>00223 <span class="preprocessor">#if HAVE_SIGNAL_H</span>
+<a name="l00224"></a>00224 <span class="preprocessor"></span><span class="preprocessor">#include &lt;signal.h&gt;</span>
+<a name="l00225"></a>00225 <span class="preprocessor">#endif </span><span class="comment">/* HAVE_SIGNAL_H */</span>
+<a name="l00226"></a>00226 
+<a name="l00227"></a>00227 <span class="preprocessor">#include &lt;setjmp.h&gt;</span>
+<a name="l00228"></a>00228 <span class="preprocessor">#include &lt;limits.h&gt;</span>
+<a name="l00229"></a>00229 
+<a name="l00230"></a>00230 <span class="comment">/*</span>
+<a name="l00231"></a>00231 <span class="comment"> * Boolean values to make us independent of system includes.</span>
+<a name="l00232"></a>00232 <span class="comment"> */</span>
+<a name="l00233"></a>00233 <span class="keyword">enum</span> {
+<a name="l00234"></a>00234   PTW32_FALSE = 0,
+<a name="l00235"></a>00235   PTW32_TRUE = (! PTW32_FALSE)
+<a name="l00236"></a>00236 };
+<a name="l00237"></a>00237 
+<a name="l00238"></a>00238 <span class="comment">/*</span>
+<a name="l00239"></a>00239 <span class="comment"> * This is a duplicate of what is in the autoconf config.h,</span>
+<a name="l00240"></a>00240 <span class="comment"> * which is only used when building the pthread-win32 libraries.</span>
+<a name="l00241"></a>00241 <span class="comment"> */</span>
+<a name="l00242"></a>00242 
+<a name="l00243"></a>00243 <span class="preprocessor">#ifndef PTW32_CONFIG_H</span>
+<a name="l00244"></a>00244 <span class="preprocessor"></span><span class="preprocessor">#  if defined(WINCE)</span>
+<a name="l00245"></a>00245 <span class="preprocessor"></span><span class="preprocessor">#    define NEED_ERRNO</span>
+<a name="l00246"></a>00246 <span class="preprocessor"></span><span class="preprocessor">#    define NEED_SEM</span>
+<a name="l00247"></a>00247 <span class="preprocessor"></span><span class="preprocessor">#  endif</span>
+<a name="l00248"></a>00248 <span class="preprocessor"></span><span class="preprocessor">#  if defined(_UWIN) || defined(__MINGW32__)</span>
+<a name="l00249"></a>00249 <span class="preprocessor"></span><span class="preprocessor">#    define HAVE_MODE_T</span>
+<a name="l00250"></a>00250 <span class="preprocessor"></span><span class="preprocessor">#  endif</span>
+<a name="l00251"></a>00251 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00252"></a>00252 <span class="preprocessor"></span>
+<a name="l00253"></a>00253 <span class="comment">/*</span>
+<a name="l00254"></a>00254 <span class="comment"> *</span>
+<a name="l00255"></a>00255 <span class="comment"> */</span>
+<a name="l00256"></a>00256 
+<a name="l00257"></a>00257 <span class="preprocessor">#if PTW32_LEVEL &gt;= PTW32_LEVEL_MAX</span>
+<a name="l00258"></a>00258 <span class="preprocessor"></span><span class="preprocessor">#ifdef NEED_ERRNO</span>
+<a name="l00259"></a>00259 <span class="preprocessor"></span><span class="preprocessor">#include "need_errno.h"</span>
+<a name="l00260"></a>00260 <span class="preprocessor">#else</span>
+<a name="l00261"></a>00261 <span class="preprocessor"></span><span class="preprocessor">#include &lt;errno.h&gt;</span>
+<a name="l00262"></a>00262 <span class="preprocessor">#endif</span>
+<a name="l00263"></a>00263 <span class="preprocessor"></span><span class="preprocessor">#endif </span><span class="comment">/* PTW32_LEVEL &gt;= PTW32_LEVEL_MAX */</span>
+<a name="l00264"></a>00264 
+<a name="l00265"></a>00265 <span class="comment">/*</span>
+<a name="l00266"></a>00266 <span class="comment"> * Several systems don't define some error numbers.</span>
+<a name="l00267"></a>00267 <span class="comment"> */</span>
+<a name="l00268"></a>00268 <span class="preprocessor">#ifndef ENOTSUP</span>
+<a name="l00269"></a>00269 <span class="preprocessor"></span><span class="preprocessor">#  define ENOTSUP 48   </span><span class="comment">/* This is the value in Solaris. */</span>
+<a name="l00270"></a>00270 <span class="preprocessor">#endif</span>
+<a name="l00271"></a>00271 <span class="preprocessor"></span>
+<a name="l00272"></a>00272 <span class="preprocessor">#ifndef ETIMEDOUT</span>
+<a name="l00273"></a>00273 <span class="preprocessor"></span><span class="preprocessor">#  define ETIMEDOUT 10060     </span><span class="comment">/* This is the value in winsock.h. */</span>
+<a name="l00274"></a>00274 <span class="preprocessor">#endif</span>
+<a name="l00275"></a>00275 <span class="preprocessor"></span>
+<a name="l00276"></a>00276 <span class="preprocessor">#ifndef ENOSYS</span>
+<a name="l00277"></a>00277 <span class="preprocessor"></span><span class="preprocessor">#  define ENOSYS 140     </span><span class="comment">/* Semi-arbitrary value */</span>
+<a name="l00278"></a>00278 <span class="preprocessor">#endif</span>
+<a name="l00279"></a>00279 <span class="preprocessor"></span>
+<a name="l00280"></a>00280 <span class="preprocessor">#ifndef EDEADLK</span>
+<a name="l00281"></a>00281 <span class="preprocessor"></span><span class="preprocessor">#  ifdef EDEADLOCK</span>
+<a name="l00282"></a>00282 <span class="preprocessor"></span><span class="preprocessor">#    define EDEADLK EDEADLOCK</span>
+<a name="l00283"></a>00283 <span class="preprocessor"></span><span class="preprocessor">#  else</span>
+<a name="l00284"></a>00284 <span class="preprocessor"></span><span class="preprocessor">#    define EDEADLK 36     </span><span class="comment">/* This is the value in MSVC. */</span>
+<a name="l00285"></a>00285 <span class="preprocessor">#  endif</span>
+<a name="l00286"></a>00286 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00287"></a>00287 <span class="preprocessor"></span>
+<a name="l00288"></a>00288 <span class="preprocessor">#include &lt;sched.h&gt;</span>
+<a name="l00289"></a>00289 
+<a name="l00290"></a>00290 <span class="comment">/*</span>
+<a name="l00291"></a>00291 <span class="comment"> * To avoid including windows.h we define only those things that we</span>
+<a name="l00292"></a>00292 <span class="comment"> * actually need from it.</span>
+<a name="l00293"></a>00293 <span class="comment"> */</span>
+<a name="l00294"></a>00294 <span class="preprocessor">#ifndef PTW32_INCLUDE_WINDOWS_H</span>
+<a name="l00295"></a>00295 <span class="preprocessor"></span><span class="preprocessor">#ifndef HANDLE</span>
+<a name="l00296"></a>00296 <span class="preprocessor"></span><span class="preprocessor"># define PTW32__HANDLE_DEF</span>
+<a name="l00297"></a>00297 <span class="preprocessor"></span><span class="preprocessor"># define HANDLE void *</span>
+<a name="l00298"></a>00298 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00299"></a>00299 <span class="preprocessor"></span><span class="preprocessor">#ifndef DWORD</span>
+<a name="l00300"></a>00300 <span class="preprocessor"></span><span class="preprocessor"># define PTW32__DWORD_DEF</span>
+<a name="l00301"></a>00301 <span class="preprocessor"></span><span class="preprocessor"># define DWORD unsigned long</span>
+<a name="l00302"></a>00302 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00303"></a>00303 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
+<a name="l00304"></a>00304 <span class="preprocessor"></span>
+<a name="l00305"></a>00305 <span class="preprocessor">#ifndef HAVE_STRUCT_TIMESPEC</span>
+<a name="l00306"></a>00306 <span class="preprocessor"></span><span class="preprocessor">#define HAVE_STRUCT_TIMESPEC 1</span>
+<a name="l00307"></a>00307 <span class="preprocessor"></span><span class="keyword">struct </span>timespec {
+<a name="l00308"></a>00308         <span class="keywordtype">long</span> tv_sec;
+<a name="l00309"></a>00309         <span class="keywordtype">long</span> tv_nsec;
+<a name="l00310"></a>00310 };
+<a name="l00311"></a>00311 <span class="preprocessor">#endif </span><span class="comment">/* HAVE_STRUCT_TIMESPEC */</span>
+<a name="l00312"></a>00312 
+<a name="l00313"></a>00313 <span class="preprocessor">#ifndef SIG_BLOCK</span>
+<a name="l00314"></a>00314 <span class="preprocessor"></span><span class="preprocessor">#define SIG_BLOCK 0</span>
+<a name="l00315"></a>00315 <span class="preprocessor"></span><span class="preprocessor">#endif </span><span class="comment">/* SIG_BLOCK */</span>
+<a name="l00316"></a>00316 
+<a name="l00317"></a>00317 <span class="preprocessor">#ifndef SIG_UNBLOCK </span>
+<a name="l00318"></a>00318 <span class="preprocessor"></span><span class="preprocessor">#define SIG_UNBLOCK 1</span>
+<a name="l00319"></a>00319 <span class="preprocessor"></span><span class="preprocessor">#endif </span><span class="comment">/* SIG_UNBLOCK */</span>
+<a name="l00320"></a>00320 
+<a name="l00321"></a>00321 <span class="preprocessor">#ifndef SIG_SETMASK</span>
+<a name="l00322"></a>00322 <span class="preprocessor"></span><span class="preprocessor">#define SIG_SETMASK 2</span>
+<a name="l00323"></a>00323 <span class="preprocessor"></span><span class="preprocessor">#endif </span><span class="comment">/* SIG_SETMASK */</span>
+<a name="l00324"></a>00324 
+<a name="l00325"></a>00325 <span class="preprocessor">#ifdef __cplusplus</span>
+<a name="l00326"></a>00326 <span class="preprocessor"></span><span class="keyword">extern</span> <span class="stringliteral">"C"</span>
+<a name="l00327"></a>00327 {
+<a name="l00328"></a>00328 <span class="preprocessor">#endif                          </span><span class="comment">/* __cplusplus */</span>
+<a name="l00329"></a>00329 
+<a name="l00330"></a>00330 <span class="comment">/*</span>
+<a name="l00331"></a>00331 <span class="comment"> * -------------------------------------------------------------</span>
+<a name="l00332"></a>00332 <span class="comment"> *</span>
+<a name="l00333"></a>00333 <span class="comment"> * POSIX 1003.1-2001 Options</span>
+<a name="l00334"></a>00334 <span class="comment"> * =========================</span>
+<a name="l00335"></a>00335 <span class="comment"> *</span>
+<a name="l00336"></a>00336 <span class="comment"> * Options are normally set in &lt;unistd.h&gt;, which is not provided</span>
+<a name="l00337"></a>00337 <span class="comment"> * with pthreads-win32.</span>
+<a name="l00338"></a>00338 <span class="comment"> *</span>
+<a name="l00339"></a>00339 <span class="comment"> * For conformance with the Single Unix Specification (version 3), all of the</span>
+<a name="l00340"></a>00340 <span class="comment"> * options below are defined, and have a value of either -1 (not supported)</span>
+<a name="l00341"></a>00341 <span class="comment"> * or 200112L (supported).</span>
+<a name="l00342"></a>00342 <span class="comment"> *</span>
+<a name="l00343"></a>00343 <span class="comment"> * These options can neither be left undefined nor have a value of 0, because</span>
+<a name="l00344"></a>00344 <span class="comment"> * either indicates that sysconf(), which is not implemented, may be used at</span>
+<a name="l00345"></a>00345 <span class="comment"> * runtime to check the status of the option.</span>
+<a name="l00346"></a>00346 <span class="comment"> *</span>
+<a name="l00347"></a>00347 <span class="comment"> * _POSIX_THREADS (== 200112L)</span>
+<a name="l00348"></a>00348 <span class="comment"> *                      If == 200112L, you can use threads</span>
+<a name="l00349"></a>00349 <span class="comment"> *</span>
+<a name="l00350"></a>00350 <span class="comment"> * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)</span>
+<a name="l00351"></a>00351 <span class="comment"> *                      If == 200112L, you can control the size of a thread's</span>
+<a name="l00352"></a>00352 <span class="comment"> *                      stack</span>
+<a name="l00353"></a>00353 <span class="comment"> *                              pthread_attr_getstacksize</span>
+<a name="l00354"></a>00354 <span class="comment"> *                              pthread_attr_setstacksize</span>
+<a name="l00355"></a>00355 <span class="comment"> *</span>
+<a name="l00356"></a>00356 <span class="comment"> * _POSIX_THREAD_ATTR_STACKADDR (== -1)</span>
+<a name="l00357"></a>00357 <span class="comment"> *                      If == 200112L, you can allocate and control a thread's</span>
+<a name="l00358"></a>00358 <span class="comment"> *                      stack. If not supported, the following functions</span>
+<a name="l00359"></a>00359 <span class="comment"> *                      will return ENOSYS, indicating they are not</span>
+<a name="l00360"></a>00360 <span class="comment"> *                      supported:</span>
+<a name="l00361"></a>00361 <span class="comment"> *                              pthread_attr_getstackaddr</span>
+<a name="l00362"></a>00362 <span class="comment"> *                              pthread_attr_setstackaddr</span>
+<a name="l00363"></a>00363 <span class="comment"> *</span>
+<a name="l00364"></a>00364 <span class="comment"> * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)</span>
+<a name="l00365"></a>00365 <span class="comment"> *                      If == 200112L, you can use realtime scheduling.</span>
+<a name="l00366"></a>00366 <span class="comment"> *                      This option indicates that the behaviour of some</span>
+<a name="l00367"></a>00367 <span class="comment"> *                      implemented functions conforms to the additional TPS</span>
+<a name="l00368"></a>00368 <span class="comment"> *                      requirements in the standard. E.g. rwlocks favour</span>
+<a name="l00369"></a>00369 <span class="comment"> *                      writers over readers when threads have equal priority.</span>
+<a name="l00370"></a>00370 <span class="comment"> *</span>
+<a name="l00371"></a>00371 <span class="comment"> * _POSIX_THREAD_PRIO_INHERIT (== -1)</span>
+<a name="l00372"></a>00372 <span class="comment"> *                      If == 200112L, you can create priority inheritance</span>
+<a name="l00373"></a>00373 <span class="comment"> *                      mutexes.</span>
+<a name="l00374"></a>00374 <span class="comment"> *                              pthread_mutexattr_getprotocol +</span>
+<a name="l00375"></a>00375 <span class="comment"> *                              pthread_mutexattr_setprotocol +</span>
+<a name="l00376"></a>00376 <span class="comment"> *</span>
+<a name="l00377"></a>00377 <span class="comment"> * _POSIX_THREAD_PRIO_PROTECT (== -1)</span>
+<a name="l00378"></a>00378 <span class="comment"> *                      If == 200112L, you can create priority ceiling mutexes</span>
+<a name="l00379"></a>00379 <span class="comment"> *                      Indicates the availability of:</span>
+<a name="l00380"></a>00380 <span class="comment"> *                              pthread_mutex_getprioceiling</span>
+<a name="l00381"></a>00381 <span class="comment"> *                              pthread_mutex_setprioceiling</span>
+<a name="l00382"></a>00382 <span class="comment"> *                              pthread_mutexattr_getprioceiling</span>
+<a name="l00383"></a>00383 <span class="comment"> *                              pthread_mutexattr_getprotocol     +</span>
+<a name="l00384"></a>00384 <span class="comment"> *                              pthread_mutexattr_setprioceiling</span>
+<a name="l00385"></a>00385 <span class="comment"> *                              pthread_mutexattr_setprotocol     +</span>
+<a name="l00386"></a>00386 <span class="comment"> *</span>
+<a name="l00387"></a>00387 <span class="comment"> * _POSIX_THREAD_PROCESS_SHARED (== -1)</span>
+<a name="l00388"></a>00388 <span class="comment"> *                      If set, you can create mutexes and condition</span>
+<a name="l00389"></a>00389 <span class="comment"> *                      variables that can be shared with another</span>
+<a name="l00390"></a>00390 <span class="comment"> *                      process.If set, indicates the availability</span>
+<a name="l00391"></a>00391 <span class="comment"> *                      of:</span>
+<a name="l00392"></a>00392 <span class="comment"> *                              pthread_mutexattr_getpshared</span>
+<a name="l00393"></a>00393 <span class="comment"> *                              pthread_mutexattr_setpshared</span>
+<a name="l00394"></a>00394 <span class="comment"> *                              pthread_condattr_getpshared</span>
+<a name="l00395"></a>00395 <span class="comment"> *                              pthread_condattr_setpshared</span>
+<a name="l00396"></a>00396 <span class="comment"> *</span>
+<a name="l00397"></a>00397 <span class="comment"> * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)</span>
+<a name="l00398"></a>00398 <span class="comment"> *                      If == 200112L you can use the special *_r library</span>
+<a name="l00399"></a>00399 <span class="comment"> *                      functions that provide thread-safe behaviour</span>
+<a name="l00400"></a>00400 <span class="comment"> *</span>
+<a name="l00401"></a>00401 <span class="comment"> * _POSIX_READER_WRITER_LOCKS (== 200112L)</span>
+<a name="l00402"></a>00402 <span class="comment"> *                      If == 200112L, you can use read/write locks</span>
+<a name="l00403"></a>00403 <span class="comment"> *</span>
+<a name="l00404"></a>00404 <span class="comment"> * _POSIX_SPIN_LOCKS (== 200112L)</span>
+<a name="l00405"></a>00405 <span class="comment"> *                      If == 200112L, you can use spin locks</span>
+<a name="l00406"></a>00406 <span class="comment"> *</span>
+<a name="l00407"></a>00407 <span class="comment"> * _POSIX_BARRIERS (== 200112L)</span>
+<a name="l00408"></a>00408 <span class="comment"> *                      If == 200112L, you can use barriers</span>
+<a name="l00409"></a>00409 <span class="comment"> *</span>
+<a name="l00410"></a>00410 <span class="comment"> *      + These functions provide both 'inherit' and/or</span>
+<a name="l00411"></a>00411 <span class="comment"> *        'protect' protocol, based upon these macro</span>
+<a name="l00412"></a>00412 <span class="comment"> *        settings.</span>
+<a name="l00413"></a>00413 <span class="comment"> *</span>
+<a name="l00414"></a>00414 <span class="comment"> * -------------------------------------------------------------</span>
+<a name="l00415"></a>00415 <span class="comment"> */</span>
+<a name="l00416"></a>00416 
+<a name="l00417"></a>00417 <span class="comment">/*</span>
+<a name="l00418"></a>00418 <span class="comment"> * POSIX Options</span>
+<a name="l00419"></a>00419 <span class="comment"> */</span>
+<a name="l00420"></a>00420 <span class="preprocessor">#undef _POSIX_THREADS</span>
+<a name="l00421"></a>00421 <span class="preprocessor"></span><span class="preprocessor">#define _POSIX_THREADS 200112L</span>
+<a name="l00422"></a>00422 <span class="preprocessor"></span>
+<a name="l00423"></a>00423 <span class="preprocessor">#undef _POSIX_READER_WRITER_LOCKS</span>
+<a name="l00424"></a>00424 <span class="preprocessor"></span><span class="preprocessor">#define _POSIX_READER_WRITER_LOCKS 200112L</span>
+<a name="l00425"></a>00425 <span class="preprocessor"></span>
+<a name="l00426"></a>00426 <span class="preprocessor">#undef _POSIX_SPIN_LOCKS</span>
+<a name="l00427"></a>00427 <span class="preprocessor"></span><span class="preprocessor">#define _POSIX_SPIN_LOCKS 200112L</span>
+<a name="l00428"></a>00428 <span class="preprocessor"></span>
+<a name="l00429"></a>00429 <span class="preprocessor">#undef _POSIX_BARRIERS</span>
+<a name="l00430"></a>00430 <span class="preprocessor"></span><span class="preprocessor">#define _POSIX_BARRIERS 200112L</span>
+<a name="l00431"></a>00431 <span class="preprocessor"></span>