System.currentTimeMillis() is totally wrong after call JNA mlockall

黄文辉 huanghwh at yahoo.com
Sun Jun 2 02:33:17 UTC 2013


Hi,
I recently found that Cassandra 1.2.4 could not shutdown when enable JNA,
so I try to solve it, and found that under OpenJDK6/FreeBSD, 
System.currentTimeMillis() is totally wrong after call JNA mlockall,
time seams to not change anymore.

The sample code list here:

import java.util.Date;

import com.sun.jna.LastErrorException;
import com.sun.jna.Native;

public class Test_mlockall2 {

  static boolean run = true;
  private static final int MCL_CURRENT = 1;
  private static final int MCL_FUTURE = 2;

  static {    
    try
    {
      Native.register("c");
    }
    catch (NoClassDefFoundError e)
    {
      System.err.println("JNA not found. Native methods will be disabled.");
    }
    catch (UnsatisfiedLinkError e)
    {
      System.err.println("JNA link failure, one or more native method will be unavailable.");
      System.err.println("JNA link failure details: " + e.getMessage());
    }
    catch (NoSuchMethodError e)
    {
      System.err.println("Obsolete version of JNA present; unable to register C library. Upgrade to JNA 3.2.7 or later");
    }

  }

  private static native int mlockall(int flags) throws LastErrorException;

  public static void tryMlockall()
  {
    try
    {
      mlockall(MCL_CURRENT);
      System.err.println("JNA mlockall successful");
    }
    catch (UnsatisfiedLinkError e)
    {
      // this will have already been logged by CLibrary, no need to repeat it
    }
    catch (RuntimeException e)
    {
      if (!(e instanceof LastErrorException))
        throw e;
      System.err.println("Unknown mlockall error " + e);

    }
  }

  public static void main(String[] args) throws Exception {
    tryMlockall();
    while(run){
      long prev_time = System.currentTimeMillis();
      System.out.println("prev_time="+new Date(prev_time));
      try {
        Thread.sleep(1000);
        System.out.println("Sleep 1 second.");
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
      long now = System.currentTimeMillis();
      System.out.println("now time"+new Date(now));
      System.out.printf("%d, %d, diff=%d\n", prev_time, now, now-prev_time);
      if(now-prev_time>=1000){
        System.out.println("Hi.");
      }
    }
    System.err.println("thr1 quit!");
  }
}


The sample program output:

JNA mlockall successful
prev_time=Sat Jun 01 21:12:22 CST 2013
Sleep 1 second.
now timeSat Jun 01 21:12:22 CST 2013
1370092342096, 1370092342347, diff=251
prev_time=Sat Jun 01 21:12:22 CST 2013
Sleep 1 second.
now timeSat Jun 01 21:12:22 CST 2013
1370092342382, 1370092342386, diff=4
prev_time=Sat Jun 01 21:12:22 CST 2013
Sleep 1 second.
now timeSat Jun 01 21:12:22 CST 2013
1370092342390, 1370092342397, diff=7
prev_time=Sat Jun 01 21:12:22 CST 2013
Sleep 1 second.
now timeSat Jun 01 21:12:22 CST 2013
1370092342397, 1370092342401, diff=4
prev_time=Sat Jun 01 21:12:22 CST 2013


you need user root to run it or 
sysctl security.bsd.unprivileged_mlock=1

Any ideas how to solve it?

Cheers,
Huang Wen Hui



More information about the freebsd-java mailing list