summaryrefslogtreecommitdiff
path: root/tools/multigcc.pl
blob: fbe7c17aae6cf2367afaaa03649bcb26bc56b241 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/perl
use List::Util 'shuffle'; # standard from Perl 5.8 and later

my $tempfile = "multigcc.out";
my @params;
my @files;
my $list = \@params;

# parse command line arguments
for my $a (@ARGV) {
    if ($a eq "--") {
        $list = \@files;
        next;
    }

    push @{$list}, $a;
}

exit if (not @files);

my $command = join " ", @params;

# shuffle the file list to spread the load as evenly as we can
@files = shuffle(@files);  

# count number of cores
my $cores = 1;
if (open CPUINFO, "</proc/cpuinfo") {
    $cores = scalar grep /^processor/i, <CPUINFO>;
    close CPUINFO;
}

# don't run empty children
if (scalar @files <= $cores)
{
    $cores = 1;
}

# fork children
my @pids;
my $slice = int((scalar @files + $cores) / $cores);
for my $i (0 .. $cores-1)
{
    my $pid = fork;
    if ($pid)
    {
        # mother
        $pids[$i] = $pid;
    }
    else
    {
        # get my slice of the files
        my @list = @files[$i * $slice .. $i * $slice + $slice - 1];

        # run command
        system("$command @list > $tempfile.$$");

        exit;
    }
}

for my $i (0 .. $cores - 1)
{
    # wait for child to complete
    waitpid $pids[$i], 0;

    # read & print result
    if (open F, "<$tempfile.$pids[$i]")
    {
        print <F>;
        close F;
        unlink "$tempfile.$pids[$i]";
    }
}