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>