/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #define WAIT_TICKS 5 #define TIMEOUT_TICKS (10 + WAIT_TICKS) #define STACKSZ CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE int max_mtx_cnt = CONFIG_CMSIS_V2_MUTEX_MAX_COUNT; const osMutexAttr_t mutex_attr = { "myMutex", osMutexRecursive | osMutexPrioInherit, NULL, 0U }; void cleanup_max_mutex(osMutexId_t *mutex_ids) { int mutex_count = 0; osStatus_t status; for (mutex_count = 0; mutex_count < max_mtx_cnt; mutex_count++) { status = osMutexDelete(mutex_ids[mutex_count]); zassert_true(status == osOK, "Mutex delete fail"); } } void test_max_mutex(void) { osMutexId_t mutex_ids[CONFIG_CMSIS_V2_MUTEX_MAX_COUNT + 1]; int mtx_cnt = 0; /* Try mutex creation for more than maximum count */ for (mtx_cnt = 0; mtx_cnt < max_mtx_cnt + 1; mtx_cnt++) { mutex_ids[mtx_cnt] = osMutexNew(&mutex_attr); if (mtx_cnt == max_mtx_cnt) { zassert_true(mutex_ids[mtx_cnt] == NULL, "Mutex creation pass unexpectedly after max count"); cleanup_max_mutex(mutex_ids); } else { zassert_true(mutex_ids[mtx_cnt] != NULL, "Multiple mutex creation failed before max count"); } } } ZTEST(cmsis_mutex, test_mutex) { osMutexId_t mutex_id = 0; osThreadId_t id; osStatus_t status; const char *name; /* Try deleting invalid mutex object */ status = osMutexDelete(mutex_id); zassert_true(status == osErrorParameter, "Invalid Mutex deleted unexpectedly!"); mutex_id = osMutexNew(&mutex_attr); zassert_true(mutex_id != NULL, "Mutex1 creation failed"); name = osMutexGetName(mutex_id); zassert_str_equal(mutex_attr.name, name, "Error getting Mutex name"); /* Try to release mutex without obtaining it */ status = osMutexRelease(mutex_id); zassert_true(status == osErrorResource, "Mutex released unexpectedly!"); /* Try figuring out the owner for a Mutex which has not been * acquired by any thread yet. */ id = osMutexGetOwner(mutex_id); zassert_true(id == NULL, "Something wrong with MutexGetOwner!"); status = osMutexAcquire(mutex_id, 0); zassert_true(status == osOK, "Mutex wait failure"); id = osMutexGetOwner(mutex_id); zassert_equal(id, osThreadGetId(), "Current thread is not the owner!"); /* Try to acquire an already acquired mutex */ status = osMutexAcquire(mutex_id, 0); zassert_true(status == osOK, "Mutex wait failure"); status = osMutexRelease(mutex_id); zassert_true(status == osOK, "Mutex release failure"); /* Release mutex again as it was acquired twice */ status = osMutexRelease(mutex_id); zassert_true(status == osOK, "Mutex release failure"); /* Try to release mutex that was already released */ status = osMutexRelease(mutex_id); zassert_true(status == osErrorResource, "Mutex released unexpectedly!"); status = osMutexDelete(mutex_id); zassert_true(status == osOK, "Mutex delete failure"); /* Try mutex creation for more than maximum allowed count */ test_max_mutex(); } void tThread_entry_lock_timeout(void *arg) { osStatus_t status; osThreadId_t id; /* Mutex cannot be acquired/released here as it is still held * by the other thread. Try with and without timeout. */ status = osMutexAcquire((osMutexId_t)arg, 0); zassert_true(status == osErrorResource); status = osMutexAcquire((osMutexId_t)arg, WAIT_TICKS); zassert_true(status == osErrorTimeout); status = osMutexRelease((osMutexId_t)arg); zassert_true(status == osErrorResource, "Mutex unexpectedly released"); id = osMutexGetOwner((osMutexId_t)arg); zassert_not_equal(id, osThreadGetId(), "Unexpectedly, current thread is the mutex owner!"); /* This delay ensures that the mutex gets released by the other * thread in the meantime */ osDelay(TIMEOUT_TICKS); /* Now that the mutex is free, it should be possible to acquire * and release it. */ status = osMutexAcquire((osMutexId_t)arg, TIMEOUT_TICKS); zassert_true(status == osOK); osMutexRelease((osMutexId_t)arg); } static K_THREAD_STACK_DEFINE(test_stack, STACKSZ); static osThreadAttr_t thread_attr = { .name = "Mutex_check", .attr_bits = osThreadDetached, .cb_mem = NULL, .cb_size = 0, .stack_mem = &test_stack, .stack_size = STACKSZ, .priority = osPriorityNormal, .tz_module = 0, .reserved = 0 }; ZTEST(cmsis_mutex, test_mutex_lock_timeout) { osThreadId_t id; osMutexId_t mutex_id; osStatus_t status; mutex_id = osMutexNew(&mutex_attr); zassert_true(mutex_id != NULL, "Mutex2 creation failed"); id = osThreadNew(tThread_entry_lock_timeout, mutex_id, &thread_attr); zassert_true(id != NULL, "Thread creation failed"); status = osMutexAcquire(mutex_id, osWaitForever); zassert_true(status == osOK, "Mutex wait failure"); /* wait for spawn thread to take action */ osDelay(TIMEOUT_TICKS); /* Release the mutex to be used by the other thread */ osMutexRelease(mutex_id); osDelay(TIMEOUT_TICKS); osMutexDelete(mutex_id); } ZTEST_SUITE(cmsis_mutex, NULL, NULL, NULL, NULL, NULL);