1*91f110e0Safresh1use strict; 2*91f110e0Safresh1use warnings; 3*91f110e0Safresh1 4*91f110e0Safresh1BEGIN { 5*91f110e0Safresh1 use Config; 6*91f110e0Safresh1 if (! $Config{'useithreads'}) { 7*91f110e0Safresh1 print("1..0 # SKIP Perl not compiled with 'useithreads'\n"); 8*91f110e0Safresh1 exit(0); 9*91f110e0Safresh1 } 10*91f110e0Safresh1} 11*91f110e0Safresh1 12*91f110e0Safresh1use ExtUtils::testlib; 13*91f110e0Safresh1 14*91f110e0Safresh1BEGIN { 15*91f110e0Safresh1 $| = 1; 16*91f110e0Safresh1 print("1..226\n"); ### Number of tests that will be run ### 17*91f110e0Safresh1} 18*91f110e0Safresh1 19*91f110e0Safresh1use threads; 20*91f110e0Safresh1use threads::shared; 21*91f110e0Safresh1use Scalar::Util qw(dualvar); 22*91f110e0Safresh1 23*91f110e0Safresh1my $TEST = 1; 24*91f110e0Safresh1 25*91f110e0Safresh1sub ok { 26*91f110e0Safresh1 my ($ok, $name) = @_; 27*91f110e0Safresh1 28*91f110e0Safresh1 # You have to do it this way or VMS will get confused. 29*91f110e0Safresh1 if ($ok) { 30*91f110e0Safresh1 print("ok $TEST - $name\n"); 31*91f110e0Safresh1 } else { 32*91f110e0Safresh1 print("not ok $TEST - $name\n"); 33*91f110e0Safresh1 printf("# Failed test at line %d\n", (caller(1))[2]); 34*91f110e0Safresh1 } 35*91f110e0Safresh1 36*91f110e0Safresh1 $TEST++; 37*91f110e0Safresh1} 38*91f110e0Safresh1 39*91f110e0Safresh1sub ok_iv 40*91f110e0Safresh1{ 41*91f110e0Safresh1 my ($var, $iv) = @_; 42*91f110e0Safresh1 ok($var == $iv, 'IV number preserved'); 43*91f110e0Safresh1 ok($var eq $iv, 'String preserved'); 44*91f110e0Safresh1} 45*91f110e0Safresh1 46*91f110e0Safresh1sub ok_nv 47*91f110e0Safresh1{ 48*91f110e0Safresh1 my ($var, $nv) = @_; 49*91f110e0Safresh1 ok($var == $nv, 'NV number preserved'); 50*91f110e0Safresh1 ok($var eq $nv, 'String preserved'); 51*91f110e0Safresh1} 52*91f110e0Safresh1 53*91f110e0Safresh1sub ok_uv 54*91f110e0Safresh1{ 55*91f110e0Safresh1 my ($var, $uv) = @_; 56*91f110e0Safresh1 ok($var == $uv, 'UV number preserved'); 57*91f110e0Safresh1 ok($var > 0, 'UV number preserved'); 58*91f110e0Safresh1 ok($var eq $uv, 'String preserved'); 59*91f110e0Safresh1} 60*91f110e0Safresh1 61*91f110e0Safresh1### Start of Testing ### 62*91f110e0Safresh1 63*91f110e0Safresh1my $iv = dualvar(42, 'Fourty-Two'); 64*91f110e0Safresh1my $nv = dualvar(3.14, 'PI'); 65*91f110e0Safresh1my $bits = ($Config{'use64bitint'}) ? 63 : 31; 66*91f110e0Safresh1my $uv = dualvar(1<<$bits, 'Large unsigned int'); 67*91f110e0Safresh1 68*91f110e0Safresh1print("# Shared scalar assignment using shared_clone()\n"); 69*91f110e0Safresh1 70*91f110e0Safresh1my $siv :shared = shared_clone($iv); 71*91f110e0Safresh1my $snv :shared = shared_clone($nv); 72*91f110e0Safresh1my $suv :shared = shared_clone($uv); 73*91f110e0Safresh1 74*91f110e0Safresh1ok_iv($siv, $iv); 75*91f110e0Safresh1ok_nv($snv, $nv); 76*91f110e0Safresh1ok_uv($suv, $uv); 77*91f110e0Safresh1 78*91f110e0Safresh1{ 79*91f110e0Safresh1 print("# Shared array initialization\n"); 80*91f110e0Safresh1 81*91f110e0Safresh1 my @ary :shared = ($iv, $nv, $uv); 82*91f110e0Safresh1 83*91f110e0Safresh1 ok_iv($ary[0], $iv); 84*91f110e0Safresh1 ok_nv($ary[1], $nv); 85*91f110e0Safresh1 ok_uv($ary[2], $uv); 86*91f110e0Safresh1} 87*91f110e0Safresh1 88*91f110e0Safresh1{ 89*91f110e0Safresh1 print("# Shared array list assignment\n"); 90*91f110e0Safresh1 91*91f110e0Safresh1 my @ary :shared; 92*91f110e0Safresh1 @ary = ($iv, $nv, $uv); 93*91f110e0Safresh1 94*91f110e0Safresh1 ok_iv($ary[0], $iv); 95*91f110e0Safresh1 ok_nv($ary[1], $nv); 96*91f110e0Safresh1 ok_uv($ary[2], $uv); 97*91f110e0Safresh1} 98*91f110e0Safresh1 99*91f110e0Safresh1{ 100*91f110e0Safresh1 print("# Shared array element assignment\n"); 101*91f110e0Safresh1 102*91f110e0Safresh1 my @ary :shared; 103*91f110e0Safresh1 $ary[0] = $iv; 104*91f110e0Safresh1 $ary[1] = $nv; 105*91f110e0Safresh1 $ary[2] = $uv; 106*91f110e0Safresh1 107*91f110e0Safresh1 ok_iv($ary[0], $iv); 108*91f110e0Safresh1 ok_nv($ary[1], $nv); 109*91f110e0Safresh1 ok_uv($ary[2], $uv); 110*91f110e0Safresh1} 111*91f110e0Safresh1 112*91f110e0Safresh1{ 113*91f110e0Safresh1 print("# Shared array initialization - shared scalars\n"); 114*91f110e0Safresh1 115*91f110e0Safresh1 my @ary :shared = ($siv, $snv, $suv); 116*91f110e0Safresh1 117*91f110e0Safresh1 ok_iv($ary[0], $iv); 118*91f110e0Safresh1 ok_nv($ary[1], $nv); 119*91f110e0Safresh1 ok_uv($ary[2], $uv); 120*91f110e0Safresh1} 121*91f110e0Safresh1 122*91f110e0Safresh1{ 123*91f110e0Safresh1 print("# Shared array list assignment - shared scalars\n"); 124*91f110e0Safresh1 125*91f110e0Safresh1 my @ary :shared; 126*91f110e0Safresh1 @ary = ($siv, $snv, $suv); 127*91f110e0Safresh1 128*91f110e0Safresh1 ok_iv($ary[0], $iv); 129*91f110e0Safresh1 ok_nv($ary[1], $nv); 130*91f110e0Safresh1 ok_uv($ary[2], $uv); 131*91f110e0Safresh1} 132*91f110e0Safresh1 133*91f110e0Safresh1{ 134*91f110e0Safresh1 print("# Shared array element assignment - shared scalars\n"); 135*91f110e0Safresh1 136*91f110e0Safresh1 my @ary :shared; 137*91f110e0Safresh1 $ary[0] = $siv; 138*91f110e0Safresh1 $ary[1] = $snv; 139*91f110e0Safresh1 $ary[2] = $suv; 140*91f110e0Safresh1 141*91f110e0Safresh1 ok_iv($ary[0], $iv); 142*91f110e0Safresh1 ok_nv($ary[1], $nv); 143*91f110e0Safresh1 ok_uv($ary[2], $uv); 144*91f110e0Safresh1} 145*91f110e0Safresh1 146*91f110e0Safresh1{ 147*91f110e0Safresh1 print("# Shared hash initialization\n"); 148*91f110e0Safresh1 149*91f110e0Safresh1 my %hsh :shared = ( 150*91f110e0Safresh1 'iv' => $iv, 151*91f110e0Safresh1 'nv' => $nv, 152*91f110e0Safresh1 'uv' => $uv, 153*91f110e0Safresh1 ); 154*91f110e0Safresh1 155*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 156*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 157*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 158*91f110e0Safresh1} 159*91f110e0Safresh1 160*91f110e0Safresh1{ 161*91f110e0Safresh1 print("# Shared hash assignment\n"); 162*91f110e0Safresh1 163*91f110e0Safresh1 my %hsh :shared; 164*91f110e0Safresh1 %hsh = ( 165*91f110e0Safresh1 'iv' => $iv, 166*91f110e0Safresh1 'nv' => $nv, 167*91f110e0Safresh1 'uv' => $uv, 168*91f110e0Safresh1 ); 169*91f110e0Safresh1 170*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 171*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 172*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 173*91f110e0Safresh1} 174*91f110e0Safresh1 175*91f110e0Safresh1{ 176*91f110e0Safresh1 print("# Shared hash element assignment\n"); 177*91f110e0Safresh1 178*91f110e0Safresh1 my %hsh :shared; 179*91f110e0Safresh1 $hsh{'iv'} = $iv; 180*91f110e0Safresh1 $hsh{'nv'} = $nv; 181*91f110e0Safresh1 $hsh{'uv'} = $uv; 182*91f110e0Safresh1 183*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 184*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 185*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 186*91f110e0Safresh1} 187*91f110e0Safresh1 188*91f110e0Safresh1{ 189*91f110e0Safresh1 print("# Shared hash initialization - shared scalars\n"); 190*91f110e0Safresh1 191*91f110e0Safresh1 my %hsh :shared = ( 192*91f110e0Safresh1 'iv' => $siv, 193*91f110e0Safresh1 'nv' => $snv, 194*91f110e0Safresh1 'uv' => $suv, 195*91f110e0Safresh1 ); 196*91f110e0Safresh1 197*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 198*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 199*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 200*91f110e0Safresh1} 201*91f110e0Safresh1 202*91f110e0Safresh1{ 203*91f110e0Safresh1 print("# Shared hash assignment - shared scalars\n"); 204*91f110e0Safresh1 205*91f110e0Safresh1 my %hsh :shared; 206*91f110e0Safresh1 %hsh = ( 207*91f110e0Safresh1 'iv' => $siv, 208*91f110e0Safresh1 'nv' => $snv, 209*91f110e0Safresh1 'uv' => $suv, 210*91f110e0Safresh1 ); 211*91f110e0Safresh1 212*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 213*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 214*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 215*91f110e0Safresh1} 216*91f110e0Safresh1 217*91f110e0Safresh1{ 218*91f110e0Safresh1 print("# Shared hash element assignment - shared scalars\n"); 219*91f110e0Safresh1 220*91f110e0Safresh1 my %hsh :shared; 221*91f110e0Safresh1 $hsh{'iv'} = $siv; 222*91f110e0Safresh1 $hsh{'nv'} = $snv; 223*91f110e0Safresh1 $hsh{'uv'} = $suv; 224*91f110e0Safresh1 225*91f110e0Safresh1 ok_iv($hsh{'iv'}, $iv); 226*91f110e0Safresh1 ok_nv($hsh{'nv'}, $nv); 227*91f110e0Safresh1 ok_uv($hsh{'uv'}, $uv); 228*91f110e0Safresh1} 229*91f110e0Safresh1 230*91f110e0Safresh1{ 231*91f110e0Safresh1 print("# Shared array push\n"); 232*91f110e0Safresh1 233*91f110e0Safresh1 my @ary :shared; 234*91f110e0Safresh1 push(@ary, $iv, $nv, $uv); 235*91f110e0Safresh1 236*91f110e0Safresh1 ok_iv($ary[0], $iv); 237*91f110e0Safresh1 ok_nv($ary[1], $nv); 238*91f110e0Safresh1 ok_uv($ary[2], $uv); 239*91f110e0Safresh1 240*91f110e0Safresh1 print("# Shared array pop\n"); 241*91f110e0Safresh1 242*91f110e0Safresh1 my $xuv = pop(@ary); 243*91f110e0Safresh1 my $xnv = pop(@ary); 244*91f110e0Safresh1 my $xiv = pop(@ary); 245*91f110e0Safresh1 246*91f110e0Safresh1 ok_iv($xiv, $iv); 247*91f110e0Safresh1 ok_nv($xnv, $nv); 248*91f110e0Safresh1 ok_uv($xuv, $uv); 249*91f110e0Safresh1 250*91f110e0Safresh1 print("# Shared array unshift\n"); 251*91f110e0Safresh1 252*91f110e0Safresh1 unshift(@ary, $iv, $nv, $uv); 253*91f110e0Safresh1 254*91f110e0Safresh1 ok_iv($ary[0], $iv); 255*91f110e0Safresh1 ok_nv($ary[1], $nv); 256*91f110e0Safresh1 ok_uv($ary[2], $uv); 257*91f110e0Safresh1 258*91f110e0Safresh1 print("# Shared array shift\n"); 259*91f110e0Safresh1 260*91f110e0Safresh1 $xiv = shift(@ary); 261*91f110e0Safresh1 $xnv = shift(@ary); 262*91f110e0Safresh1 $xuv = shift(@ary); 263*91f110e0Safresh1 264*91f110e0Safresh1 ok_iv($xiv, $iv); 265*91f110e0Safresh1 ok_nv($xnv, $nv); 266*91f110e0Safresh1 ok_uv($xuv, $uv); 267*91f110e0Safresh1} 268*91f110e0Safresh1 269*91f110e0Safresh1{ 270*91f110e0Safresh1 print("# Shared array push - shared scalars\n"); 271*91f110e0Safresh1 272*91f110e0Safresh1 my @ary :shared; 273*91f110e0Safresh1 push(@ary, $siv, $snv, $suv); 274*91f110e0Safresh1 275*91f110e0Safresh1 ok_iv($ary[0], $iv); 276*91f110e0Safresh1 ok_nv($ary[1], $nv); 277*91f110e0Safresh1 ok_uv($ary[2], $uv); 278*91f110e0Safresh1 279*91f110e0Safresh1 print("# Shared array pop - shared scalars\n"); 280*91f110e0Safresh1 281*91f110e0Safresh1 my $xuv = pop(@ary); 282*91f110e0Safresh1 my $xnv = pop(@ary); 283*91f110e0Safresh1 my $xiv = pop(@ary); 284*91f110e0Safresh1 285*91f110e0Safresh1 ok_iv($xiv, $iv); 286*91f110e0Safresh1 ok_nv($xnv, $nv); 287*91f110e0Safresh1 ok_uv($xuv, $uv); 288*91f110e0Safresh1 289*91f110e0Safresh1 print("# Shared array unshift - shared scalars\n"); 290*91f110e0Safresh1 291*91f110e0Safresh1 unshift(@ary, $siv, $snv, $suv); 292*91f110e0Safresh1 293*91f110e0Safresh1 ok_iv($ary[0], $iv); 294*91f110e0Safresh1 ok_nv($ary[1], $nv); 295*91f110e0Safresh1 ok_uv($ary[2], $uv); 296*91f110e0Safresh1 297*91f110e0Safresh1 print("# Shared array shift - shared scalars\n"); 298*91f110e0Safresh1 299*91f110e0Safresh1 $xiv = shift(@ary); 300*91f110e0Safresh1 $xnv = shift(@ary); 301*91f110e0Safresh1 $xuv = shift(@ary); 302*91f110e0Safresh1 303*91f110e0Safresh1 ok_iv($xiv, $iv); 304*91f110e0Safresh1 ok_nv($xnv, $nv); 305*91f110e0Safresh1 ok_uv($xuv, $uv); 306*91f110e0Safresh1} 307*91f110e0Safresh1 308*91f110e0Safresh1{ 309*91f110e0Safresh1 print("# Shared hash delete\n"); 310*91f110e0Safresh1 311*91f110e0Safresh1 my %hsh :shared = ( 312*91f110e0Safresh1 'iv' => $iv, 313*91f110e0Safresh1 'nv' => $nv, 314*91f110e0Safresh1 'uv' => $uv, 315*91f110e0Safresh1 ); 316*91f110e0Safresh1 317*91f110e0Safresh1 ok_iv(delete($hsh{'iv'}), $iv); 318*91f110e0Safresh1 ok_nv(delete($hsh{'nv'}), $nv); 319*91f110e0Safresh1 ok_uv(delete($hsh{'uv'}), $uv); 320*91f110e0Safresh1} 321*91f110e0Safresh1 322*91f110e0Safresh1{ 323*91f110e0Safresh1 print("# Shared hash delete - shared scalars\n"); 324*91f110e0Safresh1 325*91f110e0Safresh1 my %hsh :shared = ( 326*91f110e0Safresh1 'iv' => $siv, 327*91f110e0Safresh1 'nv' => $snv, 328*91f110e0Safresh1 'uv' => $suv, 329*91f110e0Safresh1 ); 330*91f110e0Safresh1 331*91f110e0Safresh1 ok_iv(delete($hsh{'iv'}), $iv); 332*91f110e0Safresh1 ok_nv(delete($hsh{'nv'}), $nv); 333*91f110e0Safresh1 ok_uv(delete($hsh{'uv'}), $uv); 334*91f110e0Safresh1} 335*91f110e0Safresh1 336*91f110e0Safresh1{ 337*91f110e0Safresh1 print("# Shared array copy to non-shared array\n"); 338*91f110e0Safresh1 339*91f110e0Safresh1 my @ary :shared = ($iv, $nv, $uv); 340*91f110e0Safresh1 my @nsa = @ary; 341*91f110e0Safresh1 342*91f110e0Safresh1 ok_iv($nsa[0], $iv); 343*91f110e0Safresh1 ok_nv($nsa[1], $nv); 344*91f110e0Safresh1 ok_uv($nsa[2], $uv); 345*91f110e0Safresh1 346*91f110e0Safresh1 print("# Shared array copy using shared_clone()\n"); 347*91f110e0Safresh1 348*91f110e0Safresh1 my $copy :shared = shared_clone(\@nsa); 349*91f110e0Safresh1 350*91f110e0Safresh1 ok_iv($$copy[0], $iv); 351*91f110e0Safresh1 ok_nv($$copy[1], $nv); 352*91f110e0Safresh1 ok_uv($$copy[2], $uv); 353*91f110e0Safresh1} 354*91f110e0Safresh1 355*91f110e0Safresh1{ 356*91f110e0Safresh1 print("# Shared array copy to non-shared array - shared scalars\n"); 357*91f110e0Safresh1 358*91f110e0Safresh1 my @ary :shared = ($siv, $snv, $suv); 359*91f110e0Safresh1 my @nsa = @ary; 360*91f110e0Safresh1 361*91f110e0Safresh1 ok_iv($nsa[0], $iv); 362*91f110e0Safresh1 ok_nv($nsa[1], $nv); 363*91f110e0Safresh1 ok_uv($nsa[2], $uv); 364*91f110e0Safresh1 365*91f110e0Safresh1 print("# Shared array copy using shared_clone()\n"); 366*91f110e0Safresh1 367*91f110e0Safresh1 my $copy :shared = shared_clone(\@nsa); 368*91f110e0Safresh1 369*91f110e0Safresh1 ok_iv($$copy[0], $iv); 370*91f110e0Safresh1 ok_nv($$copy[1], $nv); 371*91f110e0Safresh1 ok_uv($$copy[2], $uv); 372*91f110e0Safresh1} 373*91f110e0Safresh1 374*91f110e0Safresh1{ 375*91f110e0Safresh1 print("# Shared hash copy to non-shared hash\n"); 376*91f110e0Safresh1 377*91f110e0Safresh1 my %hsh :shared = ( 378*91f110e0Safresh1 'iv' => $iv, 379*91f110e0Safresh1 'nv' => $nv, 380*91f110e0Safresh1 'uv' => $uv, 381*91f110e0Safresh1 ); 382*91f110e0Safresh1 my %nsh = %hsh; 383*91f110e0Safresh1 384*91f110e0Safresh1 ok_iv($nsh{'iv'}, $iv); 385*91f110e0Safresh1 ok_nv($nsh{'nv'}, $nv); 386*91f110e0Safresh1 ok_uv($nsh{'uv'}, $uv); 387*91f110e0Safresh1 388*91f110e0Safresh1 print("# Shared hash copy using shared_clone()\n"); 389*91f110e0Safresh1 390*91f110e0Safresh1 my $copy :shared = shared_clone(\%nsh); 391*91f110e0Safresh1 392*91f110e0Safresh1 ok_iv($$copy{'iv'}, $iv); 393*91f110e0Safresh1 ok_nv($$copy{'nv'}, $nv); 394*91f110e0Safresh1 ok_uv($$copy{'uv'}, $uv); 395*91f110e0Safresh1} 396*91f110e0Safresh1 397*91f110e0Safresh1{ 398*91f110e0Safresh1 print("# Shared hash copy to non-shared hash - shared scalars\n"); 399*91f110e0Safresh1 400*91f110e0Safresh1 my %hsh :shared = ( 401*91f110e0Safresh1 'iv' => $siv, 402*91f110e0Safresh1 'nv' => $snv, 403*91f110e0Safresh1 'uv' => $suv, 404*91f110e0Safresh1 ); 405*91f110e0Safresh1 my %nsh = %hsh; 406*91f110e0Safresh1 407*91f110e0Safresh1 ok_iv($nsh{'iv'}, $iv); 408*91f110e0Safresh1 ok_nv($nsh{'nv'}, $nv); 409*91f110e0Safresh1 ok_uv($nsh{'uv'}, $uv); 410*91f110e0Safresh1 411*91f110e0Safresh1 print("# Shared hash copy using shared_clone()\n"); 412*91f110e0Safresh1 413*91f110e0Safresh1 my $copy :shared = shared_clone(\%nsh); 414*91f110e0Safresh1 415*91f110e0Safresh1 ok_iv($$copy{'iv'}, $iv); 416*91f110e0Safresh1 ok_nv($$copy{'nv'}, $nv); 417*91f110e0Safresh1 ok_uv($$copy{'uv'}, $uv); 418*91f110e0Safresh1} 419*91f110e0Safresh1 420*91f110e0Safresh1print("# Mix it up with a thread\n"); 421*91f110e0Safresh1my @ary :shared; 422*91f110e0Safresh1my %hsh :shared; 423*91f110e0Safresh1 424*91f110e0Safresh1threads->create(sub { 425*91f110e0Safresh1 @ary = ($siv); 426*91f110e0Safresh1 push(@ary, $snv); 427*91f110e0Safresh1 428*91f110e0Safresh1 %hsh = ( 'nv' => $ary[1] ); 429*91f110e0Safresh1 $hsh{'iv'} = $ary[0]; 430*91f110e0Safresh1 $hsh{'uv'} = $suv; 431*91f110e0Safresh1 432*91f110e0Safresh1 $ary[2] = $hsh{'uv'}; 433*91f110e0Safresh1 })->join(); 434*91f110e0Safresh1 435*91f110e0Safresh1ok_iv($hsh{'iv'}, $ary[0]); 436*91f110e0Safresh1ok_nv($hsh{'nv'}, $ary[1]); 437*91f110e0Safresh1ok_uv($hsh{'uv'}, $ary[2]); 438*91f110e0Safresh1 439*91f110e0Safresh1# $! behaves like a dualvar, but is really implemented as a tied SV. 440*91f110e0Safresh1# As a result sharing $! directly only propagates the string value. 441*91f110e0Safresh1# However, we can create a dualvar from it. 442*91f110e0Safresh1print("# Errno\n"); 443*91f110e0Safresh1$! = 1; 444*91f110e0Safresh1my $ss :shared = dualvar($!,$!); 445*91f110e0Safresh1ok_iv($ss, $!); 446*91f110e0Safresh1 447*91f110e0Safresh1exit(0); 448