1 /*
2 ** GNU Pth - The GNU Portable Threads
3 ** Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
4 **
5 ** This file is part of GNU Pth, a non-preemptive thread scheduling
6 ** library which can be found at http://www.gnu.org/software/pth/.
7 **
8 ** This library is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU Lesser General Public
10 ** License as published by the Free Software Foundation; either
11 ** version 2.1 of the License, or (at your option) any later version.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** Lesser General Public License for more details.
17 **
18 ** You should have received a copy of the GNU Lesser General Public
19 ** License along with this library; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 ** USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
22 **
23 ** test_std.c: Pth standard test program
24 */
25 /* ``Understanding a problem is knowing why
26 it is hard to solve it, and why the most
27 straightforward approaches won't work.''
28 -- Karl Popper */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <unistd.h>
35
36 #include "pth.h"
37
38 #define FAILED_IF(expr) \
39 if (expr) { \
40 fprintf(stderr, "*** ERROR, TEST FAILED:\n*** errno=%d\n\n", errno); \
41 exit(1); \
42 }
43
t1_func(void * arg)44 static void *t1_func(void *arg)
45 {
46 int i;
47 long val;
48
49 val = (long)arg;
50 FAILED_IF(val != 123)
51 for (i = 0; i < 100; i++) {
52 val += 10;
53 pth_yield(NULL);
54 }
55 return (void *)val;
56 }
57
t2_func(void * arg)58 static void *t2_func(void *arg)
59 {
60 long val;
61 pth_t tid;
62 void *rval;
63 int rc;
64
65 val = (long)arg;
66 if (val < 9) {
67 val++;
68 fprintf(stderr, "Spawning thread %ld\n", val);
69 tid = pth_spawn(PTH_ATTR_DEFAULT, t2_func, (void *)(val));
70 FAILED_IF(tid == NULL)
71 rc = pth_join(tid, &rval);
72 fprintf(stderr, "Joined thread %ld\n", val);
73 FAILED_IF(rc == FALSE)
74 rval = (void *)((long)arg * (long)rval);
75 }
76 else
77 rval = arg;
78 return rval;
79 }
80
main(int argc,char * argv[])81 int main(int argc, char *argv[])
82 {
83 fprintf(stderr, "\n=== TESTING GLOBAL LIBRARY API ===\n\n");
84 {
85 int version;
86
87 fprintf(stderr, "Fetching library version\n");
88 version = pth_version();
89 FAILED_IF(version == 0x0)
90 fprintf(stderr, "version = 0x%X\n", version);
91 }
92
93 fprintf(stderr, "\n=== TESTING BASIC OPERATION ===\n\n");
94 {
95 int rc;
96
97 fprintf(stderr, "Initializing Pth system (spawns scheduler and main thread)\n");
98 rc = pth_init();
99 FAILED_IF(rc == FALSE)
100 fprintf(stderr, "Killing Pth system for testing purposes\n");
101 pth_kill();
102 fprintf(stderr, "Re-Initializing Pth system\n");
103 rc = pth_init();
104 FAILED_IF(rc == FALSE)
105 }
106
107 fprintf(stderr, "\n=== TESTING BASIC THREAD OPERATION ===\n\n");
108 {
109 pth_attr_t attr;
110 pth_t tid;
111 void *val;
112 int rc;
113
114 fprintf(stderr, "Creating attribute object\n");
115 attr = pth_attr_new();
116 FAILED_IF(attr == NULL)
117 rc = pth_attr_set(attr, PTH_ATTR_NAME, "test1");
118 FAILED_IF(rc == FALSE)
119 rc = pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX);
120 FAILED_IF(rc == FALSE)
121
122 fprintf(stderr, "Spawning thread\n");
123 tid = pth_spawn(attr, t1_func, (void *)(123));
124 FAILED_IF(tid == NULL)
125 pth_attr_destroy(attr);
126
127 fprintf(stderr, "Joining thread\n");
128 rc = pth_join(tid, &val);
129 FAILED_IF(rc == FALSE)
130 FAILED_IF(val != (void *)(1123))
131 }
132
133 fprintf(stderr, "\n=== TESTING NESTED THREAD OPERATION ===\n\n");
134 {
135 pth_t tid;
136 void *val;
137 int rc;
138
139 fprintf(stderr, "Spawning thread 1\n");
140 tid = pth_spawn(PTH_ATTR_DEFAULT, t2_func, (void *)(1));
141 FAILED_IF(tid == NULL)
142
143 rc = pth_join(tid, &val);
144 fprintf(stderr, "Joined thread 1\n");
145 FAILED_IF(rc == FALSE)
146 FAILED_IF(val != (void *)(1*2*3*4*5*6*7*8*9))
147 }
148
149 pth_kill();
150 fprintf(stderr, "\nOK - ALL TESTS SUCCESSFULLY PASSED.\n\n");
151 exit(0);
152 }
153
154