[D-runtime] A cooperative suspension API

Michel Fortin michel.fortin at michelf.com
Sat May 5 07:54:41 PDT 2012


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/







More information about the D-runtime mailing list