Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bytes/issues/612 #614

Merged
merged 9 commits into from
Mar 21, 2024
38 changes: 26 additions & 12 deletions src/main/java/net/openhft/chronicle/bytes/MappedBytesStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -438,23 +438,30 @@ public long appendUtf8(@NonNegative long pos, char[] chars, @NonNegative int off
@Override
protected void performRelease() {
if (address != 0 && syncMode != SyncMode.NONE && OS.isLinux()) {
performMsync(0, safeLimit - start);
performMsync(0, safeLimit - start, this.syncMode());
}
// must sync before releasing
super.performRelease();
}

private void performMsync(@NonNegative long offset, long length) {
final SyncMode syncMode = this.syncMode();
/**
* Sync the ByteStore if required.
*
* @param offset the offset within the ByteStore from the start to sync, offset must be a multiple of 4K
* @param length the length to sync, length must be a multiple of 4K
* @param syncMode the mode to sync
*/
private void performMsync(@NonNegative long offset, long length, SyncMode syncMode) {
if (syncMode == SyncMode.NONE)
return;
long start0 = System.currentTimeMillis();
boolean full = offset == 0;
int ret = PosixAPI.posix().msync(address + offset, length, syncMode.mSyncFlag());
if (ret != 0)
Jvm.error().on(MappedBytesStore.class, "msync failed, " + PosixAPI.posix().lastErrorStr() + ", ret=" + ret + " " + mappedFile.file() + " " + Long.toHexString(offset) + " " + Long.toHexString(length));
long time0 = System.currentTimeMillis() - start0;
if (time0 >= 200)
Jvm.perf().on(getClass(), "Took " + time0 / 1e3 + " seconds to " + syncMode + " " + mappedFile.file());
Jvm.perf().on(getClass(), "Took " + time0 + " ms to " + syncMode + " " + mappedFile.file() + (full ? " (full)" : ""));
}

/**
Expand All @@ -479,19 +486,26 @@ public void syncMode(SyncMode syncMode) {
* @param position to sync with the syncMode()
*/
public void syncUpTo(long position) {
if (syncMode == SyncMode.NONE || address == 0 || refCount() <= 0)
syncUpTo(position, this.syncMode);
}

/**
* Synchronise from the last complete page up to this position.
*
* @param position to sync with the syncMode()
* @param syncMode to use
*/
public void syncUpTo(long position, SyncMode syncMode) {
if (syncMode == SyncMode.NONE || address == 0 || refCount() <= 0 || !OS.isLinux())
return;
long length = position - start;
if (length <= syncLength)
long positionFromStart = Math.min(safeLimit, position) - start;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @peter-lawrey if you have time it would be good to get a new test around this (unless its covered already)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, more tests needed.

if (positionFromStart <= syncLength)
return;
final long maxLength = safeLimit - start;
if (length > maxLength)
length = maxLength;
int mask = ~0xFFF;
long pageEnd = (length + 0xFFF) & mask;
long pageEnd = (positionFromStart + 0xFFF) & mask;
long syncStart = syncLength & mask;
final long length2 = pageEnd - syncStart;
performMsync(syncStart, length2);
performMsync(syncStart, length2, syncMode);
syncLength = position;
}
}