File syn_mutex.c¶
File List > sched > syn_mutex.c
Go to the documentation of this file
#if __has_include("syn_config.h")
#include "syn_config.h"
#endif
#if !defined(SYN_USE_MUTEX) || SYN_USE_MUTEX
#include "../port/syn_port_system.h"
#include "../util/syn_assert.h"
#include "syn_mutex.h"
#include "syn_sched.h"
SYN_Status syn_mutex_init(SYN_Mutex *mutex)
{
if (mutex == NULL) {
return SYN_INVALID_PARAM;
}
mutex->owner = NULL;
mutex->lock_count = 0;
mutex->original_prio = 0;
return SYN_OK;
}
SYN_Status syn_mutex_try_lock(SYN_Mutex *mutex, SYN_Task *task)
{
if (mutex == NULL) {
return SYN_INVALID_PARAM;
}
syn_port_enter_critical();
/* Case 1: Mutex is currently unlocked */
if (mutex->owner == NULL && mutex->lock_count == 0) {
mutex->owner = task;
mutex->lock_count = 1;
mutex->original_prio = (task != NULL) ? task->base_priority : 0;
syn_port_exit_critical();
return SYN_OK;
}
/* Case 2: Recursive acquisition by the current owner */
if (task != NULL && mutex->owner == task) {
mutex->lock_count++;
syn_port_exit_critical();
return SYN_OK;
}
/* Case 3: Contended by another task — apply priority inheritance */
if (task != NULL && mutex->owner != NULL) {
if (task->priority < mutex->owner->priority) {
syn_task_boost_priority(mutex->owner, task->priority);
}
}
syn_port_exit_critical();
return SYN_BUSY;
}
SYN_Status syn_mutex_unlock(SYN_Mutex *mutex, SYN_Task *task)
{
if (mutex == NULL) {
return SYN_INVALID_PARAM;
}
syn_port_enter_critical();
if (mutex->lock_count == 0 || (task != NULL && mutex->owner != task)) {
syn_port_exit_critical();
return SYN_ERROR;
}
mutex->lock_count--;
if (mutex->lock_count == 0) {
if (mutex->owner != NULL) {
syn_task_restore_priority(mutex->owner);
}
mutex->owner = NULL;
mutex->original_prio = 0;
}
syn_port_exit_critical();
return SYN_OK;
}
bool syn_mutex_is_locked(const SYN_Mutex *mutex)
{
if (mutex == NULL) {
return false;
}
return (mutex->lock_count > 0);
}
SYN_Task *syn_mutex_get_owner(const SYN_Mutex *mutex)
{
if (mutex == NULL) {
return NULL;
}
return mutex->owner;
}
#endif /* SYN_USE_MUTEX */