https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124218

--- Comment #3 from Chris Copeland <chris.n.copeland at gmail dot com> ---
In real code we have something like this, using FreeRTOS as an example:

int flag;
SemaphoreHandle_t sem;

static void setter(void *)
{
    xSemaphoreTake(mutex, portMAX_DELAY);
    flag = 1;
    xSemaphoreGive(mutex);
}

static void waiter(void *arg)
{
    for (;;)
    {
        xSemaphoreTake(mutex, portMAX_DELAY);
        int done = flag;
        xSemaphoreGive(mutex);
        if (done)
            break;
    }
}

With setter and waiter provided as the entrypoints to two different tasks.
waiter gets compiled as an infinite loop with -O1 -fwhole-program, even though
there is context switching possible within the semaphore functions. What is the
correct way to annotate those functions so that ipa sees that flag can possibly
be modified? There is already a barrier instruction and a "memory" clobber
internal to the semaphore functions when a context switch can occur. An
equivalent program with pthreads does not exhibit this issue, but I'm hoping
that's not just because the pthreads implementation is invisible to ipa in
practice. My expectation is that it's possible to implement a synchronization
mechanism that's visible to ipa and doesn't require marking all shared
variables as volatile when they are protected by that synchronization.

Reply via email to