Accessing foreign memory that already exists
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Mar 31 10:36:31 UTC 2020
Hi Antoine,
this is an interesting use case, and one I've been thinking quite a bit
recently, as it comes up with native interop (see below).
In general there are two categories of memory addresses: checked ones
(the ones with a known segment attached to them) and unchecked ones (the
ones with no segment attached to them, or the ones that have the special
Nothing segment attached to them).
Our policy is that addresses that are not backed by a segment _cannot_
be de-referenced. This is how we've been achieving safety for the basic
foreign memory access use case that doesn't do native interop. (we're
discussing as to whether that's the right default, based on some library
porting activity we've been doing recently - but there doesn't seem
clear evidence pointing one way or another).
But there are cases where you might want to take an existing address,
which is backed by no existing segment, and attach a segment to it -
which will make it fully functional again - this operation is called
'rebasing an address':
https://github.com/openjdk/panama-foreign/blob/foreign-abi/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java#L83
So, with all this in mind, the goal to do what you want is to be able to
(unsafely!) create a memory segment which has roughly the
characteristics you need - e.g. given base address and given size. The
native interop branch has a useful method for making these unchecked
segments:
https://github.com/openjdk/panama-foreign/blob/foreign-abi/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Foreign.java#L100
In other words, let's say you have a long address "addr" and that you
want to create a segment around it:
1) create a memory address out of "addr"
var base = MemoryAddress.ofLong(addr)
2) create an unchecked segment with right base address and size
var segment = Foreign.ofNativeUnchecked(base, size)
And voila, you now have a segment for your non-Java generated address.
Few notes:
* since the address has been generated by you, when you close this
segment, the memory access API won't attempt to do anything fancy here
(but it will make all the addresses based on that segment invalid);
options we have discussed here is to add ways to attach custom 'cleanup'
functions - I'm a bit skeptical of those, but I can be convinced given
the right use cases
* the segment will be confined on the calling thread - meaning that it
can only be accessed and closed by that thread (as a regular segment)
I think here we can do things to allow more flexibility - in principle
there's some kind of 'unsafe native segment builder' lurking in here
which lets you specify:
* whether to confine to a thread or not
* what the size of the segment is
* what is the base address of the segment
* whether the resulting segment is closeable (and, if so, if a custom
close() action should be provided)
My sense is that clients typically will _not_ need all this flexibility.
For instance, in the native interop case there are only two cases which
seem overwhelmingly common:
* I have an unchecked address and I want to give it a size - but I don't
want closeability, or confinement - just let me dereference it within
some known bounds
* I have an unchecked address which I know comes from some 'malloc'
call, and I want to attach it a full blown segment, and I want the
segment::close operation to call free()
I guess time will tell whether we need N ad-hoc unsafe factories, or a
more flexible builder-based solution.
At this point I'd be very interested on what your requirements would be
for the segment you create with this unsafe API. My educated guess would
be that:
* you'd like this segment to have a known size
* you'd like this segment to be closeable, and, upon close() some
well-known native function in your allocator should be invoked
* you'd probably like this segment not to be confined
Is my guess correct?
Cheers
Maurizio
On 31/03/2020 09:06, Antoine Chambille wrote:
> Hi everyone,
>
> At ActiveViam we are watching the foreign memory project with eager
> anticipation. Thank you for the hard work, looking forward to it!
>
> One question related to our usage of off-heap memory:
>
> If some native memory already exists, what is the preferred way to expose
> it as a memory segment?
>
>
> Some details about our use case: we make an in-memory database that
> delivers interactive queries to many users on terabyte datasets. The
> database structures are allocated off-heap, but not with malloc which is a
> bottleneck. We developed a highly concurrent, NUMA-Aware SLAB allocator.
> This custom memory manager is written almost entirely in Java with just a
> few system calls (anonymous mmap, munmap, madvise).
>
> Cheers,
> -Antoine
More information about the panama-dev
mailing list