… | |
… | |
7 | use Errno (); |
7 | use Errno (); |
8 | use Time::HiRes; |
8 | use Time::HiRes; |
9 | use Fcntl; |
9 | use Fcntl; |
10 | use IO::AIO; |
10 | use IO::AIO; |
11 | |
11 | |
|
|
12 | # find all potential exit paths, this is slow, so this info is cached |
12 | sub find_exits { |
13 | sub find_exits { |
13 | my ($map) = @_; |
14 | my ($map) = @_; |
14 | |
15 | |
15 | my %exit; |
16 | my %exit; |
16 | |
17 | |
… | |
… | |
29 | } |
30 | } |
30 | |
31 | |
31 | [keys %exit] |
32 | [keys %exit] |
32 | } |
33 | } |
33 | |
34 | |
34 | my %MAP_EXITS; |
35 | my @PREFETCH; |
35 | my %MAP_TIMEOUT; |
36 | my %MAP_TIMEOUT; |
36 | |
37 | |
37 | sub on_mapenter { |
38 | sub prefetch; |
38 | my ($ob) = @_; |
39 | sub prefetch { |
|
|
40 | while (my $path = shift @PREFETCH) { |
|
|
41 | my $NOW = Time::HiRes::time; |
39 | |
42 | |
40 | my $exit = $MAP_EXITS{$ob->map->path} ||= find_exits $ob->map; |
43 | next if $MAP_TIMEOUT{$path} > $NOW; |
41 | |
44 | |
42 | my $NOW = Time::HiRes::time; |
45 | $MAP_TIMEOUT{$path} = $NOW + 60 + rand 60; |
43 | |
|
|
44 | for my $path (@$exit) { |
|
|
45 | next if $MAP_TIMEOUT{$path} > $NOW; |
|
|
46 | |
46 | |
47 | if (my $map = cf::map::has_been_loaded $path) { |
47 | if (my $map = cf::map::has_been_loaded $path) { |
48 | next if $map->in_memory == cf::MAP_IN_MEMORY; |
48 | next if $map->in_memory == cf::MAP_IN_MEMORY; |
49 | |
49 | |
50 | $path = $map->tmppath if $map->in_memory == cf::MAP_SWAPPED; |
50 | $path = $map->tmppath if $map->in_memory == cf::MAP_SWAPPED; |
51 | } |
51 | } |
52 | |
52 | |
53 | $MAP_TIMEOUT{$path} = $NOW + 60 + rand 60; |
|
|
54 | |
|
|
55 | aio_open $path, O_RDONLY, 0, sub { |
53 | aio_open $path, O_RDONLY, 0, sub { |
56 | my ($fh) = @_ |
54 | my $fh = shift |
57 | or return; |
55 | or return; |
58 | aio_readahead $fh, 0, -s $fh, sub { |
56 | aio_readahead $fh, 0, -s $fh, sub { |
59 | my $stop = Time::HiRes::time; |
57 | my $time = Time::HiRes::time - $NOW; |
60 | warn "$path ", $stop-$NOW; |
58 | warn "LONG PREFETCH $path $time\n" if $time > 0.3; |
|
|
59 | |
|
|
60 | prefetch; |
61 | }; |
61 | }; |
62 | }; |
62 | }; |
|
|
63 | |
|
|
64 | last; |
63 | } |
65 | } |
|
|
66 | } |
|
|
67 | |
|
|
68 | my %MAP_EXITS; |
|
|
69 | |
|
|
70 | sub on_mapenter { |
|
|
71 | my ($ob) = @_; |
|
|
72 | |
|
|
73 | my $exit = $MAP_EXITS{$ob->map->path} ||= find_exits $ob->map; |
|
|
74 | |
|
|
75 | push @PREFETCH, @$exit; |
|
|
76 | prefetch; |
64 | } |
77 | } |
65 | |
78 | |
66 | sub on_clock { |
79 | sub on_clock { |
67 | # boy how I hate polling |
80 | # boy how I hate polling |
68 | IO::AIO::poll_cb; |
81 | IO::AIO::poll_cb; |