Why doesn't this compiler barrier enforce ordering?

天涯浪子 提交于 2020-01-02 07:54:07

问题


I was looking at the documentation on the Atmel website and I came across this example where they explain some issues with reordering.

Here's the example code:

#define cli() __asm volatile( "cli" ::: "memory" )
#define sei() __asm volatile( "sei" ::: "memory" )

unsigned int ivar;

void test2( unsigned int val )
{
  val = 65535U / val;

  cli();

  ivar = val;

  sei();
}

In this example, they're implementing a critical region-like mechanism. The cli instruction disables interrupts and the sei instruction enables them. Normally, I would save the interrupt state and restore to that state, but I digress...

The problem which they note is that, with optimization enabled, the division on the first line actually gets moved to after the cli instruction. This can cause some issues when you're trying to be inside of the critical region for the shortest amount of time as possible.

How come this is possible if the cli() MACRO expands to inline asm which explicitly clobbers the memory? How is the compiler free to move things before or after this statement?

Also, I modified the code to include memory barriers before every statement in the form of __asm volatile("" ::: "memory"); and it doesn't seem to change anything.

I also removed the memory clobber from the cli() and sei() MACROs, and the generated code was identical.

Of course, if I declare the test2 function argument as volatile, there is no reordering, which I assume to be because volatile statements can't be reordered with respect to other volatile statements (which the inline asm technically is). Is my assumption correct?

Can volatile accesses be reordered with respect to volatile inline asm?

Can non-volatile accesses be reordered with respect to volatile inline asm?

What's weird is that Atmel claims they need the memory clobber just to enforce the ordering of volatile accesses with respect to the asm. That doesn't make any sense to me.

If the compiler barrier isn't the proper solution for this, then how could I go about preventing any outside code from "leaking" into the critical region?

If anyone could shed some light, I'd appreciate it.

Thanks

来源:https://stackoverflow.com/questions/37897848/why-doesnt-this-compiler-barrier-enforce-ordering

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!