use warnings ; use strict ; my $MASK = @ARGV ? shift(@ARGV) : 1 ; my $TWIDDLE = @ARGV ? shift(@ARGV) : 1 ; $| = 1 ; use POSIX qw(:signal_h) ; use Time::HiRes qw(time) ; my $main_alrm = 0 ; my $temp_alrm = 0 ; $SIG{ALRM} = sub { $main_alrm++ ; }; sub set_temp_alrm { my $sigset = POSIX::SigSet->new ; my $blockset = POSIX::SigSet->new( SIGALRM ) ; sigprocmask(SIG_BLOCK, $blockset, $sigset) if $MASK ; local $SIG{ALRM} = sub { $temp_alrm++ ; } ; sigprocmask(SIG_SETMASK, $sigset) if $MASK ; my $t = $TWIDDLE ; while ($t) { $t-- ; } ; } ; if (fork) { print "parent started MASK=$MASK TWIDDLE=$TWIDDLE\n" ; my $start = time ; my $next = $start ; while (1) { set_temp_alrm() ; my $now = time ; if ($now > $next) { printf "main:%6d temp:%6d after:%6.1fs\n", $main_alrm, $temp_alrm, $now-$start ; $next = $now + 1 ; } ; } ; } else { print "child started\n" ; sleep 2 ; print "ALRM storm started\n"; 1 while kill ALRM => getppid; } ;