#! /usr/bin/perl use POSIX qw(:sys_wait_h); @ARGV == 2 or die "usage: $0 DIR WORKERS"; my ($DIR, $WORKERS) = @ARGV; open my $fh, "<", $WORKERS or die "open($WORKERS): $!"; my @W = (); my @C = (); my %P = (); my @F = (); while (<$fh>) { next unless /^\s*[^#]/; my ($w, $n, @c) = split; for (my $i = 0; $i < $n; $i++) { push @W, "$w#$i"; push @C, \@c; } } for (my $i = 0; $i < @W; $i++) { push @F, $i; } sub state { system "./rhodes", "done", $DIR; if ($? == 0) { return 'DONE'; } elsif ($? == 512) { return 'IDLE'; } elsif ($? != 256) { die "job broken: done rc = $?"; } else { $STATE = 'BUSY'; } } my $STATE = 'BUSY'; my $RUN = 0; while ($RUN || $STATE ne 'DONE') { if ($STATE ne 'DONE') { $STATE = state; } while (@F && $STATE eq 'BUSY') { my $i = shift @F; print "## -> $W[$i]\n"; defined (my $kid = fork) or die "fork: $!"; if (!$kid) { exec "./rhodes", "step", $DIR, @{$C[$i]}; die "exec: $!"; } $P{$kid} = $i; $RUN++; $STATE = state; } my $kid = waitpid -1, 0; while ($kid > 0) { next unless exists $P{$kid}; my $i = $P{$kid}; print "## <- $W[$i] rc = $?\n"; push @F, $i; $RUN--; $kid = waitpid -1, WNOHANG; } }