foreach $line () { chomp $line; if ($line =~ m/(\d)-(\d)->(\d)-(\d)/) { #create local sender and receiver vars my $sp = "$1-$2"; my $rp = "$3-$4"; #update sender and receiver hashes $sender{$sp} = $rp; $receiver{$rp} = $sp; print "enter $sender{$sp}->$receiver{$rp} in dependency hashes\n"; } elsif($line =~ m/(\d)-(\d)/) { #create local process var my $p = "$1-$2"; #queue process on @p_s multi-dimensional array unshift (@{$p_s[$1]},$p); print "unshift $p_s[$1][0] onto process array\n"; $numevents++; } else { print "\nunmatched line: $line \n"; chomp($line); #remove empty newlines in input file } } #### while($timestamp <= $numevents) { print "\ntimestamp: $timestamp, numevents: $numevents\n"; foreach $pid (@p_s) { my $p_e = 0, $p_t = 0; #for every process pop the first event and examine it if($p_e = pop @{$p_s[$pid]}) { #if process-event has receiver-dependency then push it back on the stack if($receiver{$p_e}) { push (@{$p_s[$pid]},$p_e); } else { my $s_o = 0; #else if process-event has sender-obligation then update sender and reciever hashes if($s_o = $sender{$p_e}) { delete $sender{$p_e}; delete $receiver{$s_o}; } #and then enqueue process-event with process-timestamp in schedule hash if($p_e =~ m/(\d)-(\d)/) { $p_t = "$timestamp.$1" } else { print "\nerror parsing processor-event signature\n"; } $schedule{$p_e} = $p_t; unshift (@totalorder, $p_t); } } } $timestamp++; } #### $pid = 0; #process index @p_s = (); #2d process array/stack %sender = (); #sending event hash %receiver = (); #receiving event hash $numevents = 0; #total number of events in all processes $timestamp = 0; #timestamp for event scheduler %schedule = (); #hash of each event with timestamp @totalorder = (); #final order of each event #### ################### #Lamport.pl ################### #!/usr/bin/perl -w #begin main routine #$pid = 0; #process index #@p_s = (); #process stack #%sender = (); #sending event hash #%receiver = (); #receiving event hash #$numevents = 0; #total number of events in all processes #$timestamp = 0; #timestamp for event scheduler #%schedule = (); #= Tie::IxHash->new(); #@totalorder = (); #read process/event input from file open FILE, $ARGV[0] or die "$ARGV[0] can't be opened:\n$!"; #local $/; # Set input to "slurp" mode. #initialize process/event stack/hash from input file print "\nbegin Lamport's algorithm for input file $ARGV[0]\n"; foreach $line () { chomp $line; if ($line =~ m/(\d)-(\d)->(\d)-(\d)/) { #create local sender and receiver vars my $sp = "$1-$2"; my $rp = "$3-$4"; #update sender and receiver hashes $sender{$sp} = $rp; $receiver{$rp} = $sp; print "enter $sender{$sp}->$receiver{$rp} in dependency hashes\n"; } elsif($line =~ m/(\d)-(\d)/) { #create local process var my $p = "$1-$2"; #queue process on @p_s multi-dimensional array unshift (@{$p_s[$1]},$p); print "unshift $p_s[$1][0] onto process array\n"; $numevents++; } else { print "\nunmatched line: $line \n"; chomp($line); #remove empty newlines in input file } } print "\ncompleted $ARGV[0] parsing\n"; close FILE; check_data(); #schedule process events according to Lamport's algorithm while($timestamp <= $numevents) { print "\ntimestamp: $timestamp, numevents: $numevents\n"; foreach $pid (@p_s) { my $p_e = 0, $p_t = 0; #for every process pop the first event and examine it if($p_e = pop @{$p_s[$pid]}) { #if process-event has receiver-dependency then push it back on the stack if($receiver{$p_e}) { push (@{$p_s[$pid]},$p_e); } else { my $s_o = 0; #else if process-event has sender-obligation then update sender and reciever hashes if($s_o = $sender{$p_e}) { delete $sender{$p_e}; delete $receiver{$s_o}; } #and then enqueue process-event with process-timestamp in schedule hash if($p_e =~ m/(\d)-(\d)/) { $p_t = "$timestamp.$1" } else { print "\nerror parsing processor-event signature\n"; } $schedule{$p_e} = $p_t; unshift (@totalorder, $p_t); } } } $timestamp++; } check_data(); #create "totalorder" copy of schedule hash #pop totalorder as stack and print #sort and print schedule hash #end MAIN routine #begin subroutine definitions sub check_data { #print "numprocs = $numprocs\n"; print "\ntimestamp = $timestamp\n"; print "numevents = $numevents\n"; print "\ncontents of process stack:\n"; foreach my $r (@p_s) { my $j=0; foreach my $c (@{$r}) { print "P$i j: $j Value: $c\n"; $j++; } $i++; print "\n"; } print "\nsender key/value pairs:\n"; foreach my $k (sort keys %sender) { print "$k => $sender{$k}\n"; } print "\nreceiver key/value pairs:\n"; foreach my $k (sort keys %receiver) { print "$k => $receiver{$k}\n"; } print "\nschedule key/value pairs:\n"; foreach my $k (sort keys %schedule) { print "$k => $schedule{$k}\n"; } print "\ncontents of totalorder queue:\n"; foreach my $r (@totalorder) { print "$r, "; } print "\n\n"; }