Upgrade to threads 1.75
[p5sagit/p5-mst-13.2.git] / dist / threads / t / free2.t
CommitLineData
385d56e4 1use strict;
2use warnings;
3
4BEGIN {
4271b527 5 # Import test.pl into its own package
6 {
7 package Test;
2adbc9b6 8 require($ENV{PERL_CORE} ? '../../t/test.pl' : './t/test.pl');
4271b527 9 }
10
385d56e4 11 use Config;
12 if (! $Config{'useithreads'}) {
4271b527 13 Test::skip_all(q/Perl not compiled with 'useithreads'/);
385d56e4 14 }
15}
16
17use ExtUtils::testlib;
18
19use threads;
385d56e4 20
21BEGIN {
e301958b 22 if (! eval 'use threads::shared; 1') {
4271b527 23 Test::skip_all(q/threads::shared not available/);
58a3a76c 24 }
25
385d56e4 26 if (($] < 5.008002) && ($threads::shared::VERSION < 0.92)) {
4271b527 27 Test::skip_all(q/Needs threads::shared 0.92 or later/);
385d56e4 28 }
29
18b9e6f5 30 require Thread::Queue;
31
385d56e4 32 $| = 1;
d4315dd6 33 print("1..78\n"); ### Number of tests that will be run ###
4dcb9e53 34}
385d56e4 35
4271b527 36Test::watchdog(60); # In case we get stuck
385d56e4 37
18b9e6f5 38my $q = Thread::Queue->new();
39my $TEST = 1;
385d56e4 40
18b9e6f5 41sub ok
42{
43 $q->enqueue(@_) if @_;
385d56e4 44
18b9e6f5 45 while ($q->pending()) {
46 my $ok = $q->dequeue();
47 my $name = $q->dequeue();
48 my $id = $TEST++;
385d56e4 49
18b9e6f5 50 if ($ok) {
51 print("ok $id - $name\n");
52 } else {
53 print("not ok $id - $name\n");
54 printf("# Failed test at line %d\n", (caller)[2]);
55 }
56 }
385d56e4 57}
58
59
18b9e6f5 60
385d56e4 61### Start of Testing ###
18b9e6f5 62ok(1, 'Loaded');
385d56e4 63
64# Tests freeing the Perl interperter for each thread
65# See http://www.nntp.perl.org/group/perl.perl5.porters/110772 for details
66
67my $COUNT;
68share($COUNT);
69my %READY;
70share(%READY);
71
72# Init a thread
18b9e6f5 73sub th_start
74{
75 my $q = shift;
385d56e4 76 my $tid = threads->tid();
18b9e6f5 77 $q->enqueue($tid, "Thread $tid started");
385d56e4 78
d4315dd6 79 threads->yield();
80
81 my $other;
82 {
83 lock(%READY);
84
85 # Create next thread
4271b527 86 if ($tid < 18) {
87 my $next = 'th' . $tid;
18b9e6f5 88 my $th = threads->create($next, $q);
d4315dd6 89 } else {
90 # Last thread signals first
18b9e6f5 91 th_signal($q, 1);
d4315dd6 92 }
93
94 # Wait until signalled by another thread
95 while (! exists($READY{$tid})) {
96 cond_wait(%READY);
97 }
98 $other = delete($READY{$tid});
385d56e4 99 }
18b9e6f5 100 $q->enqueue($tid, "Thread $tid received signal from $other");
d4315dd6 101 threads->yield();
385d56e4 102}
103
104# Thread terminating
18b9e6f5 105sub th_done
106{
107 my $q = shift;
385d56e4 108 my $tid = threads->tid();
109
110 lock($COUNT);
111 $COUNT++;
112 cond_signal($COUNT);
113
18b9e6f5 114 $q->enqueue($tid, "Thread $tid done");
385d56e4 115}
116
385d56e4 117# Signal another thread to go
118sub th_signal
119{
18b9e6f5 120 my $q = shift;
385d56e4 121 my $other = shift;
4271b527 122 $other++;
385d56e4 123 my $tid = threads->tid();
124
18b9e6f5 125 $q->enqueue($tid, "Thread $tid signalling $other");
385d56e4 126
127 lock(%READY);
128 $READY{$other} = $tid;
129 cond_broadcast(%READY);
130}
131
132#####
133
18b9e6f5 134sub th1
135{
136 my $q = shift;
137 th_start($q);
385d56e4 138
139 threads->detach();
140
18b9e6f5 141 th_signal($q, 2);
142 th_signal($q, 6);
143 th_signal($q, 10);
144 th_signal($q, 14);
385d56e4 145
18b9e6f5 146 th_done($q);
385d56e4 147}
148
18b9e6f5 149sub th2
150{
151 my $q = shift;
152 th_start($q);
385d56e4 153 threads->detach();
18b9e6f5 154 th_signal($q, 4);
155 th_done($q);
385d56e4 156}
157
18b9e6f5 158sub th6
159{
160 my $q = shift;
161 th_start($q);
385d56e4 162 threads->detach();
18b9e6f5 163 th_signal($q, 8);
164 th_done($q);
385d56e4 165}
166
18b9e6f5 167sub th10
168{
169 my $q = shift;
170 th_start($q);
385d56e4 171 threads->detach();
18b9e6f5 172 th_signal($q, 12);
173 th_done($q);
385d56e4 174}
175
18b9e6f5 176sub th14
177{
178 my $q = shift;
179 th_start($q);
385d56e4 180 threads->detach();
18b9e6f5 181 th_signal($q, 16);
182 th_done($q);
385d56e4 183}
184
18b9e6f5 185sub th4
186{
187 my $q = shift;
188 th_start($q);
385d56e4 189 threads->detach();
18b9e6f5 190 th_signal($q, 3);
191 th_done($q);
385d56e4 192}
193
18b9e6f5 194sub th8
195{
196 my $q = shift;
197 th_start($q);
385d56e4 198 threads->detach();
18b9e6f5 199 th_signal($q, 7);
200 th_done($q);
385d56e4 201}
202
18b9e6f5 203sub th12
204{
205 my $q = shift;
206 th_start($q);
385d56e4 207 threads->detach();
18b9e6f5 208 th_signal($q, 13);
209 th_done($q);
385d56e4 210}
211
18b9e6f5 212sub th16
213{
214 my $q = shift;
215 th_start($q);
385d56e4 216 threads->detach();
18b9e6f5 217 th_signal($q, 17);
218 th_done($q);
385d56e4 219}
220
18b9e6f5 221sub th3
222{
223 my $q = shift;
d4315dd6 224 my $tid = threads->tid();
385d56e4 225 my $other = 5;
226
18b9e6f5 227 th_start($q);
385d56e4 228 threads->detach();
18b9e6f5 229 th_signal($q, $other);
385d56e4 230 sleep(1);
18b9e6f5 231 $q->enqueue(1, "Thread $tid getting return from thread $other");
4271b527 232 my $ret = threads->object($other+1)->join();
233 $q->enqueue($ret == $other+1, "Thread $tid saw that thread $other returned $ret");
18b9e6f5 234 th_done($q);
385d56e4 235}
236
18b9e6f5 237sub th5
238{
239 my $q = shift;
240 th_start($q);
241 th_done($q);
385d56e4 242 return (threads->tid());
243}
244
245
18b9e6f5 246sub th7
247{
248 my $q = shift;
d4315dd6 249 my $tid = threads->tid();
385d56e4 250 my $other = 9;
251
18b9e6f5 252 th_start($q);
385d56e4 253 threads->detach();
18b9e6f5 254 th_signal($q, $other);
255 $q->enqueue(1, "Thread $tid getting return from thread $other");
4271b527 256 my $ret = threads->object($other+1)->join();
257 $q->enqueue($ret == $other+1, "Thread $tid saw that thread $other returned $ret");
18b9e6f5 258 th_done($q);
385d56e4 259}
260
18b9e6f5 261sub th9
262{
263 my $q = shift;
264 th_start($q);
385d56e4 265 sleep(1);
18b9e6f5 266 th_done($q);
385d56e4 267 return (threads->tid());
268}
269
270
18b9e6f5 271sub th13
272{
273 my $q = shift;
d4315dd6 274 my $tid = threads->tid();
385d56e4 275 my $other = 11;
276
18b9e6f5 277 th_start($q);
385d56e4 278 threads->detach();
18b9e6f5 279 th_signal($q, $other);
385d56e4 280 sleep(1);
18b9e6f5 281 $q->enqueue(1, "Thread $tid getting return from thread $other");
4271b527 282 my $ret = threads->object($other+1)->join();
283 $q->enqueue($ret == $other+1, "Thread $tid saw that thread $other returned $ret");
18b9e6f5 284 th_done($q);
385d56e4 285}
286
18b9e6f5 287sub th11
288{
289 my $q = shift;
290 th_start($q);
291 th_done($q);
385d56e4 292 return (threads->tid());
293}
294
295
18b9e6f5 296sub th17
297{
298 my $q = shift;
d4315dd6 299 my $tid = threads->tid();
385d56e4 300 my $other = 15;
301
18b9e6f5 302 th_start($q);
385d56e4 303 threads->detach();
18b9e6f5 304 th_signal($q, $other);
305 $q->enqueue(1, "Thread $tid getting return from thread $other");
4271b527 306 my $ret = threads->object($other+1)->join();
307 $q->enqueue($ret == $other+1, "Thread $tid saw that thread $other returned $ret");
18b9e6f5 308 th_done($q);
385d56e4 309}
310
18b9e6f5 311sub th15
312{
313 my $q = shift;
314 th_start($q);
385d56e4 315 sleep(1);
18b9e6f5 316 th_done($q);
385d56e4 317 return (threads->tid());
318}
319
320
385d56e4 321TEST_STARTS_HERE:
322{
323 $COUNT = 0;
18b9e6f5 324 threads->create('th1', $q);
385d56e4 325 {
326 lock($COUNT);
327 while ($COUNT < 17) {
328 cond_wait($COUNT);
18b9e6f5 329 ok(); # Prints out any intermediate results
385d56e4 330 }
331 }
385d56e4 332 sleep(1);
333}
334ok($COUNT == 17, "Done - $COUNT threads");
335
561ee912 336exit(0);
337
385d56e4 338# EOF