Hello Eyal, Are you looking for a pure Perl way of getting aligned memory, or an XS approach?
One really hackish, pure Perl way to do what you want is to allocate more memory than you need---more by a page size---then give an address within $buffer that aligns to your memory page size, which is probably 64 bytes. This is far from ideal, but it would work. How then would you read or modify the contents from Perl? You'd have to use substr. (I looked for a way to utilize Perl's internal sv_chop C method, but that only appears to work on very short strings, as documented here: https://perldoc.perl.org/perlguts.html#Offsets). use strict; use warnings; use Devel::Peek; my $BUFFER_SIZE = 128; my $PAGE_SIZE = 64; # Initial memory allocation my $buffer = "\0" x ($BUFFER_SIZE + $PAGE_SIZE - 1); print "=== Initial PV has COW flag set:\n"; Dump($buffer); # Must modify to remove COW flag $buffer .= ''; print "=== After appending empty string, we have\n"; Dump($buffer); # Find offset to use, which is also needed for substr operations my $c_address = unpack('Q', pack('P', $buffer)); my $bytes_into_page = $c_address % $PAGE_SIZE; my $offset = $PAGE_SIZE - $bytes_into_page; printf "=== address is 0x%x, which is %d into a page; use offset of %d\n", $c_address, $bytes_into_page, $offset; # Modify the contents using substr substr($buffer, $offset, 5) = 'a' x 5; print "=== After substr, dump gives === \n"; Dump($buffer); -- David On Thu, Oct 18, 2018 at 11:39 AM Eyal BenDavid <bde...@gmail.com> wrote: > Hi all, > > A driver exposes its API by ioctl interface. > > The argument for the ioctl call is a memory buffer that its address > must aligned to OS page size. > > For example the allocation in C would call valloc (or posix_memalign) > > Simple Perl allocation of the buffer like this: > > $buffer = "\0" x BUFFER_SIZE ; > > is not enough since most probably the starting address of the scalar > wont be aligned to OS page size. > > Is there a simple way to achieve this? > > Note: I convert the buffer to the C address like this: > > my $c_address = unpack('Q', pack('P', $buffer)); > > Thanks! > Eyal > -- "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." -- Brian Kernighan