package voldemort.utils; import org.apache.log4j.Logger; import com.sun.jna.LastErrorException; import com.sun.jna.Native; /** * Native functions used through JNA * */ public class JNAUtils { private static final Logger logger = Logger.getLogger(JNAUtils.class); /* Flags for mlock_all */ private static final int MCL_CURRENT = 1; private static final int MCL_FUTURE = 2; private static final int ENOMEM = 12; static { try { Native.register("c"); } catch(NoClassDefFoundError e) { logger.info("Could not locate JNA classes"); } catch(UnsatisfiedLinkError e) { logger.info("Failed to link to native library"); } catch(NoSuchMethodError e) { logger.warn("Older version of JNA. Please upgrade to 3.2.7+"); } } private static native int mlockall(int flags) throws LastErrorException; private static native int munlockall() throws LastErrorException; private static boolean isOperatingSystem(String os) { if(System.getProperty("os.name").toLowerCase().contains(os)) return true; else return false; } public static void tryMlockall() { try { if(isOperatingSystem("windows")) return; // Since we demand-zero every page of the heap while bringing up the // jvm, MCL_FUTURE is not needed mlockall(MCL_CURRENT); logger.info("mlockall() on JVM Heap successful"); } catch(Exception e) { if(!(e instanceof LastErrorException)) logger.error("Unexpected error during mlock of server heap", e); LastErrorException le = (LastErrorException) e; if(le.getErrorCode() == ENOMEM && isOperatingSystem("linux")) { logger.warn("Unable to lock JVM memory (ENOMEM)." + " This can result in part of the JVM being swapped out with higher Young gen stalls" + " Increase RLIMIT_MEMLOCK or run Voldemort as root."); } else if(!isOperatingSystem("mac")) { // fixes a OS X oddity, where it still throws an error, even // though mlockall succeeds logger.warn("Unknown mlockall error " + le.getErrorCode()); } } } public static void tryMunlockall() { try { if(isOperatingSystem("windows")) return; munlockall(); logger.info("munlockall() on JVM Heap successful"); } catch(Exception e) { if(!(e instanceof LastErrorException)) logger.error("Unexpected error during mlock of server heap", e); LastErrorException le = (LastErrorException) e; logger.warn("Error unlocking JVM heap " + le.getErrorCode()); } } }