Home » OS » Linux » O_DIRECT & O_ASYNC, Linux & Perl

O_DIRECT & O_ASYNC, Linux & Perl

I’ve written a C program that creates a 20GB file using O_DIRECT and O_ASYNC correctly. The trick to write to a file using O_DIRECT is that I have to align the buffer with respect to the memory block size.

When I write a similar program using Perl, I receive the expected “System write error: Invalid argument” as the buffer is not aligned.

So, my question is: Is it possible, in Perl, to align the buffer?

#!/usr/bin/perl

use strict;
use warnings;

$|++;

use Fcntl qw(:DEFAULT O_ASYNC O_DIRECT);

my $FH;
sysopen($FH, "./test.dat", O_WRONLY | O_TRUNC | O_CREAT | O_ASYNC | O_
+DIRECT, 0666);

my $BUFFER = "0"x1048576;
my $BUFSIZE = 1048576;

for (my $i = 0; $i < 20480; $i++) {
my $written = syswrite($FH, $BUFFER, $BUFSIZE);
die "System write error: $!\\n" unless defined $written;
}

Don’t forget Mother’s Day! It’s this Sunday so get her some sock yarn.

Update: sgifford over at Perlmonks.org, gave me the answer. Just mmap() the buffer using Sys::Mmap 🙂

#!/usr/bin/perl

use strict;
use warnings;

$|++;

use Fcntl qw(:DEFAULT O_ASYNC O_DIRECT);
use Sys::Mmap;

my $FH;
sysopen($FH, "./test.dat", O_WRONLY | O_TRUNC | O_CREAT | O_ASYNC | O_DIRECT, 0666);

my $BUFSIZE = 1048576;
my $BUFFER;

mmap($BUFFER, $BUFSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, STDOUT) or die "Couldn't mmap\\n";

for (my $i = 0; $i < 20480; $i++) {
        my $written = syswrite($FH, $BUFFER, $BUFSIZE);
        die "System write error: $!\\n" unless defined $written;
}
Share Button

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

Facebook login by WP-FB-AutoConnect