commit 910bb7eebc6a092c7e681e8b3febd4104af54836
parent 677fc0e8253ffffa12ccc7082c5d915c6b0fb079
Author: Kyle Milz <kyle@windows.krwm.net>
Date: Mon, 9 Jan 2017 22:16:35 -0800
t: add win32 memory map file support
Diffstat:
3 files changed, 100 insertions(+), 18 deletions(-)
diff --git a/t/mem_unix.pm b/t/mem_unix.pm
@@ -0,0 +1,23 @@
+package t::shm;
+
+use strict;
+use warnings;
+
+use POSIX;
+use Sys::Mmap;
+use autodie;
+
+our $page_mask = POSIX::sysconf(POSIX::_SC_PAGESIZE) - 1;
+
+sub get_mem {
+ my ($self, $procfile) = @_;
+
+ open( FH, "<", $procfile );
+
+ mmap( $self->{mem}, 0, PROT_READ, MAP_SHARED, FH ) or die "mmap: $!";
+ $self->{size} = length $self->{mem};
+
+ close FH;
+}
+
+1;
diff --git a/t/mem_win32.pm b/t/mem_win32.pm
@@ -0,0 +1,71 @@
+package t::shm;
+
+use strict;
+use warnings;
+
+use POSIX; # NULL
+use Win32::API;
+use autodie;
+
+our $page_mask = 64 * 1024 - 1;
+
+use constant GENERIC_READ => 0x80000000;
+use constant OPEN_EXISTING => 3;
+use constant INVALID_HANDLE_VALUE => -1;
+use constant PAGE_READONLY => 0x02;
+use constant FILE_MAP_READ => 0x0004;
+
+sub get_mem {
+ my ($self, $procfile) = @_;
+
+ # Roll our own Perl entry points into windows functions... wtf..
+ my $CreateFile = Win32::API::More->new(
+ 'kernel32', 'HANDLE WINAPI CreateFile(
+ LPCTSTR path,
+ DWORD a,
+ DWORD b,
+ LPSECURITY_ATTRIBUTES c,
+ DWORD d,
+ DWORD e,
+ HANDLE f)'
+ );
+ my $GetFileSize = Win32::API::More->new(
+ 'kernel32', 'HANDLE WINAPI GetFileSize(
+ HANDLE hFile,
+ LPWORD lpFileSizeHigh)'
+ );
+ my $CreateFileMapping = Win32::API::More->new(
+ 'kernel32', 'HANDLE WINAPI CreateFileMapping(
+ HANDLE h,
+ LPSECURITY_ATTRIBUTES lpAttr,
+ DWORD prot,
+ DWORD max_hi,
+ DWORD max_lo,
+ LPCTSTR lp)'
+ );
+ my $MapViewOfFile = Win32::API::More->new(
+ 'kernel32', 'UINT_PTR WINAPI MapViewOfFile(
+ HANDLE h,
+ DWORD acc,
+ DWORD off_hi,
+ DWORD off_lo,
+ SIZE_T len)'
+ );
+
+ my $handle = $CreateFile->Call($procfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+ die "CreateFile" if ($handle == INVALID_HANDLE_VALUE);
+
+ my $size = $GetFileSize->Call($handle, NULL);
+ #die "GetFileSize" if ($size == INVALID_FILE_SIZE);
+
+ my $fm = $CreateFileMapping->Call($handle, NULL, PAGE_READONLY, 0, 0, NULL);
+ die "CreateFileMapping" if ($fm == NULL);
+
+ my $mem = $MapViewOfFile->Call($fm, FILE_MAP_READ, 0, 0, $size);
+ die "MapViewOfFile" unless (defined $mem);
+
+ $self->{mem} = unpack "P$size", pack 'Q', $mem;
+ $self->{size} = $size;
+}
+
+1;
diff --git a/t/shm.pm b/t/shm.pm
@@ -1,26 +1,21 @@
package t::shm;
+
use strict;
use warnings;
+
use Inline 'C';
use POSIX;
-use Sys::Mmap;
+use if $^O eq 'MSWin32', 't::mem_win32';
+use if $^O ne 'MSWin32', 't::mem_unix';
use autodie;
-
sub new {
my ($class, $procfile) = @_;
my $self = {};
bless($self, $class);
- $self->{mem} = '';
- open(FH, "<", $procfile);
- if ($^O ne "MSWin32") {
- mmap($self->{mem}, 0, PROT_READ, MAP_SHARED, FH) or die "mmap: $!";
- }
- close FH;
-
- $self->{size} = length $self->{mem};
+ get_mem( $self, $procfile );
# These functions proved by C code at the end of this file.
my $header_size = citrun_header_size();
@@ -64,14 +59,7 @@ sub new {
sub get_aligned_size {
my ($unaligned_size) = @_;
- my $page_mask;
- if ($^O eq "MSWin32") {
- $page_mask = 64 * 1024 - 1;
- } else {
- $page_mask = POSIX::sysconf(POSIX::_SC_PAGESIZE) - 1;
- }
-
- return ($unaligned_size + $page_mask) & ~$page_mask;
+ return ($unaligned_size + $t::shm::page_mask) & ~$t::shm::page_mask;
}
sub get_buffers {