#!/usr/bin/perl use strict; use IO::Socket::INET; use IO::Select; $|=1; my $p=$ARGV[0]; my @i=(); while( my $x = ) { chomp( $x ); push( @i, $x ); } my $inos=scalar(@i); my %p=(); $p{p}=$p; $p{pc}=0; $p{reg}=(); $p{reg}{p}=$p; $p{sendct}=0; $p{run}=1; $p{lrcv}=time(); my $csock; my $sel= IO::Select->new(); if( $p == 0 ) { # Master # Listen # Accept my $socket = new IO::Socket::INET ( LocalHost => '127.0.0.1', LocalPort => '7777', Proto => 'tcp', Listen => 5, Reuse => 1 ); if( !defined( $socket ) ) { print "Can't open socket: $!\n"; exit; } print "p0: Awaiting connection\n"; $csock = $socket->accept(); print "p0: Got connection\n"; } elsif( $p == 1 ) { # Slave # Connect while( ! defined( $csock ) ) { $csock = new IO::Socket::INET ( PeerHost => '127.0.0.1', PeerPort => '7777', Proto => 'tcp' ); if( ! defined( $csock ) ) { print "p1: Can't connect to master, sleeping.\n"; sleep(1); } } print "p1: Connected!\n"; } else { print "UNKNOWN $p\n"; exit; } $sel->add( $csock ); while( $p{run} == 1 ) { go( \%p ); } if( $p == 1 ) { print "p1 sent $p{sendct} values\n"; } sleep(3); exit; sub go { my ( $comp ) = @_; if( $comp->{run} != 1 ) { return; } my $pc=$comp->{pc}; if( $i[$pc] =~ /^snd (-?\d+)$/ ) { my $f=$1; $csock->send( "$f\n" ); $comp->{sendct}++; $comp->{pc}++; } elsif( $i[$pc] =~ /^snd ([a-z]+)$/ ) { my $r=$1; $csock->send( "$comp->{reg}{$r}\n" ); $comp->{sendct}++; $comp->{pc}++; } elsif( $i[$pc] =~ /^rcv ([a-z]+)$/ ) { my $r=$1; #print "RCV: $comp->{p} has sent $comp->{sendct}\n"; while( !$sel->can_read(0.001) ) { my $n=time()-$comp->{lrcv}; if( time()-$comp->{lrcv} >= 5 ) { print "RCV: $comp->{p} not received anything for 5 seconds. assuming deadlock and exiting.\n"; $comp->{run}=0; return; } } #print "AWAIT $comp->{p}\n"; my $l = <$csock>; # Cheap and nasty, get a single line, avoids having to deal with socket->read() which could get multiple chunks of data chomp( $l ); # print "GOT: $comp->{p} [$l]\n"; $comp->{reg}{$r}=$l; $comp->{pc}++; $comp->{lrcv}=time(); } elsif( $i[$pc] =~ /^set ([a-z]+) (-?\d+)$/ ) { my $r=$1; my $n=$2; $comp->{reg}{$r}=$n; $comp->{pc}++; } elsif( $i[$pc] =~ /^set ([a-z]+) ([a-z]+)$/ ) { my $r1=$1; my $r2=$2; $comp->{reg}{$r1}=$comp->{reg}{$r2}; $comp->{pc}++; } elsif( $i[$pc] =~ /^add ([a-z]+) (-?\d+)$/ ) { my $r=$1; my $n=$2; $comp->{reg}{$r}+=$n; $comp->{pc}++; } elsif( $i[$pc] =~ /^add ([a-z]+) ([a-z]+)$/ ) { my $r1=$1; my $r2=$2; $comp->{reg}{$r1}+=$comp->{reg}{$r2}; $comp->{pc}++; } elsif( $i[$pc] =~ /^mul ([a-z]+) (-?\d+)$/ ) { my $r=$1; my $n=$2; $comp->{reg}{$r}*=$n; $comp->{pc}++; } elsif( $i[$pc] =~ /^mul ([a-z]+) ([a-z]+)$/ ) { my $r1=$1; my $r2=$2; $comp->{reg}{$r1}*=$comp->{reg}{$r2}; $comp->{pc}++; } elsif( $i[$pc] =~ /^mod ([a-z]+) (-?\d+)$/ ) { my $r=$1; my $n=$2; $comp->{reg}{$r}%=$n; $comp->{pc}++; } elsif( $i[$pc] =~ /^mod ([a-z]+) ([a-z]+)$/ ) { my $r1=$1; my $r2=$2; $comp->{reg}{$r1}%=$comp->{reg}{$r2}; $comp->{pc}++; } elsif( $i[$pc] =~ /^jgz (-?\d+) (-?\d+)$/ ) { my $rn=$1; my $n=$2; if( $rn > 0 ) { $comp->{pc}+=$n; } else { $comp->{pc}++; } } elsif( $i[$pc] =~ /^jgz ([a-z]+) (-?\d+)$/ ) { my $r=$1; my $n=$2; if( int($comp->{reg}{$r}) > 0 ) { $comp->{pc}+=$n; } else { $comp->{pc}++; } } elsif( $i[$pc] =~ /^jgz ([a-z]+) ([a-z]+)$/ ) { my $r1=$1; my $r2=$2; if( int($comp->{reg}{$r1}) > 0 ) { $comp->{pc}+=$comp->{reg}{$r2}; } else { $comp->{pc}++; } } else { print "UNHANDLED: [$i[$pc]]\n"; exit; } if( $pc < 0 || $pc >= $inos ) { $comp->{run}=0; } }