BEGIN {
{
require
(
$ENV
{PERL_CORE} ?
'../../t/test.pl'
:
'./t/test.pl'
);
}
if
(!
$Config
{
'useithreads'
}) {
Test::skip_all(
q/Perl not compiled with 'useithreads'/
);
}
if
(!
eval
'use Time::HiRes "time"; 1'
) {
Test::skip_all(
'Time::HiRes not available'
);
}
if
($^O eq
'linux'
&&
$Config
{archname} =~ /^m68k/) {
exit
(0);
}
}
sub
ok {
my
(
$id
,
$ok
,
$name
) =
@_
;
if
(
$ok
) {
print
(
"ok $id - $name\n"
);
}
else
{
print
(
"not ok $id - $name\n"
);
printf
(
"# Failed test at line %d\n"
, (
caller
)[2]);
}
return
(
$ok
);
}
BEGIN {
$| = 1;
print
(
"1..63\n"
);
};
Test::watchdog(60);
my
$TEST
= 1;
ok(
$TEST
++, 1,
'Loaded'
);
my
@wait_how
= (
"simple"
,
"repeat"
,
"twain"
);
sub
do_cond_timedwait {
my
$ok
;
my
(
$t0
,
$t1
);
if
(
@_
== 3) {
$t0
=
time
();
$ok
= cond_timedwait(
$_
[0],
time
()+
$_
[1],
$_
[2]);
$t1
=
time
();
}
else
{
$t0
=
time
();
$ok
= cond_timedwait(
$_
[0],
time
()+
$_
[1]);
$t1
=
time
();
}
return
(
$ok
,
$t1
-
$t0
)
if
$ok
;
if
(
@_
== 3) {
cond_wait(
$_
[0],
$_
[2]);
}
else
{
cond_wait(
$_
[0]);
}
return
(
$ok
,
$t1
-
$t0
);
}
SYNC_SHARED: {
my
$test_type
:shared;
my
$cond
:shared;
my
$lock
:shared;
my
$ready
:shared;
ok(
$TEST
++, 1,
"Shared synchronization tests preparation"
);
sub
signaller
{
my
$testno
=
$_
[0];
my
(
$t0
,
$t1
);
{
lock
(
$ready
);
$ready
= 1;
$t0
=
time
();
cond_signal(
$ready
);
}
{
ok(
$testno
++, 1,
"$test_type: child before lock"
);
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testno
++, 1,
"$test_type: child obtained lock"
);
if
(
$test_type
=~
'twain'
) {
no
warnings
'threads'
;
cond_signal(
$cond
);
}
else
{
cond_signal(
$cond
);
}
$t1
=
time
();
}
ok(
$testno
++, 1,
"$test_type: child signalled condition"
);
return
(
$testno
,
$t1
-
$t0
);
}
sub
ctw_ok
{
my
(
$testnum
,
$to
) =
@_
;
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
lock
(
$ready
);
$ready
= 0;
my
(
$thr
) = threads->create(\
&signaller
,
$testnum
);
my
$ok
= 0;
cond_wait(
$ready
)
while
!
$ready
;
my
$t
;
for
(
$test_type
) {
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
),
last
if
/simple/;
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
,
$cond
),
last
if
/repeat/;
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
,
$lock
),
last
if
/twain/;
die
"$test_type: unknown test\n"
;
}
my
$child_time
;
(
$testnum
,
$child_time
) =
$thr
->
join
();
if
(
$ok
) {
ok(
$testnum
++,
$ok
,
"$test_type: condition obtained"
);
ok(
$testnum
++, 1,
"nothing to do here"
);
}
else
{
ok(
$testnum
++,
$child_time
>=
$to
,
"test_type: child exceeded time"
);
print
"# child time = $child_time\n"
;
ok(
$testnum
++,
$t
>=
$to
,
"test_type: parent exceeded time"
);
print
"# parent time = $t\n"
;
}
return
(
$testnum
);
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait [$_]"
;
my
$thr
= threads->create(\
&ctw_ok
,
$TEST
, 0.4);
$TEST
=
$thr
->
join
();
}
sub
ctw_fail
{
my
(
$testnum
,
$to
) =
@_
;
if
($^O eq
"hpux"
&&
$Config
{osvers} <= 10.20) {
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
ok(
$testnum
++, 0,
"# SKIP see perl583delta"
);
}
else
{
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
my
$ok
;
for
(
$test_type
) {
$ok
= cond_timedwait(
$cond
,
time
() +
$to
),
last
if
/simple/;
$ok
= cond_timedwait(
$cond
,
time
() +
$to
,
$cond
),
last
if
/repeat/;
$ok
= cond_timedwait(
$cond
,
time
() +
$to
,
$lock
),
last
if
/twain/;
die
"$test_type: unknown test\n"
;
}
ok(
$testnum
++, !
defined
(
$ok
),
"$test_type: timeout"
);
}
return
(
$testnum
);
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait pause, timeout [$_]"
;
my
$thr
= threads->create(\
&ctw_fail
,
$TEST
, 0.3);
$TEST
=
$thr
->
join
();
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait instant timeout [$_]"
;
my
$thr
= threads->create(\
&ctw_fail
,
$TEST
, -0.60);
$TEST
=
$thr
->
join
();
}
}
SYNCH_REFS: {
my
$test_type
:shared;
my
$true_cond
:shared;
my
$true_lock
:shared;
my
$ready
:shared;
my
$cond
= \
$true_cond
;
my
$lock
= \
$true_lock
;
ok(
$TEST
++, 1,
"Synchronization reference tests preparation"
);
sub
signaller2
{
my
$testno
=
$_
[0];
my
(
$t0
,
$t1
);
{
lock
(
$ready
);
$ready
= 1;
$t0
=
time
();
cond_signal(
$ready
);
}
{
ok(
$testno
++, 1,
"$test_type: child before lock"
);
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testno
++, 1,
"$test_type: child obtained lock"
);
if
(
$test_type
=~
'twain'
) {
no
warnings
'threads'
;
cond_signal(
$cond
);
}
else
{
cond_signal(
$cond
);
}
$t1
=
time
();
}
ok(
$testno
++, 1,
"$test_type: child signalled condition"
);
return
(
$testno
,
$t1
-
$t0
);
}
sub
ctw_ok2
{
my
(
$testnum
,
$to
) =
@_
;
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
lock
(
$ready
);
$ready
= 0;
my
(
$thr
) = threads->create(\
&signaller2
,
$testnum
);
my
$ok
= 0;
cond_wait(
$ready
)
while
!
$ready
;
my
$t
;
for
(
$test_type
) {
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
),
last
if
/simple/;
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
,
$cond
),
last
if
/repeat/;
(
$ok
,
$t
) = do_cond_timedwait(
$cond
,
$to
,
$lock
),
last
if
/twain/;
die
"$test_type: unknown test\n"
;
}
my
$child_time
;
(
$testnum
,
$child_time
) =
$thr
->
join
();
if
(
$ok
) {
ok(
$testnum
++,
$ok
,
"$test_type: condition obtained"
);
ok(
$testnum
++, 1,
"nothing to do here"
);
}
else
{
ok(
$testnum
++,
$child_time
>=
$to
,
"test_type: child exceeded time"
);
print
"# child time = $child_time\n"
;
ok(
$testnum
++,
$t
>=
$to
,
"test_type: parent exceeded time"
);
print
"# parent time = $t\n"
;
}
return
(
$testnum
);
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait [$_]"
;
my
$thr
= threads->create(\
&ctw_ok2
,
$TEST
, 0.4);
$TEST
=
$thr
->
join
();
}
sub
ctw_fail2
{
my
(
$testnum
,
$to
) =
@_
;
if
($^O eq
"hpux"
&&
$Config
{osvers} <= 10.20) {
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
ok(
$testnum
++, 0,
"# SKIP see perl583delta"
);
}
else
{
$test_type
=~ /twain/ ?
lock
(
$lock
) :
lock
(
$cond
);
ok(
$testnum
++, 1,
"$test_type: obtained initial lock"
);
my
$ok
;
for
(
$test_type
) {
$ok
= cond_timedwait(
$cond
,
time
() +
$to
),
last
if
/simple/;
$ok
= cond_timedwait(
$cond
,
time
() +
$to
,
$cond
),
last
if
/repeat/;
$ok
= cond_timedwait(
$cond
,
time
() +
$to
,
$lock
),
last
if
/twain/;
die
"$test_type: unknown test\n"
;
}
ok(
$testnum
++, !
defined
(
$ok
),
"$test_type: timeout"
);
}
return
(
$testnum
);
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait pause, timeout [$_]"
;
my
$thr
= threads->create(\
&ctw_fail2
,
$TEST
, 0.3);
$TEST
=
$thr
->
join
();
}
foreach
(
@wait_how
) {
$test_type
=
"cond_timedwait instant timeout [$_]"
;
my
$thr
= threads->create(\
&ctw_fail2
,
$TEST
, -0.60);
$TEST
=
$thr
->
join
();
}
}
exit
(0);