CALL GLOP()

Andy Malakov software blog

Monday, December 5, 2011

Monday, October 11, 2010

ShouldNotReachHere

#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (classFileParser.cpp:3161), pid=3136, tid=4676
# Error: ShouldNotReachHere()
#

Sunday, October 3, 2010

My first Android app





I created my first Android app. It converts a date in Gregorian Calendar into Maya "Long Count" calendar. Contrary to popular view Mayan calendar doesn't end on December 21st, 2012. You can test this in my app :-).

Sources can be found here.

Sunday, June 6, 2010

Alternative to Thread.sleep()

Follow-up to my previous post. Here is an alternative to Thread.sleep() that uses spin-yield:

private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); //TODO: Determine for current machine

public static void sleepNanos (long nanoDuration) throws InterruptedException {
final long end = System.nanoTime() + nanoDuration;


long timeLeft = nanoDuration;
do {
if (timeLeft > SLEEP_PRECISION)
Thread.sleep (
1);
else

Thread.sleep (
0); // Thread.yield();
timeLeft = end - System.nanoTime();

if (Thread.interrupted())
throw new InterruptedException ();

}
while (timeLeft > 0);

}



Test


I run 4 threads requesting 5 millisecond sleep 1000 times each (on my Dual-Core CPU). The first chart shows sleepNanos(TimeUnit.MILLISECONDS(5).toNanos()):

Actual sleep time of sleepNanos(5000000)

The second chart shows Thread.sleep(5):

Actual sleep time of Thread.sleep(5)

As you can see, sleepNanos() is much more precise. I found that this approach was originally used by Ryan Geiss for WinAmp visualization plugin.

UPDATE



Even better precision can be achieved if you are willing to consume more CPU power doing Spin-Wait for the last part of the wait:







public static void sleepNanos (long nanoDuration) throws InterruptedException {
final long end = System.nanoTime() + nanoDuration;
long timeLeft = nanoDuration;
do {

if (timeLeft > SLEEP_PRECISION)
Thread.sleep (1);
else
if (timeLeft > SPIN_YIELD_PRECISION)

Thread.sleep(0);

timeLeft = end - System.nanoTime();

if (Thread.interrupted())
throw new InterruptedException ();

} while (timeLeft > 0);

}

Thursday, May 13, 2010

Measuring nanoseconds in Java / Windows

I was under false impression that interval timers in Java allow sub-millisecond precision on Windows. I knew that Thread.sleep(millis, nanos) internally uses milliseconds, but for some reason I thought that methods like LockSupport.parkNanos() method provide precise waits. Well, I was wrong. The smallest delay this method can realize is approximately 1.95 milliseconds on my Windows PC.



Back in 2006 David Holmes explained that Java timer intervals are based on waitForMultipleObjects() Windows API (which uses dwMilliseconds). They still are.



One simple (but not universal) workaround is a "spin-sleep":


private static void sleepNanos (long nanoDelay) {
final long end = System.nanoTime() + nanoDelay;
do {
Thread.yield(); // Thread.sleep (0);
} while (System.nanoTime() < end);
}


When running standalone this method consumes all free resources of single CPU core, but it will share with other threads that may be running. For large durations it can be enhanced to use Thread.sleep() for bulk of the waiting.



P.S. Difference between Thread.yield() and Thread.sleep( 0 ) is explained here.

Friday, December 11, 2009

Old trap

I was puzzled why one of my objects had incorrect toString()

class Foo { 
private long id;
private String name;

Foo(
long id, String name) {
this.id = id;
this.name = name;
}

public String toString () {
return id + ' ' + name;
}
}


The statement new Foo(123, "Hello") prints something like "155Hello" instead of "123 Hello". Of course the reason is pretty simple:

 
public String toString2() {
return new StringBuilder().append(id + 32L).append(name.toString()).toString();
}

Wednesday, November 11, 2009

Stack allocation in Java is still a myth

There were rumors that Mustang will have on stack allocation as a part of hot spot optimization.

Four+ years later this :


public long encode (String input) {
final byte [] buffer = new byte [8];

.. encode input into buffer

.. convert buffer into LONG

return result;
}


I was hoping JVM will allocate buffer on stack based on the fact that it does not escape from this method. Running this test 10M times with -verbosegc shows extensive GC work (1.6.0_16-b01 64 bit server JVM with -XX:+DoEscapeAnalysis option).



On the positive side. GC is very fast. Consider three functions:

  1. encodeNewBuffer () uses new byte array to encode input string.

  2. encodeSynchronizedField () uses private field, guarded by synchronized{} block

  3. encodeThreadLocalField () uses ThreadLocal cache to encode input string



Here is the code:

long encodeNewBuffer (String input) {
final byte [] buffer = new byte [8];

return f (buffer);
}

/////////////

private final byte [] buffer = new byte [8];

synchronized long encodeSynchronizedField (String input) {
return f (buffer);
}

/////////////

ThreadLocal<byte[]> threadLocal = new ThreadLocal<byte[]>();
{
threadLocal.set(new byte [8]);
}

long encodeThreadLocalField (String input) {
byte [] buffer = threadLocal.get();
return f (buffer);
}


GC-based method is a winner:


encodeNewBuffer(): 4,108 sec.
encodeSynchronizedField(): 5,322 sec.
encodeThreadLocalField() : 5,411 sec

Monday, November 9, 2009

Multi-threaded testing with JUnit. Switch to ConcJUnit .

Our JUnit tests deal with components that use multiple threads. Unfortunately JUnit has no built-in support for this kind of testing.

Lets consider a simple thread that interprets commands from input queue. In this example it can only understand "exit" command. All other inputs trigger an error.

 

abstract class MainLoop extends Thread {

private Queue<String> commands = new LinkedBlockingDeque<String>();


public void run () {
while (true) {
String command = commands.poll();
if (command.equals ("exit"))
break;

else
reportError (
"Unknown command: " + command);
}
}

public void add (String command) {
commands.add(command);

}

abstract void reportError (String error);
}

public class MyTest {

@Test
public void test() {
MainLoop thread =
new MainLoop() {

void reportError(String error) {
Assert.fail (error);
}
};
thread.start();
thread.add (
"quit"); // sic! shoudl be "exit"

}
}



If we run the above test, JUnit completely ignores failure of "Commands Interpreter" thread (Although default uncaughtExceptionHandler prints exception to standard output):


[junit] Running test.MyTest
[junit] Exception in thread "Commands Interpreter": java.lang.AssertionError: Unknown command: quit
[junit] at org.junit.Assert.fail(Assert.java:91)
[junit] at test.MyTest$1.reportError(MyTest.java:36)
[junit] at test.MainLoop.run(MyTest.java:19)
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.422 sec


As you can see JUnit detected 0 errors. JUnit has at least two problems when it comes to multi-threaded tests:

  1. JUnit only cares about errors in its own thread. It completely ignores exceptions or assertion failures in child threads.

  2. Left over child threads may produce side effect on subsequent tests. In some cases failures in child threads may happen after the main thread is finished.



We used various custom workarounds until it was clear that we need a generic solution for growing number of multi-threaded tests. Luckily we found an excellent tool - ConcJUnit (AKA ConcuTest) written by Mathias Ricken.

a) ConcJUnit is a drop-in replacement of JUnit. It includes standard JUnit classes and introduces own test runners. Just replace junit.jar by concutest.jar .

b) ConcJUnit detects both failures in child threads and leftover threads.

Switching to ConcJUnit produces expected result:


java.lang.AssertionError: Unknown command: quit
at org.junit.Assert.fail(Assert.java:91)
at test.MyTest$1.reportError(MyTest.java:36)
at test.MainLoop.run(MyTest.java:19)
at test.MainLoop.run(MyTest.java:19)


If you want to know more about ConcJUnit, read materials from introduction page. For example, the following presentation.

Thursday, November 5, 2009

GLOP

"Consider a program — any program; let us call it GLOP. We begin designing our program by imagining that we have a machine with a hardware instruction that will perform GLOP (an idea that is not beyond the realm of possibility with today's microprogrammable computers) Thus, to write program GLOP, we merely write the instruction
GLOP
and we are done! Not only are we finished, but we are relatively certain that the resulting program is correct — assuming that the hardware primitive GLOP performs correctly (and if it doesn't, we can always blame it on the vendor)."

Edward Yourdon "Techniques of program structure and design‎" 1975.

Tuesday, November 3, 2009

2:5020/236.23 :-)