What about on UP, where a strong compiler will realize that the call only raises IRQL to dispatch, and since these apis are in NTOSKRNL, they might get in-lined or modified.

On AMD64, raising the IRQL means only modifying cr8.

So the function will become:

OldIrql == __readcr8();
__writecr8(DISPATCH_LEVEL);
inc dword ptr [reg];
__writecr8(OldIrql);

Is ordering still guaranteed in this scenario?

--
Best regards,
Alex Ionescu

On 2011-06-03, at 3:35 PM, Timo Kreuzer wrote:

Am 03.06.2011 17:55, schrieb Alex Ionescu:
While the paper on Linux's spinlock semantics was very interesting, it remains the fact that this is not the case in Windows in this particular instance.

A lot of ReactOS code *is* missing calls such as KeMemoryBarrier() and (volatile), and only works by chance, so the argument that "otherwise our code wouldn't work" is a bit of a fallacy.

You also need to think outside the strict-ordering x86 box. Most of ReactOS' code is totally borked on IA64, PPC or ARM (and semi-broken on x64 too, which has looser ordering).

Of course, feel free to ignore the suggestion.

--
Best regards,
Alex Ionescu


I won't ignore the suggestion. I'd rather try to convince you that its useless.
Lets look at this particular instance.

    Irql = KeAcquireQueuedSpinLock(Queue);
    OldValue = (*Ulong)--;
    KeReleaseQueuedSpinLock(Queue, Irql);

KeAcquireQueuedSpinLock is declared as:

_DECL_HAL_KE_IMPORT
KIRQL
FASTCALL
KeAcquireQueuedSpinLock(
  IN OUT KSPIN_LOCK_QUEUE_NUMBER Number);

Thats really all we need to know. Its a fastcall function. Its not inline, but a function calls across the translation unit boundaries. This alone is enough to guarantee strict compiler ordering of memory accesses around the bounds of the call.
The compiler cannot know what will happen inside the function that is being called, so it won't make any assumptions about reordering possibilities.

See:
http://publications.gbdirect.co.uk/c_book/chapter8/sequence_points.html

MSDN: http://msdn.microsoft.com/en-us/library/d45c7a5d%28VS.80%29.aspx
"Function-call operator. The function-call expression and all arguments to a function, including default arguments, are evaluated and all side effects completed prior to entry to the function. There is no specified order of evaluation among the arguments or the function-call expression."

Also described in the ansi-C standard, but pretty abstract:
http://www.bsb.me.uk/ansi-c/ansi-c-one-file#sec_2_1_2_3
http://www.bsb.me.uk/ansi-c/ansi-c-one-file#sec_3_3_2_2

Regards,
Timo

_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev