Is semaphore protection required in cooperative RTOS scheduler?

Assume I have #define configUSE_PREEMPTION 0, i.e. I’m using the cooperative RTOS scheduler.

My understanding is that if taskA writes a globally accessible data structure (and is the only task to write that data structure), then I don’t need to semaphore protection on that data structure since no other tasks can run while taskA is performing the write operation.

Is my understanding correct?

For example, in the following pidgin code, other tasks can safely call access_data_structure() at any time since vTaskA will always complete the update_data_structure() operation before any other tasks have a chance to run.

static data_structure_t s_data_structure;

void vTaskA(void *params) {
    ...
    while (1) {
        xTaskNotifyWait(0, 0, notification, xTicksToWait);
        update_data_structure(&s_data_structure);
    }
} 

data_structure_t *access_data_structure() {
  return &s_data_structure;
}

But if I DID have a preemptive RTOS scheduler, I might protect access to the data structure using a semaphore, along these lines:

static data_structure_t s_data_structure;

static void vTaskA(void *params) {
    ...
    while (1) {
        xTaskNotifyWait(0, 0, notification, xTicksToWait);
        xSemaphoreTake(s_my_mutex, WAIT_FOREVER);
        update_data_structure(&s_data_structure);
        xSemaphoreGive(s_my_mutex);
    }
} 

void access_data_structure(data_structure_t *dst) {
    // make a safe copy since taskA may modify it any time.
    xSemaphoreTake(s_my_mutex, WAIT_FOREVER);
    memcpy(dst, &s_data_structure, sizeof(data_structure_t));
    xSemaphoreGive(s_my_mutex);
}

Is that more or less right?

Understanding is correct provided no interrupt accesses the data and you don’t context switch in interrupts.

Thank you.

Interrupts do not access the data: Check!

Context switch in interrupts: Unknown. What controls whether or not context switching is enabled in interrupts?

Depends on the port, but most provide a macro called portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) for you to force a context switch from an interrupt. If you don’t call that from your ISRs then no context switches will happen from an ISR.

1 Like