[D-runtime] A cooperative suspension API
Sean Kelly
sean at invisibleduck.org
Sat May 5 08:16:43 PDT 2012
I think __gshared is treated just like static in C. You'd probably want shared.
On May 5, 2012, at 8:11 AM, Alex Rønne Petersen <xtzgzorex at gmail.com> wrote:
>> Here the compiler can coalesce every read to g_shouldSuspend into a single read because it assumes g_shouldSuspend is thread local and sees no code in the loop that could potentially change the variable. Hence why you need volatile to force the compiler to always read from memory.
>
> OK, I understand what you are getting at. A C compiler would probably
> make this assumption at -O3 or something. However, things aren't quite
> the same in D as they are in C here. In D, __gshared explicitly tells
> the compiler "this variable is global -- it is shared among threads --
> and can change at any time". If a compiler still chooses to do the
> read only once, then it is generating wrong code. Keep in mind that in
> D, we have an explicit differentiation between thread-local and global
> data.
>
> Besides, if the compiler did do this optimization, I think a lot of
> druntime and phobos code would break.
>
> Regards,
> Alex
>
> On Sat, May 5, 2012 at 4:54 PM, Michel Fortin <michel.fortin at michelf.com> wrote:
>> Le 2012-05-05 à 10:37, Alex Rønne Petersen a écrit :
>>
>>> I don't follow. Why would inlining the function have any impact on how
>>> many times the variable is actually read? That seems like a totally
>>> separate issue.
>>
>> Ok, for one thing, I quoted the wrong code. I'm still unsure about isCooperative, but I meant to quote shouldSuspend and suspendIfNeeded.
>>
>> __gshared bool g_shouldSuspend; // set by thread_suspendAll()
>>
>> @property static bool shouldSuspend()
>> {
>> return g_shouldSuspend;
>> }
>>
>> final void suspendIfNeeded()
>> {
>> if (g_shouldSuspend) // can only race against thread_suspendAll() setting it to false, which is ok
>> suspend(this);
>> }
>>
>> If you inline shouldSuspend and suspendIfNeeded inside a loop in some function, here's what you get:
>>
>> int i = 0;
>> while (true)
>> {
>> if (g_shouldSuspend)
>> suspend();
>> ++i;
>> }
>>
>> Here the compiler can coalesce every read to g_shouldSuspend into a single read because it assumes g_shouldSuspend is thread local and sees no code in the loop that could potentially change the variable. Hence why you need volatile to force the compiler to always read from memory.
>>
>> The optimized code would behave like this one, which is obviously not what you want:
>>
>> int i = 0;
>> bool local_shouldSuspend = g_shouldSuspend; // single read from memory to a register
>> while (true)
>> {
>> if (local_shouldSuspend)
>> suspend();
>> ++i;
>> }
>>
>>
>> --
>> Michel Fortin
>> michel.fortin at michelf.com
>> http://michelf.com/
>>
>>
>>
>>
>>
>> _______________________________________________
>> D-runtime mailing list
>> D-runtime at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/d-runtime
> _______________________________________________
> D-runtime mailing list
> D-runtime at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/d-runtime
More information about the D-runtime
mailing list