From 299cd8341c8012c6c94adccb29dd71f7e0f048e5 Mon Sep 17 00:00:00 2001 From: leventov Date: Sun, 31 Jan 2016 21:16:42 +0700 Subject: [PATCH] HCOLL-397 msync before pointing to newly created tier bulk in the header --- pom.xml | 12 ++++ .../chronicle/hash/impl/PosixMsync.java | 42 ++++++++++++ .../hash/impl/VanillaChronicleHash.java | 68 +++++++++++++++---- .../chronicle/hash/impl/WindowsMsync.java | 61 +++++++++++++++++ 4 files changed, 170 insertions(+), 13 deletions(-) create mode 100644 src/main/java/net/openhft/chronicle/hash/impl/PosixMsync.java create mode 100644 src/main/java/net/openhft/chronicle/hash/impl/WindowsMsync.java diff --git a/pom.xml b/pom.xml index b48b84f0a..5794ef006 100755 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,18 @@ 1.1.6 + + net.java.dev.jna + jna + 4.2.1 + + + + net.java.dev.jna + jna-platform + 4.2.1 + + diff --git a/src/main/java/net/openhft/chronicle/hash/impl/PosixMsync.java b/src/main/java/net/openhft/chronicle/hash/impl/PosixMsync.java new file mode 100644 index 000000000..e36013ae0 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/hash/impl/PosixMsync.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 higherfrequencytrading.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package net.openhft.chronicle.hash.impl; + +import com.sun.jna.Native; +import com.sun.jna.Platform; + +import java.io.IOException; + +final class PosixMsync { + + private static final int MS_SYNC = 4; + + public static void msync(long addr, long length) throws IOException { + if (msync(addr, length, MS_SYNC) == -1) + throw new IOException(strerror_r(Native.getLastError(), null, 0)); + } + + private static native String strerror_r(int errnum, char[] buf, int buflen); + + private static native int msync(long addr, long length, int flags); + + static { + Native.register(PosixMsync.class, Platform.C_LIBRARY_NAME); + } + + private PosixMsync() {} +} diff --git a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java index d7b096546..65d47a13c 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java @@ -731,10 +731,24 @@ public abstract class VanillaChronicleHash. + */ + +package net.openhft.chronicle.hash.impl; + +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32Util; + +import java.io.IOException; +import java.io.RandomAccessFile; + +import static com.sun.jna.platform.win32.WinError.ERROR_LOCK_VIOLATION; + +final class WindowsMsync { + + public static void msync(RandomAccessFile raf, long addr, long length) + throws IOException { + int retry = 0; + boolean success; + int lastError = 0; + // FlushViewOfFile can fail with ERROR_LOCK_VIOLATION if the memory system is writing dirty + // pages to disk. As there is no way to synchronize the flushing then we retry a limited + // number of times. + do { + if ((success = FlushViewOfFile(addr, length)) || + (lastError = GetLastError()) != ERROR_LOCK_VIOLATION) + break; + retry++; + } while (retry < 3); + + if (success) { + // Finally calls FlushFileBuffers + raf.getChannel().force(false); + } else { + throw new IOException(Kernel32Util.formatMessage(lastError)); + } + } + + private static native boolean FlushViewOfFile(long addr, long length); + + private static native int GetLastError(); + + static { + Native.register(WindowsMsync.class, "kernel32"); + } + + private WindowsMsync() {} +}