#!/usr/bin/perl use strict; use warnings; sub Log; die "Usage: $0 \n" unless @ARGV == 1; my $logfile = shift; # Pass #1 : gather line numbers to be deleted. my %locks; # Hash of currently open locks. my @unlock_lines; # lines to rid ourselves of open(LOGFILE,$logfile) or die "Can't read $logfile - $!\n"; while () { Log 2, "Analysing line $."; next unless /Mutex\((.*?)\)::(\w+)/; my ($address,$action) = ($1,$2); if ($action eq 'locking') { Log 2, "Address $address locked at line $."; if (defined $locks{$address}) { Log 0, "ERROR: Address $address locked at line $., but already locked at line $locks{$address}."; } $locks{$address} = $.; } if ($action eq 'unlocked') { Log 2, "Address $address unlocked at line $."; unless (defined $locks{$address}) { Log 0, "ERROR: Address $address not locked, but unlocked at line $.."; } else { push @unlock_lines, $., delete $locks{$address}; } } } close LOGFILE; # Sort the lines numbers that we've accumulated because we put them in # unordered. This allows us to make just one more pass through the file # to remove the lines. @unlock_lines = sort { $a <=> $b } @unlock_lines; # Pass #2: output all but the lines we're not interested in. my $rmline = shift @unlock_lines; open(LOGFILE,$logfile) or die "Can't read $logfile - $!\n"; while () { if (defined $rmline && $. == $rmline) { $rmline = shift @unlock_lines; next; } print; } close LOGFILE;