| 1 | #! /usr/bin/perl |
| 2 | ### -*-cperl-*- |
| 3 | ### |
| 4 | ### Job distribution for discrete logs |
| 5 | ### |
| 6 | ### (c) 2017 Mark Wooding |
| 7 | ### |
| 8 | |
| 9 | ###----- Licensing notice --------------------------------------------------- |
| 10 | ### |
| 11 | ### This file is part of Rhodes, a distributed discrete-log finder. |
| 12 | ### |
| 13 | ### Rhodes is free software; you can redistribute it and/or modify |
| 14 | ### it under the terms of the GNU General Public License as published by |
| 15 | ### the Free Software Foundation; either version 2 of the License, or |
| 16 | ### (at your option) any later version. |
| 17 | ### |
| 18 | ### Rhodes is distributed in the hope that it will be useful, |
| 19 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 | ### GNU General Public License for more details. |
| 22 | ### |
| 23 | ### You should have received a copy of the GNU General Public License |
| 24 | ### along with Rhodes; if not, write to the Free Software Foundation, |
| 25 | ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 26 | |
| 27 | use POSIX qw(:sys_wait_h); |
| 28 | |
| 29 | @ARGV == 2 or die "usage: $0 DIR WORKERS"; |
| 30 | my ($DIR, $WORKERS) = @ARGV; |
| 31 | |
| 32 | open my $fh, "<", $WORKERS or die "open($WORKERS): $!"; |
| 33 | my @W = (); |
| 34 | my @C = (); |
| 35 | my %P = (); |
| 36 | my @F = (); |
| 37 | while (<$fh>) { |
| 38 | next unless /^\s*[^#]/; |
| 39 | my ($w, $n, @c) = split; |
| 40 | for (my $i = 0; $i < $n; $i++) { |
| 41 | push @W, "$w#$i"; |
| 42 | push @C, \@c; |
| 43 | } |
| 44 | } |
| 45 | for (my $i = 0; $i < @W; $i++) { push @F, $i; } |
| 46 | |
| 47 | sub state { |
| 48 | system "./rhodes", "done", $DIR; |
| 49 | if ($? == 0) { return 'DONE'; } |
| 50 | elsif ($? == 512) { return 'IDLE'; } |
| 51 | elsif ($? != 256) { die "job broken: done rc = $?"; } |
| 52 | else { $STATE = 'BUSY'; } |
| 53 | } |
| 54 | |
| 55 | my $STATE = 'BUSY'; |
| 56 | my $RUN = 0; |
| 57 | while ($RUN || $STATE ne 'DONE') { |
| 58 | if ($STATE ne 'DONE') { $STATE = state; } |
| 59 | while (@F && $STATE eq 'BUSY') { |
| 60 | my $i = shift @F; |
| 61 | print "## -> $W[$i]\n"; |
| 62 | defined (my $kid = fork) or die "fork: $!"; |
| 63 | if (!$kid) { |
| 64 | exec "./rhodes", "step", $DIR, @{$C[$i]}; |
| 65 | die "exec: $!"; |
| 66 | } |
| 67 | $P{$kid} = $i; |
| 68 | $RUN++; |
| 69 | $STATE = state; |
| 70 | } |
| 71 | |
| 72 | my $kid = waitpid -1, 0; |
| 73 | while ($kid > 0) { |
| 74 | next unless exists $P{$kid}; |
| 75 | my $i = $P{$kid}; |
| 76 | print "## <- $W[$i] rc = $?\n"; |
| 77 | push @F, $i; $RUN--; |
| 78 | $kid = waitpid -1, WNOHANG; |
| 79 | } |
| 80 | } |