summaryrefslogtreecommitdiff
path: root/src/ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipc.c')
-rw-r--r--src/ipc.c319
1 files changed, 145 insertions, 174 deletions
diff --git a/src/ipc.c b/src/ipc.c
index fe85c9d56c..75bdb2eafc 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -45,6 +45,7 @@
* 2022-10-15 Bernard add nested mutex feature
* 2022-10-16 Bernard add prioceiling feature in mutex
* 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size
+ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
*/
#include <rtthread.h>
@@ -133,6 +134,8 @@ rt_inline rt_err_t _ipc_list_suspend(rt_list_t *list,
rt_uint8_t flag,
int suspend_flag)
{
+ rt_base_t level_local;
+ level_local = rt_hw_local_irq_disable();
if ((thread->stat & RT_THREAD_SUSPEND_MASK) != RT_THREAD_SUSPEND_MASK)
{
rt_err_t ret = rt_thread_suspend_with_flag(thread, suspend_flag);
@@ -140,6 +143,7 @@ rt_inline rt_err_t _ipc_list_suspend(rt_list_t *list,
/* suspend thread */
if (ret != RT_EOK)
{
+ rt_hw_local_irq_enable(level_local);
return ret;
}
}
@@ -182,7 +186,7 @@ rt_inline rt_err_t _ipc_list_suspend(rt_list_t *list,
RT_ASSERT(0);
break;
}
-
+ rt_hw_local_irq_enable(level_local);
return RT_EOK;
}
@@ -240,13 +244,10 @@ rt_inline rt_err_t _ipc_list_resume(rt_list_t *list)
rt_inline rt_err_t _ipc_list_resume_all(rt_list_t *list)
{
struct rt_thread *thread;
- rt_base_t level;
/* wakeup all suspended threads */
while (!rt_list_isempty(list))
{
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
/* get next suspended thread */
thread = rt_list_entry(list->next, struct rt_thread, tlist);
@@ -259,9 +260,6 @@ rt_inline rt_err_t _ipc_list_resume_all(rt_list_t *list)
* suspended list
*/
rt_thread_resume(thread);
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
}
return RT_EOK;
@@ -331,6 +329,7 @@ rt_err_t rt_sem_init(rt_sem_t sem,
/* set parent */
sem->parent.parent.flag = flag;
+ rt_spin_lock_init(&(sem->spinlock));
return RT_EOK;
}
@@ -357,16 +356,20 @@ RTM_EXPORT(rt_sem_init);
*/
rt_err_t rt_sem_detach(rt_sem_t sem)
{
+ rt_base_t level;
+
/* parameter check */
RT_ASSERT(sem != RT_NULL);
RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore);
RT_ASSERT(rt_object_is_systemobject(&sem->parent.parent));
+ level = rt_spin_lock_irqsave(&(sem->spinlock));
/* wakeup all suspended threads */
_ipc_list_resume_all(&(sem->parent.suspend_thread));
/* detach semaphore object */
rt_object_detach(&(sem->parent.parent));
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
return RT_EOK;
}
@@ -427,6 +430,7 @@ rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)
/* set parent */
sem->parent.parent.flag = flag;
+ rt_spin_lock_init(&(sem->spinlock));
return sem;
}
@@ -514,8 +518,7 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
/* current context checking */
RT_DEBUG_SCHEDULER_AVAILABLE(sem->value == 0 && timeout != 0);
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(sem->spinlock));
LOG_D("thread %s take sem:%s, which value is: %d",
rt_thread_self()->parent.name,
@@ -526,17 +529,14 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
{
/* semaphore is available */
sem->value --;
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
}
else
{
/* no waiting, return with timeout */
if (timeout == 0)
{
- rt_hw_interrupt_enable(level);
-
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
return -RT_ETIMEOUT;
}
else
@@ -557,7 +557,7 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
return ret;
}
@@ -574,7 +574,7 @@ static rt_err_t _rt_sem_take(rt_sem_t sem, rt_int32_t timeout, int suspend_flag)
}
/* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
/* do schedule */
rt_schedule();
@@ -655,8 +655,7 @@ rt_err_t rt_sem_release(rt_sem_t sem)
need_schedule = RT_FALSE;
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(sem->spinlock));
LOG_D("thread %s releases sem:%s, which value is: %d",
rt_thread_self()->parent.name,
@@ -677,13 +676,12 @@ rt_err_t rt_sem_release(rt_sem_t sem)
}
else
{
- rt_hw_interrupt_enable(level); /* enable interrupt */
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
return -RT_EFULL; /* value overflowed */
}
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
/* resume a thread, re-schedule */
if (need_schedule == RT_TRUE)
@@ -722,18 +720,14 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg)
/* get value */
value = (rt_ubase_t)arg;
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(sem->spinlock));
/* resume all waiting thread */
_ipc_list_resume_all(&sem->parent.suspend_thread);
/* set new value */
sem->value = (rt_uint16_t)value;
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
-
+ rt_spin_unlock_irqrestore(&(sem->spinlock), level);
rt_schedule();
return RT_EOK;
@@ -894,6 +888,7 @@ rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
/* flag can only be RT_IPC_FLAG_PRIO. RT_IPC_FLAG_FIFO cannot solve the unbounded priority inversion problem */
mutex->parent.parent.flag = RT_IPC_FLAG_PRIO;
+ rt_spin_lock_init(&(mutex->spinlock));
return RT_EOK;
}
@@ -927,12 +922,12 @@ rt_err_t rt_mutex_detach(rt_mutex_t mutex)
RT_ASSERT(rt_object_get_type(&mutex->parent.parent) == RT_Object_Class_Mutex);
RT_ASSERT(rt_object_is_systemobject(&mutex->parent.parent));
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
/* wakeup all suspended threads */
_ipc_list_resume_all(&(mutex->parent.suspend_thread));
/* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list);
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
/* detach mutex object */
rt_object_detach(&(mutex->parent.parent));
@@ -953,7 +948,13 @@ void rt_mutex_drop_thread(rt_mutex_t mutex, rt_thread_t thread)
{
rt_uint8_t priority;
rt_bool_t need_update = RT_FALSE;
+ rt_ubase_t level;
+ /* parameter check */
+ RT_ASSERT(mutex != RT_NULL);
+ RT_ASSERT(thread != RT_NULL);
+
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
rt_list_remove(&(thread->tlist));
/**
@@ -994,6 +995,7 @@ void rt_mutex_drop_thread(rt_mutex_t mutex, rt_thread_t thread)
_thread_update_priority(mutex->owner, priority, RT_UNINTERRUPTIBLE);
}
}
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
}
@@ -1012,7 +1014,7 @@ rt_uint8_t rt_mutex_setprioceiling(rt_mutex_t mutex, rt_uint8_t priority)
if ((mutex) && (priority < RT_THREAD_PRIORITY_MAX))
{
/* critical section here if multiple updates to one mutex happen */
- rt_ubase_t level = rt_hw_interrupt_disable();
+ rt_ubase_t level = rt_spin_lock_irqsave(&(mutex->spinlock));
ret_priority = mutex->ceiling_priority;
mutex->ceiling_priority = priority;
if (mutex->owner)
@@ -1021,7 +1023,7 @@ rt_uint8_t rt_mutex_setprioceiling(rt_mutex_t mutex, rt_uint8_t priority)
if (priority != mutex->owner->current_priority)
_thread_update_priority(mutex->owner, priority, RT_UNINTERRUPTIBLE);
}
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
}
else
{
@@ -1043,10 +1045,16 @@ RTM_EXPORT(rt_mutex_setprioceiling);
rt_uint8_t rt_mutex_getprioceiling(rt_mutex_t mutex)
{
rt_uint8_t prio = 0xFF;
+ rt_ubase_t level;
+
+ /* parameter check */
+ RT_ASSERT(mutex != RT_NULL);
if (mutex)
{
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
prio = mutex->ceiling_priority;
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
}
return prio;
@@ -1098,6 +1106,7 @@ rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
/* flag can only be RT_IPC_FLAG_PRIO. RT_IPC_FLAG_FIFO cannot solve the unbounded priority inversion problem */
mutex->parent.parent.flag = RT_IPC_FLAG_PRIO;
+ rt_spin_lock_init(&(mutex->spinlock));
return mutex;
}
@@ -1133,12 +1142,12 @@ rt_err_t rt_mutex_delete(rt_mutex_t mutex)
RT_DEBUG_NOT_IN_INTERRUPT;
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
/* wakeup all suspended threads */
_ipc_list_resume_all(&(mutex->parent.suspend_thread));
/* remove mutex from thread's taken list */
rt_list_remove(&mutex->taken_list);
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
/* delete mutex object */
rt_object_delete(&(mutex->parent.parent));
@@ -1189,8 +1198,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
/* get current thread */
thread = rt_thread_self();
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mutex->parent.parent)));
@@ -1209,7 +1217,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
}
else
{
- rt_hw_interrupt_enable(level); /* enable interrupt */
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
return -RT_EFULL; /* value overflowed */
}
}
@@ -1241,8 +1249,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
/* set error as timeout */
thread->error = -RT_ETIMEOUT;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
return -RT_ETIMEOUT;
}
@@ -1261,7 +1268,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
return ret;
}
@@ -1291,14 +1298,12 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
rt_timer_start(&(thread->thread_timer));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
/* do schedule */
rt_schedule();
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
if (thread->error == RT_EOK)
{
@@ -1349,8 +1354,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
}
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
/* clear pending object before exit */
thread->pending_object = RT_NULL;
@@ -1363,8 +1367,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
}
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mutex->parent.parent)));
@@ -1441,8 +1444,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
/* get current thread */
thread = rt_thread_self();
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mutex->spinlock));
LOG_D("mutex_release:current thread %s, hold: %d",
thread->parent.name, mutex->hold);
@@ -1453,9 +1455,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
if (thread != mutex->owner)
{
thread->error = -RT_ERROR;
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
return -RT_ERROR;
}
@@ -1494,6 +1494,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
LOG_D("mutex_release: resume thread: %s",
next_thread->parent.name);
+ rt_spin_lock(&(next_thread->spinlock));
/* remove the thread from the suspended list of mutex */
rt_list_remove(&(next_thread->tlist));
@@ -1503,7 +1504,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
rt_list_insert_after(&next_thread->taken_object_list, &mutex->taken_list);
/* cleanup pending object */
next_thread->pending_object = RT_NULL;
-
+ rt_spin_unlock(&(next_thread->spinlock));
/* resume thread */
rt_thread_resume(next_thread);
@@ -1532,8 +1533,7 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
}
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mutex->spinlock), level);
/* perform a schedule */
if (need_schedule == RT_TRUE)
@@ -1628,6 +1628,7 @@ rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag)
/* initialize event */
event->set = 0;
+ rt_spin_lock_init(&(event->spinlock));
return RT_EOK;
}
@@ -1654,16 +1655,20 @@ RTM_EXPORT(rt_event_init);
*/
rt_err_t rt_event_detach(rt_event_t event)
{
+ rt_base_t level;
+
/* parameter check */
RT_ASSERT(event != RT_NULL);
RT_ASSERT(rt_object_get_type(&event->parent.parent) == RT_Object_Class_Event);
RT_ASSERT(rt_object_is_systemobject(&event->parent.parent));
+ level = rt_spin_lock_irqsave(&(event->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&(event->parent.suspend_thread));
/* detach event object */
rt_object_detach(&(event->parent.parent));
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
return RT_EOK;
}
@@ -1719,6 +1724,7 @@ rt_event_t rt_event_create(const char *name, rt_uint8_t flag)
/* initialize event */
event->set = 0;
+ rt_spin_lock_init(&(event->spinlock));
return event;
}
@@ -1752,11 +1758,13 @@ rt_err_t rt_event_delete(rt_event_t event)
RT_DEBUG_NOT_IN_INTERRUPT;
+ rt_spin_lock(&(event->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&(event->parent.suspend_thread));
/* delete event object */
rt_object_delete(&(event->parent.parent));
+ rt_spin_unlock(&(event->spinlock));
return RT_EOK;
}
@@ -1799,8 +1807,7 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
need_schedule = RT_FALSE;
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(event->spinlock));
/* set event */
event->set |= set;
@@ -1838,8 +1845,7 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
}
else
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
return -RT_EINVAL;
}
@@ -1868,8 +1874,7 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
}
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
/* do a schedule */
if (need_schedule == RT_TRUE)
@@ -1943,8 +1948,7 @@ static rt_err_t _rt_event_recv(rt_event_t event,
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(event->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(event->spinlock));
/* check event set */
if (option & RT_EVENT_FLAG_AND)
@@ -1984,8 +1988,7 @@ static rt_err_t _rt_event_recv(rt_event_t event,
/* no waiting */
thread->error = -RT_ETIMEOUT;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
return -RT_ETIMEOUT;
}
@@ -2002,7 +2005,7 @@ static rt_err_t _rt_event_recv(rt_event_t event,
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
return ret;
}
@@ -2016,8 +2019,7 @@ static rt_err_t _rt_event_recv(rt_event_t event,
rt_timer_start(&(thread->thread_timer));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
/* do a schedule */
rt_schedule();
@@ -2029,15 +2031,14 @@ static rt_err_t _rt_event_recv(rt_event_t event,
}
/* received an event, disable interrupt to protect */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(event->spinlock));
/* set received event */
if (recved)
*recved = thread->event_set;
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(event->parent.parent)));
@@ -2097,8 +2098,7 @@ rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg)
if (cmd == RT_IPC_CMD_RESET)
{
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(event->spinlock));
/* resume all waiting thread */
_ipc_list_resume_all(&event->parent.suspend_thread);
@@ -2106,8 +2106,7 @@ rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg)
/* initialize event set */
event->set = 0;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(event->spinlock), level);
rt_schedule();
@@ -2192,6 +2191,7 @@ rt_err_t rt_mb_init(rt_mailbox_t mb,
/* initialize an additional list of sender suspend thread */
rt_list_init(&(mb->suspend_sender_thread));
+ rt_spin_lock_init(&(mb->spinlock));
return RT_EOK;
}
@@ -2218,11 +2218,14 @@ RTM_EXPORT(rt_mb_init);
*/
rt_err_t rt_mb_detach(rt_mailbox_t mb)
{
+ rt_base_t level;
+
/* parameter check */
RT_ASSERT(mb != RT_NULL);
RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox);
RT_ASSERT(rt_object_is_systemobject(&mb->parent.parent));
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&(mb->parent.suspend_thread));
/* also resume all mailbox private suspended thread */
@@ -2230,6 +2233,7 @@ rt_err_t rt_mb_detach(rt_mailbox_t mb)
/* detach mailbox object */
rt_object_detach(&(mb->parent.parent));
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return RT_EOK;
}
@@ -2302,6 +2306,7 @@ rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
/* initialize an additional list of sender suspend thread */
rt_list_init(&(mb->suspend_sender_thread));
+ rt_spin_lock_init(&(mb->spinlock));
return mb;
}
@@ -2334,6 +2339,7 @@ rt_err_t rt_mb_delete(rt_mailbox_t mb)
RT_ASSERT(rt_object_is_systemobject(&mb->parent.parent) == RT_FALSE);
RT_DEBUG_NOT_IN_INTERRUPT;
+ rt_spin_lock(&(mb->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&(mb->parent.suspend_thread));
@@ -2341,6 +2347,8 @@ rt_err_t rt_mb_delete(rt_mailbox_t mb)
/* also resume all mailbox private suspended thread */
_ipc_list_resume_all(&(mb->suspend_sender_thread));
+ rt_spin_unlock(&(mb->spinlock));
+
/* free mailbox pool */
RT_KERNEL_FREE(mb->msg_pool);
@@ -2401,12 +2409,12 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent)));
/* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* for non-blocking call */
if (mb->entry == mb->size && timeout == 0)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return -RT_EFULL;
}
@@ -2419,8 +2427,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
/* no waiting, return timeout */
if (timeout == 0)
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return -RT_EFULL;
}
@@ -2433,7 +2440,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return ret;
}
@@ -2452,9 +2459,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
&timeout);
rt_timer_start(&(thread->thread_timer));
}
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
/* re-schedule */
rt_schedule();
@@ -2466,8 +2471,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
return thread->error;
}
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* if it's not waiting forever and then re-calculate timeout tick */
if (timeout > 0)
@@ -2493,7 +2497,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
}
else
{
- rt_hw_interrupt_enable(level); /* enable interrupt */
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return -RT_EFULL; /* value overflowed */
}
@@ -2502,16 +2506,13 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb,
{
_ipc_list_resume(&(mb->parent.suspend_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
rt_schedule();
return RT_EOK;
}
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return RT_EOK;
}
@@ -2600,12 +2601,11 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mb->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
if (mb->entry == mb->size)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return -RT_EFULL;
}
@@ -2630,16 +2630,13 @@ rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)
{
_ipc_list_resume(&(mb->parent.suspend_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
rt_schedule();
return RT_EOK;
}
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return RT_EOK;
}
@@ -2692,13 +2689,12 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mb->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* for non-blocking call */
if (mb->entry == 0 && timeout == 0)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return -RT_ETIMEOUT;
}
@@ -2712,8 +2708,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
/* no waiting, return timeout */
if (timeout == 0)
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
thread->error = -RT_ETIMEOUT;
@@ -2727,7 +2722,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
return ret;
}
@@ -2747,8 +2742,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
rt_timer_start(&(thread->thread_timer));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
/* re-schedule */
rt_schedule();
@@ -2759,9 +2753,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
/* return error */
return thread->error;
}
-
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* if it's not waiting forever and then re-calculate timeout tick */
if (timeout > 0)
@@ -2792,8 +2784,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
{
_ipc_list_resume(&(mb->suspend_sender_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mb->parent.parent)));
@@ -2801,9 +2792,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo
return RT_EOK;
}
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mb->parent.parent)));
@@ -2852,8 +2841,7 @@ rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg)
if (cmd == RT_IPC_CMD_RESET)
{
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mb->spinlock));
/* resume all waiting thread */
_ipc_list_resume_all(&(mb->parent.suspend_thread));
@@ -2865,8 +2853,7 @@ rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg)
mb->in_offset = 0;
mb->out_offset = 0;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mb->spinlock), level);
rt_schedule();
@@ -2984,6 +2971,7 @@ rt_err_t rt_mq_init(rt_mq_t mq,
/* initialize an additional list of sender suspend thread */
rt_list_init(&(mq->suspend_sender_thread));
+ rt_spin_lock_init(&(mq->spinlock));
return RT_EOK;
}
@@ -3010,11 +2998,14 @@ RTM_EXPORT(rt_mq_init);
*/
rt_err_t rt_mq_detach(rt_mq_t mq)
{
+ rt_base_t level;
+
/* parameter check */
RT_ASSERT(mq != RT_NULL);
RT_ASSERT(rt_object_get_type(&mq->parent.parent) == RT_Object_Class_MessageQueue);
RT_ASSERT(rt_object_is_systemobject(&mq->parent.parent));
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&mq->parent.suspend_thread);
/* also resume all message queue private suspended thread */
@@ -3022,6 +3013,7 @@ rt_err_t rt_mq_detach(rt_mq_t mq)
/* detach message queue object */
rt_object_detach(&(mq->parent.parent));
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return RT_EOK;
}
@@ -3120,6 +3112,7 @@ rt_mq_t rt_mq_create(const char *name,
/* initialize an additional list of sender suspend thread */
rt_list_init(&(mq->suspend_sender_thread));
+ rt_spin_lock_init(&(mq->spinlock));
return mq;
}
@@ -3154,11 +3147,14 @@ rt_err_t rt_mq_delete(rt_mq_t mq)
RT_DEBUG_NOT_IN_INTERRUPT;
+ rt_spin_lock(&(mq->spinlock));
/* resume all suspended thread */
_ipc_list_resume_all(&(mq->parent.suspend_thread));
/* also resume all message queue private suspended thread */
_ipc_list_resume_all(&(mq->suspend_sender_thread));
+ rt_spin_unlock(&(mq->spinlock));
+
/* free message queue pool */
RT_KERNEL_FREE(mq->msg_pool);
@@ -3236,16 +3232,14 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mq->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* get a free list, there must be an empty item */
msg = (struct rt_mq_message *)mq->msg_queue_free;
/* for non-blocking call */
if (msg == RT_NULL && timeout == 0)
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_EFULL;
}
@@ -3259,8 +3253,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
/* no waiting, return timeout */
if (timeout == 0)
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_EFULL;
}
@@ -3272,7 +3265,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return ret;
}
@@ -3292,8 +3285,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
rt_timer_start(&(thread->thread_timer));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
/* re-schedule */
rt_schedule();
@@ -3304,9 +3296,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
/* return error */
return thread->error;
}
-
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* if it's not waiting forever and then re-calculate timeout tick */
if (timeout > 0)
@@ -3321,8 +3311,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
/* move free list pointer */
mq->msg_queue_free = msg->next;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
/* the msg is the new tailer of list, the next shall be NULL */
msg->next = RT_NULL;
@@ -3333,7 +3322,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
rt_memcpy(GET_MESSAGEBYTE_ADDR(msg), buffer, size);
/* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
msg->prio = prio;
if (mq->msg_queue_head == RT_NULL)
@@ -3382,7 +3371,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
}
else
{
- rt_hw_interrupt_enable(level); /* enable interrupt */
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_EFULL; /* value overflowed */
}
@@ -3391,16 +3380,13 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
{
_ipc_list_resume(&(mq->parent.suspend_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
rt_schedule();
return RT_EOK;
}
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return RT_EOK;
}
@@ -3505,32 +3491,28 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mq->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* get a free list, there must be an empty item */
msg = (struct rt_mq_message *)mq->msg_queue_free;
/* message queue is full */
if (msg == RT_NULL)
{
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_EFULL;
}
/* move free list pointer */
mq->msg_queue_free = msg->next;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
/* add the length */
((struct rt_mq_message *)msg)->length = size;
/* copy buffer */
rt_memcpy(GET_MESSAGEBYTE_ADDR(msg), buffer, size);
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* link msg to the beginning of message queue */
msg->next = (struct rt_mq_message *)mq->msg_queue_head;
@@ -3547,7 +3529,7 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
}
else
{
- rt_hw_interrupt_enable(level); /* enable interrupt */
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_EFULL; /* value overflowed */
}
@@ -3556,16 +3538,14 @@ rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
{
_ipc_list_resume(&(mq->parent.suspend_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
rt_schedule();
return RT_EOK;
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return RT_EOK;
}
@@ -3630,13 +3610,12 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
thread = rt_thread_self();
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent)));
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* for non-blocking call */
if (mq->entry == 0 && timeout == 0)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return -RT_ETIMEOUT;
}
@@ -3651,7 +3630,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
if (timeout == 0)
{
/* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
thread->error = -RT_ETIMEOUT;
@@ -3665,7 +3644,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
suspend_flag);
if (ret != RT_EOK)
{
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
return ret;
}
@@ -3685,8 +3664,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
rt_timer_start(&(thread->thread_timer));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
/* re-schedule */
rt_schedule();
@@ -3698,8 +3676,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
return thread->error;
}
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* if it's not waiting forever and then re-calculate timeout tick */
if (timeout > 0)
@@ -3726,8 +3703,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
mq->entry --;
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
/* get real message length */
len = ((struct rt_mq_message *)msg)->length;
@@ -3741,8 +3717,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
if (prio != RT_NULL)
*prio = msg->prio;
#endif
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* put message to free list */
msg->next = (struct rt_mq_message *)mq->msg_queue_free;
mq->msg_queue_free = msg;
@@ -3752,8 +3727,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
{
_ipc_list_resume(&(mq->suspend_sender_thread));
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mq->parent.parent)));
@@ -3762,8 +3736,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq,
return len;
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mq->parent.parent)));
@@ -3841,8 +3814,7 @@ rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg)
if (cmd == RT_IPC_CMD_RESET)
{
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
+ level = rt_spin_lock_irqsave(&(mq->spinlock));
/* resume all waiting thread */
_ipc_list_resume_all(&mq->parent.suspend_thread);
@@ -3869,8 +3841,7 @@ rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg)
/* clean entry */
mq->entry = 0;
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
+ rt_spin_unlock_irqrestore(&(mq->spinlock), level);
rt_schedule();