Atomicity of Reference assignment - Java

     Java's JVM specifications (http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf) claims that writes to and reads of references is atomic on both 32 bit and 64 bit implementation and i happened to have a code which enforced mutual exclusion on the destination variable,

public void set(Test ref)
{
  synchronized (this)
  {

     // obj is the member variable
     obj = ref;
  }

}

   At some point the need for synchronization was in question, as write into a reference is atomic and i started looking at underlying assembly instructions for the above code without synchronized block. I used 64 bit implementation of Open JDK 7 Update 3 on Ubuntu running on Intel x86 64 bit processor. The assembly code turned out as,

Decoding compiled method 0x00007f8c5d061110:
Code:
[Entry Point]
[Constants]
# {method} 'set' '(LTest;)V' in 'Test'
# this: rsi:rsi = 'Test'
# parm0: rdx:rdx = 'Test'
# [sp+0x20] (sp of caller)
0x00007f8c5d061240: mov 0x8(%rsi),%r10d
0x00007f8c5d061244: cmp %r10,%rax
0x00007f8c5d061247: jne 0x00007f8c5d0378a0 ; {runtime_call}
0x00007f8c5d06124d: xchg %ax,%ax
[Verified Entry Point]
0x00007f8c5d061250: push %rbp
0x00007f8c5d061251: sub $0x10,%rsp
0x00007f8c5d061255: nop ;*synchronization entry ; - Test::set@-1 (line 19)
0x00007f8c5d061256: mov %rsi,%r10
0x00007f8c5d061259: mov %rdx,%r8
0x00007f8c5d06125c: mov %r8d,0x10(%rsi)
0x00007f8c5d061260: shr $0x9,%r10
0x00007f8c5d061264: mov $0x7f8c661d7000,%r11
0x00007f8c5d06126e: mov %r12b,(%r11,%r10,1) ;*putfield obj ; - Test::set@2 (line 19)
0x00007f8c5d061272: add $0x10,%rsp
0x00007f8c5d061276: pop %rbp
0x00007f8c5d061277: test %eax,0xcc88d83(%rip) # 0x00007f8c69cea000 ; {poll_return}
0x00007f8c5d06127d: retq 
0x00007f8c5d06127e: hlt 
0x00007f8c5d06127f: hlt 

   It uses two move instructions, one (mov%rdx, %r8) to copy the input reference (param0) into a intermediate register (r8) and the other one (move %r8d, 0x10(%rsi)) to copy the 32bits of register (r8) into the destination reference.

   What happens if the CPU's context changed after the first move instruction and other thread tries to access the value of the reference (obj)? It would end up getting the old value of the reference, despite the fact that an earlier thread had started the copy process of the reference with a new value. Is this desirable and expected? Its up to the application's requirements. In my case, i wanted to ensure a first come first serve (FCFS) behavior for threads. The thread which started the copy of source reference had to complete with a successful write into the destination reference before other threads could use the value of destination reference. Hence, i had to use either a synchronized block or AtomicReference.

    The synchronized block in the Test function translates well into the assembly, and enforces mutual exclusion over the shared reference,

[Entry Point]
[Constants]
# {method} 'set' '(LTest;)V' in 'Test'
# this: rsi:rsi = 'Test'
# parm0: rdx:rdx = 'Test'

# [sp+0x40] (sp of caller)
0x00007f713905f340: mov 0x8(%rsi),%r10d
0x00007f713905f344: cmp %r10,%rax
0x00007f713905f347: jne 0x00007f71390378a0 ; {runtime_call}
0x00007f713905f34d: xchg %ax,%ax
[Verified Entry Point]
0x00007f713905f350: mov %eax,-0x6000(%rsp)
0x00007f713905f357: push %rbp
0x00007f713905f358: sub $0x30,%rsp ;*synchronization entry ; - Test::set@-1 (line 19)
0x00007f713905f35c: mov %rdx,(%rsp)
0x00007f713905f360: mov %rsi,%rbp
0x00007f713905f363: mov (%rsi),%rax
0x00007f713905f366: mov %rax,%r10
0x00007f713905f369: and $0x7,%r10
0x00007f713905f36d: cmp $0x5,%r10
0x00007f713905f371: jne 0x00007f713905f3da
0x00007f713905f373: mov $0xcc29d340,%r11d ; {oop('Test')}
0x00007f713905f379: mov 0xb0(%r11),%r10
0x00007f713905f380: mov %r10,%r11
0x00007f713905f383: or %r15,%r11
0x00007f713905f386: mov %r11,%r8
0x00007f713905f389: xor %rax,%r8
0x00007f713905f38c: test $0xffffffffffffff87,%r8
0x00007f713905f393: jne 0x00007f713905f50e ;*monitorenter ; - Test::set@3 (line 19)

0x00007f713905f399: mov (%rsp),%r10
0x00007f713905f39d: mov %r10,%r11
0x00007f713905f3a0: mov %r11d,0x10(%rbp)

0x00007f713905f3a4: mov %rbp,%r10
0x00007f713905f3a7: shr $0x9,%r10
0x00007f713905f3ab: mov $0x7f7142670000,%r11
0x00007f713905f3b5: mov %r12b,(%r11,%r10,1)
0x00007f713905f3b9: mov $0x7,%r10d
0x00007f713905f3bf: and 0x0(%rbp),%r10
0x00007f713905f3c3: cmp $0x5,%r10
0x00007f713905f3c7: jne 0x00007f713905f445 ;*monitorexit ; - Test::set@10 (line 22) 

     Bottom line, writes to and reads from reference is atomic but assignment (copy from source and write into destination) of a reference isn't atomic and when in doubt, source of truth is in assembly instructions. :-)

  

   

Java : Package specific static initialization

       I was working on a sample android application having an activity and a service, declared in the same package. The application logic didn't enforce a specific order of creation and had to perform static initialization irrespective of whichever application component was created first by android framework (which ever class was loaded by the DEX class loader of dalvik virtual machine). This basically boils down to a Java package level static initialization and i had to settle for a workaround using singleton pattern




Init enforces a singleton pattern and exposes a static function (initialize) invoked by the static blocks of both Activity and Service.





Android - Find process id of service

     Ever felt the need to find the id of the process hosting a service via code and thought of extracting the same output of "adb shell ps | grep "? 
 
      It seems to work except for the fact that searching by process name is not reliable. However, services in android world are uniquely identified by their name (string) and if you have access to android platform source code, just pull in this change,

         https://android-review.googlesource.com/#/c/19269/

     And its just a question to invoking a API

         ServiceManager.getServicePid("media.audio_flinger");

Update: Few folks have reached out for an existing solution as the Patch was never merged. The closest alternative i came across is to get the pid based on the command line which was used to launch the service process. This works for services hosted in its own process space like media server, surface flinger etc. Android's Process has a hidden API

     public static final native int[] getPidsForCommands(String[] cmds);

     The input parameter is an array of command lines like (/system/bin/mediaserver, /system/bin/surfaceflinger etc). The native logic is brute force which tries to open /proc/pid/cmdline for all known processes in a loop and returns the pid based on the specified command line options. Note that this isn't a process name based check which isn't reliable and is not recommended by framework developers. The downside is that developers need to know the process which hosts the queried service.