2

This only for learning the purpose, not intended for production usage.

I'm learning about memory barriers and trying to experiment with it. I have single CPU, multi-core system. I found out that two new memory-barrier related methods were introduced since Java 8. Now I wrote the following code and not quite sure about its thread-safety

private static final Unsafe U = //...
private int a = 0;
private int b = 0;

void foo(){
    a = 1;
    U.storeFence();
    b = 1;
}

void bar(){
    while( b == 0) continue;
    U.loadFence();
    assert(a == 1);
}

Now suppose we have 2-core CPU and two threads A and B. A invokes foo and B invokes bar. The load-store barrier Unsafe::loadFence executes store buffer on each CPU core, therefore, thread B should get the actual value of b.

Can this assertion fail? Is it correct? If no, please could you clarify?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 1
    Isn't it for [codereview.se] ? – AxelH Oct 23 '17 at 06:54
  • 1
    @AxelH Not exactly... I would like to improve my understanding of memory-barrier behavior on sinlge CPU system multicore. – St.Antario Oct 23 '17 at 06:55
  • 4
    Why do you want to use `Unsafe`? Wouldn't it be better to make it, well, safe? – Andy Turner Oct 23 '17 at 06:58
  • 1
    You might want to read this: https://stackoverflow.com/questions/23603304/java-8-unsafe-xxxfence-instructions – Erik Oct 23 '17 at 06:59
  • @AndyTurner Because I want to put memory barriers by myself. Is it possible to do another way? The question is not about unsafe anyway. I don't quite understand how memory barriers will do on the single cpu with mutiple cores. Does it make sense? – St.Antario Oct 23 '17 at 07:00
  • @Erik Yes, thanks much. – St.Antario Oct 23 '17 at 07:01
  • No, that code is not thread safe. You need to read the Java Memory Model specification (it's part of the JLS). There is no reason why a thread running method `bar` should even see the update to instance variable `b` done in method `foo` in a different thread. A compliant JVM is allowed to never show updates unless code is "correctly synchronized" (a term from the JMM, doesn't mean it needs to use `synchronized`, there are other ways too) and you are not using storeFence and loadFence to correctly synchronize the write to `b` either. – Erwin Bolwidt Oct 23 '17 at 07:03
  • @ErwinBolwidt I know about memory model. The question is not about happens-before ordering and synchronization, but about CPU caches and store-buffers and how Unsafe API can help us working with it. Just experimenting... – St.Antario Oct 23 '17 at 07:09
  • Your question was "Is the code thread safe?" - it's not. – Erwin Bolwidt Oct 23 '17 at 07:10
  • @ErwinBolwidt Incorrectly asked, yes. Fixed. – St.Antario Oct 23 '17 at 07:12
  • From programming point of view, different cores are different processors. They are counted separately in `Runtime.availableProcessors()`. And indeed they have separate L3 caches. – Alexei Kaigorodov Oct 23 '17 at 11:06
  • @AlexeiKaigorodov But how do cores communicate? I mean they also support some cache coherency protocol? Like in case of inter-CPU communication? – St.Antario Oct 23 '17 at 11:26
  • Of course they support cache coherency, and even at higher speed than separate CPUs, but still a programmer cannot assume that cache content is always identical. – Alexei Kaigorodov Oct 23 '17 at 15:29
  • @AlexeiKaigorodov Very interesting. Since they use the same L1 and L2 caches, the protocol should be simpler than in multi-CPU system. Where can I read about it for x86 architecture? Or for core-i7.... – St.Antario Oct 23 '17 at 15:47
  • @St.Antario sorry I did not investigate that issue and cannot help you. – Alexei Kaigorodov Oct 23 '17 at 21:55

0 Answers0