Date: 10 Jun 1998 21:41:08 -0500 From: sfarrell@farrell.org To: freebsd hackers <hackers@FreeBSD.ORG> Subject: perl forking causes panic in 2.2.6-stable Message-ID: <87bts0lkxn.fsf@couatl.uchicago.edu>
next in thread | raw e-mail | index | archive | help
tom christiansen posted a nifty prime number generator script that
uses forking to approximate threads [attached below].
i decided it was a little bit boring at only find primes under 1000,
so i upped the number to 5000.
unfortunately this panics my machine! the panic is get_pv_entry:
cannot get a pv_entry_t. i tried a less creative fork bomb with sh
and noticed that it gives "cannot fork", causes significant denial of
service, but can be killed and does not panic.
sparc/solaris gives an error: can't pipe: too many open files...,
but no panic.
FreeBSD 2.2.6-STABLE #0: Mon Jun 8 21:58:37 CDT 1998
-------------------------------------------------------------------
#!/usr/bin/perl
# prime-fork: use sugalskd's thread algorithm
# but with real processes.
sub main;
sub check_num;
sub forksub(&);
sub queue;
sub enqueue(*$);
sub dequeue(*);
use strict;
main();
exit;
sub main {
pipe(UPSTREAM, DOWNSTREAM);
my($head,$tail) = queue();
my $kid = forksub {
close($tail);
check_num($head, 2)
};
close $head;
for (my $i = 3; $i <= 5000; $i++) {
enqueue($tail, $i);
}
close $tail;
waitpid($kid,0);
}
sub check_num {
my ($stream, $cur_prime) = @_;
my ($spawned, $num);
my($head, $tail) = queue();
while ($num = dequeue($stream) ) {
next unless $num % $cur_prime;
if ($spawned) {
enqueue($tail, $num);
next;
}
print "Found prime $num\n";
$spawned = forksub {
close($tail);
check_num($head, $num)
};
close $head;
}
close($head) unless $spawned;
close($tail);
waitpid($spawned,0) if $spawned;
exit;
}
sub forksub(&) {
my $coderef = $_[0];
my $pid = fork();
die "cannot fork: $!" unless defined $pid;
return $pid if $pid;
goto &$coderef; # don't need no stinkin' stack frames
}
sub queue {
local(*READER, *WRITER);
pipe(READER, WRITER) || die "can't pipe: $!";
return (*READER, *WRITER);
}
sub enqueue(*$) {
my ($stream, $n) = @_;
syswrite($stream, pack("L", $n), 4); # XXX: errno
}
sub dequeue(*) {
my ($stream) = @_;
my $n;
sysread($stream, $n, 4) == 4 || return;
unpack("L", $n);
}
--
Steve Farrell
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87bts0lkxn.fsf>
