use sv_setpvn rather than sv_setpv and save a strlen()
[p5sagit/p5-mst-13.2.git] / ext / threads / shared / t / wait.t
CommitLineData
a0e036c1 1# cond_wait and cond_timedwait extended tests
2# adapted from cond.t
3
4use warnings;
5
6BEGIN {
7 chdir 't' if -d 't';
8 push @INC ,'../lib';
9 require Config; import Config;
10 unless ($Config{'useithreads'}) {
11 print "1..0 # Skip: no threads\n";
12 exit 0;
13 }
14}
15$|++;
ee23bc3a 16print "1..102\n";
a0e036c1 17use strict;
18
19use threads;
20use threads::shared;
21use ExtUtils::testlib;
22
23my $Base = 0;
24
25sub ok {
26 my ($offset, $bool, $text) = @_;
27 my $not = '';
28 $not = "not " unless $bool;
29 print "${not}ok " . ($Base + $offset) . " - $text\n";
30}
31
32# - TEST basics
33
34ok(1, defined &cond_wait, "cond_wait() present");
35ok(2, (prototype(\&cond_wait) eq '\[$@%];\[$@%]'),
36 q|cond_wait() prototype '\[$@%];\[$@%]'|);
37ok(3, defined &cond_timedwait, "cond_timedwait() present");
38ok(4, (prototype(\&cond_timedwait) eq '\[$@%]$;\[$@%]'),
39 q|cond_timedwait() prototype '\[$@%]$;\[$@%]'|);
40
41$Base += 4;
42
43my @wait_how = (
44 "simple", # cond var == lock var; implicit lock; e.g.: cond_wait($c)
45 "repeat", # cond var == lock var; explicit lock; e.g.: cond_wait($c, $c)
46 "twain" # cond var != lock var; explicit lock; e.g.: cond_wait($c, $l)
47);
48
49SYNC_SHARED: {
50 my $test : shared; # simple|repeat|twain
51 my $cond : shared;
52 my $lock : shared;
53
ee23bc3a 54 print "# testing my \$var : shared\n";
a0e036c1 55 ok(1, 1, "Shared synchronization tests preparation");
56 $Base += 1;
57
58 sub signaller {
59 ok(2,1,"$test: child before lock");
60 $test =~ /twain/ ? lock($lock) : lock($cond);
61 ok(3,1,"$test: child obtained lock");
62 if ($test =~ 'twain') {
63 no warnings 'threads'; # lock var != cond var, so disable warnings
64 cond_signal($cond);
65 } else {
66 cond_signal($cond);
67 }
68 ok(4,1,"$test: child signalled condition");
69 }
70
71 # - TEST cond_wait
72 foreach (@wait_how) {
73 $test = "cond_wait [$_]";
74 threads->create(\&cw)->join;
ee23bc3a 75 $Base += 6;
a0e036c1 76 }
77
78 sub cw {
ee23bc3a 79 my $thr;
80
81 { # -- begin lock scope; which lock to obtain?
82 $test =~ /twain/ ? lock($lock) : lock($cond);
83 ok(1,1, "$test: obtained initial lock");
84
85 $thr = threads->create(\&signaller);
86 for ($test) {
87 cond_wait($cond), last if /simple/;
88 cond_wait($cond, $cond), last if /repeat/;
89 cond_wait($cond, $lock), last if /twain/;
90 die "$test: unknown test\n";
91 }
92 ok(5,1, "$test: condition obtained");
93 } # -- end lock scope
a0e036c1 94
a0e036c1 95 $thr->join;
ee23bc3a 96 ok(6,1, "$test: join completed");
a0e036c1 97 }
98
99 # - TEST cond_timedwait success
100
101 foreach (@wait_how) {
102 $test = "cond_timedwait [$_]";
103 threads->create(\&ctw, 5)->join;
ee23bc3a 104 $Base += 6;
a0e036c1 105 }
106
107 sub ctw($) {
108 my $to = shift;
ee23bc3a 109 my $thr;
110
111 { # -- begin lock scope; which lock to obtain?
112 $test =~ /twain/ ? lock($lock) : lock($cond);
113 ok(1,1, "$test: obtained initial lock");
114
115 $thr = threads->create(\&signaller);
116 my $ok = 0;
117 for ($test) {
118 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
119 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
120 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
121 die "$test: unknown test\n";
122 }
123 ok(5,$ok, "$test: condition obtained");
124 } # -- end lock scope
a0e036c1 125
a0e036c1 126 $thr->join;
ee23bc3a 127 ok(6,1, "$test: join completed");
a0e036c1 128 }
129
130 # - TEST cond_timedwait timeout
131
132 foreach (@wait_how) {
133 $test = "cond_timedwait pause, timeout [$_]";
134 threads->create(\&ctw_fail, 3)->join;
135 $Base += 2;
136 }
137
138 foreach (@wait_how) {
139 $test = "cond_timedwait instant timeout [$_]";
140 threads->create(\&ctw_fail, -60)->join;
141 $Base += 2;
142 }
143
144 # cond_timedwait timeout (relative timeout)
145 sub ctw_fail {
146 my $to = shift;
147
148 $test =~ /twain/ ? lock($lock) : lock($cond);
149 ok(1,1, "$test: obtained initial lock");
150 my $ok;
151 for ($test) {
152 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
153 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
154 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
155 die "$test: unknown test\n";
156 }
157 ok(2,!defined($ok), "$test: timeout");
158 }
159
160} # -- SYNCH_SHARED block
161
162
163# same as above, but with references to lock and cond vars
164
165SYNCH_REFS: {
166 my $test : shared; # simple|repeat|twain
167
168 my $true_cond; share($true_cond);
169 my $true_lock; share($true_lock);
170
171 my $cond = \$true_cond;
172 my $lock = \$true_lock;
173
ee23bc3a 174 print "# testing reference to shared(\$var)\n";
a0e036c1 175 ok(1, 1, "Synchronization reference tests preparation");
176 $Base += 1;
177
178 sub signaller2 {
179 ok(2,1,"$test: child before lock");
180 $test =~ /twain/ ? lock($lock) : lock($cond);
181 ok(3,1,"$test: child obtained lock");
182 if ($test =~ 'twain') {
183 no warnings 'threads'; # lock var != cond var, so disable warnings
184 cond_signal($cond);
185 } else {
186 cond_signal($cond);
187 }
188 ok(4,1,"$test: child signalled condition");
189 }
190
191 # - TEST cond_wait
192 foreach (@wait_how) {
193 $test = "cond_wait [$_]";
194 threads->create(\&cw2)->join;
ee23bc3a 195 $Base += 6;
a0e036c1 196 }
197
198 sub cw2 {
ee23bc3a 199 my $thr;
200
201 { # -- begin lock scope; which lock to obtain?
202 $test =~ /twain/ ? lock($lock) : lock($cond);
203 ok(1,1, "$test: obtained initial lock");
204
205 $thr = threads->create(\&signaller2);
206 for ($test) {
207 cond_wait($cond), last if /simple/;
208 cond_wait($cond, $cond), last if /repeat/;
209 cond_wait($cond, $lock), last if /twain/;
210 die "$test: unknown test\n";
211 }
212 ok(5,1, "$test: condition obtained");
213 } # -- end lock scope
a0e036c1 214
a0e036c1 215 $thr->join;
ee23bc3a 216 ok(6,1, "$test: join completed");
a0e036c1 217 }
218
219 # - TEST cond_timedwait success
220
221 foreach (@wait_how) {
222 $test = "cond_timedwait [$_]";
223 threads->create(\&ctw2, 5)->join;
ee23bc3a 224 $Base += 6;
a0e036c1 225 }
226
227 sub ctw2($) {
228 my $to = shift;
ee23bc3a 229 my $thr;
230
231 { # -- begin lock scope; which lock to obtain?
232 $test =~ /twain/ ? lock($lock) : lock($cond);
233 ok(1,1, "$test: obtained initial lock");
234
235 $thr = threads->create(\&signaller2);
236 my $ok = 0;
237 for ($test) {
238 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
239 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
240 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
241 die "$test: unknown test\n";
242 }
243 ok(5,$ok, "$test: condition obtained");
244 } # -- end lock scope
a0e036c1 245
a0e036c1 246 $thr->join;
ee23bc3a 247 ok(6,1, "$test: join completed");
a0e036c1 248 }
249
250 # - TEST cond_timedwait timeout
251
252 foreach (@wait_how) {
253 $test = "cond_timedwait pause, timeout [$_]";
254 threads->create(\&ctw_fail2, 3)->join;
255 $Base += 2;
256 }
257
258 foreach (@wait_how) {
259 $test = "cond_timedwait instant timeout [$_]";
260 threads->create(\&ctw_fail2, -60)->join;
261 $Base += 2;
262 }
263
264 sub ctw_fail2 {
265 my $to = shift;
266
267 $test =~ /twain/ ? lock($lock) : lock($cond);
268 ok(1,1, "$test: obtained initial lock");
269 my $ok;
270 for ($test) {
271 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
272 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
273 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
274 die "$test: unknown test\n";
275 }
276 ok(2,!$ok, "$test: timeout");
277 }
278
279} # -- SYNCH_REFS block
280