|
@@ -71,22 +71,20 @@ |
|
|
|
|
|
final long length; |
|
|
final int mask; |
|
|
final Thread owner; |
|
|
final MemoryScope scope; |
|
|
|
|
|
@ForceInline |
|
|
AbstractMemorySegmentImpl(long length, int mask, Thread owner, MemoryScope scope) { |
|
|
AbstractMemorySegmentImpl(long length, int mask, MemoryScope scope) { |
|
|
this.length = length; |
|
|
this.mask = mask; |
|
|
this.owner = owner; |
|
|
this.scope = scope; |
|
|
} |
|
|
|
|
|
abstract long min(); |
|
|
|
|
|
abstract Object base(); |
|
|
|
|
|
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope); |
|
|
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope); |
|
|
|
|
|
abstract ByteBuffer makeByteBuffer(); |
|
|
|
|
@@ -103,7 +101,7 @@ public AbstractMemorySegmentImpl asSlice(long offset, long newSize) { |
|
|
} |
|
|
|
|
|
private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) { |
|
|
return dup(offset, newSize, mask, owner, scope); |
|
|
return dup(offset, newSize, mask, scope); |
|
|
} |
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
@@ -155,12 +153,12 @@ public final long byteSize() { |
|
|
|
|
|
@Override |
|
|
public final boolean isAlive() { |
|
|
return scope.isAliveThreadSafe(); |
|
|
return scope.isAlive(); |
|
|
} |
|
|
|
|
|
@Override |
|
|
public Thread ownerThread() { |
|
|
return owner; |
|
|
return scope.ownerThread(); |
|
|
} |
|
|
|
|
|
@Override |
|
@@ -169,7 +167,7 @@ public AbstractMemorySegmentImpl withAccessModes(int accessModes) { |
|
|
if ((~accessModes() & accessModes) != 0) { |
|
|
throw new UnsupportedOperationException("Cannot acquire more access modes"); |
|
|
} |
|
|
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, owner, scope); |
|
|
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, scope); |
|
|
} |
|
|
|
|
|
@Override |
|
@@ -187,15 +185,14 @@ private void checkAccessModes(int accessModes) { |
|
|
@Override |
|
|
public MemorySegment withOwnerThread(Thread newOwner) { |
|
|
Objects.requireNonNull(newOwner); |
|
|
checkValidState(); |
|
|
if (!isSet(HANDOFF)) { |
|
|
throw unsupportedAccessMode(HANDOFF); |
|
|
} |
|
|
if (owner == newOwner) { |
|
|
if (scope.ownerThread() == newOwner) { |
|
|
throw new IllegalArgumentException("Segment already owned by thread: " + newOwner); |
|
|
} else { |
|
|
try { |
|
|
return dup(0L, length, mask, newOwner, scope.dup()); |
|
|
return dup(0L, length, mask, scope.dup(newOwner)); |
|
|
} finally { |
|
|
//flush read/writes to segment memory before returning the new segment |
|
|
VarHandle.fullFence(); |
|
@@ -208,7 +205,6 @@ public final void close() { |
|
|
if (!isSet(CLOSE)) { |
|
|
throw unsupportedAccessMode(CLOSE); |
|
|
} |
|
|
checkValidState(); |
|
|
closeNoCheck(); |
|
|
} |
|
|
|
|
@@ -220,7 +216,7 @@ final AbstractMemorySegmentImpl acquire() { |
|
|
if (Thread.currentThread() != ownerThread() && !isSet(ACQUIRE)) { |
|
|
throw unsupportedAccessMode(ACQUIRE); |
|
|
} |
|
|
return dup(0, length, mask, Thread.currentThread(), scope.acquire()); |
|
|
return dup(0, length, mask, scope.acquire()); |
|
|
} |
|
|
|
|
|
@Override |
|
@@ -237,7 +233,7 @@ boolean isSmall() { |
|
|
} |
|
|
|
|
|
void checkRange(long offset, long length, boolean writeAccess) { |
|
|
checkValidState(); |
|
|
scope.checkValidState(); |
|
|
if (writeAccess && !isSet(WRITE)) { |
|
|
throw unsupportedAccessMode(WRITE); |
|
|
} else if (!writeAccess && !isSet(READ)) { |
|
@@ -248,10 +244,7 @@ void checkRange(long offset, long length, boolean writeAccess) { |
|
|
|
|
|
@Override |
|
|
public final void checkValidState() { |
|
|
if (owner != null && owner != Thread.currentThread()) { |
|
|
throw new IllegalStateException("Attempt to access segment outside owning thread"); |
|
|
} |
|
|
scope.checkAliveConfined(); |
|
|
scope.checkValidState(); |
|
|
} |
|
|
|
|
|
// Helper methods |
|
@@ -425,29 +418,28 @@ public static AbstractMemorySegmentImpl ofBuffer(ByteBuffer bb) { |
|
|
AbstractMemorySegmentImpl bufferSegment = (AbstractMemorySegmentImpl)nioAccess.bufferSegment(bb); |
|
|
final MemoryScope bufferScope; |
|
|
int modes; |
|
|
final Thread owner; |
|
|
if (bufferSegment != null) { |
|
|
bufferScope = bufferSegment.scope; |
|
|
modes = bufferSegment.mask; |
|
|
owner = bufferSegment.owner; |
|
|
} else { |
|
|
bufferScope = MemoryScope.create(bb, null); |
|
|
modes = defaultAccessModes(size); |
|
|
owner = Thread.currentThread(); |
|
|
} |
|
|
if (bb.isReadOnly()) { |
|
|
modes &= ~WRITE; |
|
|
} |
|
|
if (base != null) { |
|
|
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, owner, bufferScope); |
|
|
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, bufferScope); |
|
|
} else if (unmapper == null) { |
|
|
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, owner, bufferScope); |
|
|
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, bufferScope); |
|
|
} else { |
|
|
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, owner, bufferScope); |
|
|
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, bufferScope); |
|
|
} |
|
|
} |
|
|
|
|
|
public static AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl(0, 0, null, MemoryScope.GLOBAL) { |
|
|
public static AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl( |
|
|
0, 0, MemoryScope.createUnchecked(null, null, null) |
|
|
) { |
|
|
@Override |
|
|
ByteBuffer makeByteBuffer() { |
|
|
throw new UnsupportedOperationException(); |
|
@@ -464,7 +456,7 @@ Object base() { |
|
|
} |
|
|
|
|
|
@Override |
|
|
AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) { |
|
|
AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) { |
|
|
throw new UnsupportedOperationException(); |
|
|
} |
|
|
}; |
|
|