54#define DBG_TAG "kernel.ipc"
55#define DBG_LVL DBG_INFO
58#define GET_MESSAGEBYTE_ADDR(msg) ((struct rt_mq_message *) msg + 1)
59#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
60extern void (*rt_object_trytake_hook)(
struct rt_object *object);
61extern void (*rt_object_take_hook)(
struct rt_object *object);
62extern void (*rt_object_put_hook)(
struct rt_object *object);
122 LOG_D(
"%s [error:%d] failed to resume thread:%p from suspended list",
123 __func__,
error, thread);
130 if (thread_error >= 0)
133 thread->
error = thread_error;
257 for (n = susp_list->
next; n != susp_list; n = n->
next)
292#ifdef RT_USING_CONSOLE
299 for (node = list->
next; node != list; node = node->
next)
304 if (node->
next != list)
315#ifdef RT_USING_SEMAPHORE
321static void _sem_object_init(
rt_sem_t sem,
575 LOG_D(
"thread %s take sem:%s, which value is: %d",
601 thread->
error = RT_EINTR;
632 if (thread->
error != RT_EOK)
710 LOG_D(
"thread %s releases sem:%s, which value is: %d",
797 if (max_value < sem->value)
905 thread = pending_mutex->
owner;
945static void _mutex_before_delete_detach(
rt_mutex_t mutex)
962 need_schedule = _check_and_update_prio(mutex->
owner, mutex);
1061 _mutex_before_delete_detach(mutex);
1159 if ((mutex) && (priority < RT_THREAD_PRIORITY_MAX))
1179 rt_set_errno(-RT_EINVAL);
1182 return ret_priority;
1292 _mutex_before_delete_detach(mutex);
1346 LOG_D(
"mutex_take: current thread %s, hold: %d",
1350 thread->
error = RT_EOK;
1352 if (mutex->
owner == thread)
1371 mutex->
owner = thread;
1391 thread->
error = RT_ETIMEOUT;
1394 return -RT_ETIMEOUT;
1402 LOG_D(
"mutex_take: suspend thread: %s",
1422 if (priority < mutex->priority)
1436 LOG_D(
"mutex_take: start the timer of thread:%s",
1453 if (mutex->
owner == thread)
1469 ret = thread->
error;
1524 return ret > 0 ? -ret : ret;
1609 LOG_D(
"mutex_release:current thread %s, hold: %d",
1615 if (thread != mutex->
owner)
1617 thread->
error = -RT_ERROR;
1626 if (mutex->
hold == 0)
1634 need_schedule = _check_and_update_prio(thread, mutex);
1663 LOG_D(
"mutex_release: resume thread: %s",
1667 mutex->
owner = next_thread;
1746#ifdef RT_USING_EVENT
1796 event->parent.parent.flag = flag;
1994 n =
event->parent.suspend_thread.
next;
2032 if (status == RT_EOK)
2040 thread->
error = RT_EOK;
2048 event->set &= ~need_clear_set;
2123 thread->
error = -RT_EINTR;
2132 if ((event->
set & set) == set)
2137 if (event->
set & set)
2146 if (status == RT_EOK)
2148 thread->
error = RT_EOK;
2152 *recved = (
event->set & set);
2162 else if (timeout == 0)
2165 thread->
error = -RT_ETIMEOUT;
2169 return -RT_ETIMEOUT;
2201 if (thread->
error != RT_EOK)
2204 return thread->
error;
2219 return thread->
error;
2238 return _rt_event_recv(event, set, option, timeout, recved,
RT_INTERRUPTIBLE);
2248 return _rt_event_recv(event, set, option, timeout, recved,
RT_KILLABLE);
2299#ifdef RT_USING_MAILBOX
2591 if (mb->
entry == mb->
size && timeout == 0)
2601 thread->
error = -RT_EINTR;
2627 LOG_D(
"mb_send_wait: start timer of thread:%s",
2642 if (thread->
error != RT_EOK)
2645 return thread->
error;
2654 timeout -= tick_delta;
2714 return _rt_mb_send_wait(mb, value, timeout,
RT_KILLABLE);
2869 if (mb->
entry == 0 && timeout == 0)
2873 return -RT_ETIMEOUT;
2877 while (mb->
entry == 0)
2880 thread->
error = -RT_EINTR;
2887 thread->
error = -RT_ETIMEOUT;
2889 return -RT_ETIMEOUT;
2907 LOG_D(
"mb_recv: start timer of thread:%s",
2923 if (thread->
error != RT_EOK)
2926 return thread->
error;
2934 timeout -= tick_delta;
2988 return _rt_mb_recv(mb, value, timeout,
RT_KILLABLE);
3044#ifdef RT_USING_MESSAGEQUEUE
3120 msg_align_size =
RT_ALIGN(msg_size, RT_ALIGN_SIZE);
3135 for (temp = 0; temp < mq->
max_msgs; temp ++)
3257 msg_align_size =
RT_ALIGN(msg_size, RT_ALIGN_SIZE);
3276 for (temp = 0; temp < mq->
max_msgs; temp ++)
3416 if (msg ==
RT_NULL && timeout == 0)
3427 thread->
error = -RT_EINTR;
3452 LOG_D(
"mq_send_wait: start timer of thread:%s",
3468 if (thread->
error != RT_EOK)
3471 return thread->
error;
3479 timeout -= tick_delta;
3500#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
3508 if (node->prio < msg->prio)
3513 prev_node->
next = msg;
3591 return _rt_mq_send_wait(mq, buffer, size, 0, timeout,
RT_KILLABLE);
3792 if (mq->
entry == 0 && timeout == 0)
3796 return -RT_ETIMEOUT;
3800 while (mq->
entry == 0)
3803 thread->
error = -RT_EINTR;
3811 thread->
error = -RT_ETIMEOUT;
3813 return -RT_ETIMEOUT;
3831 LOG_D(
"set thread:%s to timer list",
3847 if (thread->
error != RT_EOK)
3850 return thread->
error;
3859 timeout -= tick_delta;
3890#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
3943 return _rt_mq_recv(mq, buffer, size, 0, timeout,
RT_KILLABLE);
3945#ifdef RT_USING_MESSAGEQUEUE_PRIORITY
3953 return _rt_mq_send_wait(mq, buffer, size, prio, timeout, suspend_flag);
3962 return _rt_mq_recv(mq, buffer, size, prio, timeout, suspend_flag);
#define RT_ALIGN(size, align)
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
This function will get or set some options of the timer
rt_err_t rt_timer_start(rt_timer_t timer)
This function will start the timer
rt_tick_t rt_tick_get(void)
This function will return current tick from operating system startup.
#define RT_TIMER_CTRL_SET_TIME
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
This function will disable the local interrupt and then lock the spinlock, will lock the thread sched...
rt_err_t rt_susp_list_resume_all_irq(rt_list_t *susp_list, rt_err_t thread_error, struct rt_spinlock *lock)
This function will resume all suspended threads in the IPC object list, including the suspended list ...
rt_inline void _thread_update_priority(struct rt_thread *thread, rt_uint8_t priority, int suspend_flag)
rt_err_t rt_susp_list_resume_all(rt_list_t *susp_list, rt_err_t thread_error)
This function will resume all suspended threads in the IPC object list, including the suspended list ...
rt_inline rt_err_t _ipc_object_init(struct rt_ipc_object *ipc)
This function will initialize an IPC object, such as semaphore, mutex, messagequeue and mailbox.
void rt_susp_list_print(rt_list_t *list)
Print thread on suspend list to system console
rt_inline rt_uint8_t _thread_get_mutex_priority(struct rt_thread *thread)
void rt_spin_lock(struct rt_spinlock *lock)
This function will lock the spinlock, will lock the thread scheduler.
void rt_spin_lock_init(struct rt_spinlock *lock)
Initialize a static spinlock object.
void rt_spin_unlock(struct rt_spinlock *lock)
This function will unlock the spinlock, will unlock the thread scheduler.
rt_inline rt_uint8_t _mutex_update_priority(struct rt_mutex *mutex)
struct rt_thread * rt_susp_list_dequeue(rt_list_t *susp_list, rt_err_t thread_error)
Dequeue a thread from suspended list and set it to ready. The 2 are taken as an atomic operation,...
rt_err_t rt_susp_list_enqueue(rt_list_t *susp_list, rt_thread_t thread, int ipc_flags)
Add a thread to the suspend list
#define RT_IPC_CMD_SET_VLIMIT
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
This function will unlock the spinlock and then restore current cpu interrupt status,...
void rt_object_delete(rt_object_t object)
This function will delete an object and release object memory.
void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name)
This function will initialize an object and add it to object system management.
rt_bool_t rt_object_is_systemobject(rt_object_t object)
This function will judge the object is system object or not.
#define RT_OBJECT_HOOK_CALL(func, argv)
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
This function will allocate an object from object system.
rt_uint8_t rt_object_get_type(rt_object_t object)
This function will return the type of object without RT_Object_Class_Static flag.
void rt_object_detach(rt_object_t object)
This function will detach a static object from object system, and the memory of static object is not ...
@ RT_Object_Class_MessageQueue
@ RT_Object_Class_MailBox
@ RT_Object_Class_Semaphore
rt_inline void rt_list_remove(rt_list_t *n)
remove node from list.
#define rt_list_for_each(pos, head)
rt_inline int rt_list_isempty(const rt_list_t *l)
tests whether a list is empty
rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
insert a node before a list
#define rt_list_entry(node, type, member)
get the struct for this entry
#define RT_DEBUG_NOT_IN_INTERRUPT
rt_inline void rt_list_init(rt_list_t *l)
initialize a list
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
insert a node after a list
#define RT_DEBUG_SCHEDULER_AVAILABLE(need_check)
#define RT_DEBUG_IN_THREAD_CONTEXT
rt_err_t rt_thread_suspend_to_list(rt_thread_t thread, rt_list_t *susp_list, int ipc_flags, int suspend_flag)
This function will suspend the specified thread and change it to suspend state.
rt_thread_t rt_thread_self(void)
This function will return self thread object.
struct rt_thread * rt_thread_t
void rt_schedule(void)
This function will perform one scheduling. It will select one thread with the highest priority level ...
rt_err_t rt_event_recv_interruptible(rt_event_t event, rt_uint32_t set, rt_uint8_t option, rt_int32_t timeout, rt_uint32_t *recved)
rt_err_t rt_event_control(rt_event_t event, int cmd, void *arg)
This function will set some extra attributions of an event object.
rt_event_t rt_event_create(const char *name, rt_uint8_t flag)
Creating an event object.
rt_err_t rt_event_detach(rt_event_t event)
This function will detach a static event object.
#define RT_EVENT_FLAG_AND
rt_err_t rt_event_recv(rt_event_t event, rt_uint32_t set, rt_uint8_t option, rt_int32_t timeout, rt_uint32_t *recved)
rt_err_t rt_event_delete(rt_event_t event)
This function will delete an event object and release the memory space.
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
This function will send an event to the event object. If there is a thread suspended on the event,...
rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag)
The function will initialize a static event object.
rt_err_t rt_event_recv_killable(rt_event_t event, rt_uint32_t set, rt_uint8_t option, rt_int32_t timeout, rt_uint32_t *recved)
struct rt_event * rt_event_t
#define RT_EVENT_FLAG_CLEAR
rt_err_t rt_mb_recv_killable(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)
rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg)
This function will set some extra attributions of a mailbox object.
rt_err_t rt_mb_send_wait_killable(rt_mailbox_t mb, rt_ubase_t value, rt_int32_t timeout)
rt_err_t rt_mb_detach(rt_mailbox_t mb)
This function will detach a static mailbox object.
rt_err_t rt_mb_send_killable(rt_mailbox_t mb, rt_ubase_t value)
rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)
rt_err_t rt_mb_delete(rt_mailbox_t mb)
This function will delete a mailbox object and release the memory space.
rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag)
Creating a mailbox object.
rt_err_t rt_mb_recv_interruptible(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout)
struct rt_mailbox * rt_mailbox_t
rt_err_t rt_mb_send_interruptible(rt_mailbox_t mb, rt_ubase_t value)
rt_err_t rt_mb_urgent(rt_mailbox_t mb, rt_ubase_t value)
This function will send an urgent mail to the mailbox object.
rt_err_t rt_mb_init(rt_mailbox_t mb, const char *name, void *msgpool, rt_size_t size, rt_uint8_t flag)
Initialize a static mailbox object.
rt_err_t rt_mb_send(rt_mailbox_t mb, rt_ubase_t value)
This function will send an mail to the mailbox object. If there is a thread suspended on the mailbox,...
rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_ubase_t value, rt_int32_t timeout)
rt_err_t rt_mb_send_wait_interruptible(rt_mailbox_t mb, rt_ubase_t value, rt_int32_t timeout)
rt_err_t rt_mq_send_wait(rt_mq_t mq, const void *buffer, rt_size_t size, rt_int32_t timeout)
rt_err_t rt_mq_detach(rt_mq_t mq)
This function will detach a static messagequeue object.
rt_mq_t rt_mq_create(const char *name, rt_size_t msg_size, rt_size_t max_msgs, rt_uint8_t flag)
Creating a messagequeue object.
rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg)
This function will set some extra attributions of a messagequeue object.
rt_err_t rt_mq_send_wait_killable(rt_mq_t mq, const void *buffer, rt_size_t size, rt_int32_t timeout)
struct rt_messagequeue * rt_mq_t
rt_ssize_t rt_mq_recv_killable(rt_mq_t mq, void *buffer, rt_size_t size, rt_int32_t timeout)
rt_err_t rt_mq_send_killable(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_err_t rt_mq_send_interruptible(rt_mq_t mq, const void *buffer, rt_size_t size)
rt_ssize_t rt_mq_recv_interruptible(rt_mq_t mq, void *buffer, rt_size_t size, rt_int32_t timeout)
rt_err_t rt_mq_init(rt_mq_t mq, const char *name, void *msgpool, rt_size_t msg_size, rt_size_t pool_size, rt_uint8_t flag)
Initialize a static messagequeue object.
rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
This function will send a message to the messagequeue object. If there is a thread suspended on the m...
rt_err_t rt_mq_send_wait_interruptible(rt_mq_t mq, const void *buffer, rt_size_t size, rt_int32_t timeout)
rt_err_t rt_mq_delete(rt_mq_t mq)
This function will delete a messagequeue object and release the memory.
rt_ssize_t rt_mq_recv(rt_mq_t mq, void *buffer, rt_size_t size, rt_int32_t timeout)
rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size)
This function will send an urgent message to the messagequeue object.
rt_err_t rt_mutex_control(rt_mutex_t mutex, int cmd, void *arg)
This function will set some extra attributions of a mutex object.
rt_err_t rt_mutex_take_interruptible(rt_mutex_t mutex, rt_int32_t time)
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
This function will create a mutex object.
rt_err_t rt_mutex_take_killable(rt_mutex_t mutex, rt_int32_t time)
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
rt_err_t rt_mutex_detach(rt_mutex_t mutex)
This function will detach a static mutex object.
rt_uint8_t rt_mutex_setprioceiling(rt_mutex_t mutex, rt_uint8_t priority)
set the prioceiling attribute of the mutex.
rt_err_t rt_mutex_delete(rt_mutex_t mutex)
This function will delete a mutex object and release this memory space.
void rt_mutex_drop_thread(rt_mutex_t mutex, rt_thread_t thread)
drop a thread from the suspend list of mutex
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
Initialize a static mutex object.
rt_err_t rt_mutex_release(rt_mutex_t mutex)
This function will release a mutex. If there is thread suspended on the mutex, the thread will be res...
struct rt_mutex * rt_mutex_t
rt_err_t rt_mutex_trytake(rt_mutex_t mutex)
This function will try to take a mutex, if the mutex is unavailable, the thread returns immediately.
rt_uint8_t rt_mutex_getprioceiling(rt_mutex_t mutex)
set the prioceiling attribute of the mutex.
rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag)
This function will initialize a static semaphore object.
rt_err_t rt_sem_delete(rt_sem_t sem)
This function will delete a semaphore object and release the memory space.
rt_err_t rt_sem_take_killable(rt_sem_t sem, rt_int32_t time)
rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg)
This function will set some extra attributions of a semaphore object.
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)
Creating a semaphore object.
rt_err_t rt_sem_take_interruptible(rt_sem_t sem, rt_int32_t time)
rt_err_t rt_sem_detach(rt_sem_t sem)
This function will detach a static semaphore object.
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)
struct rt_semaphore * rt_sem_t
rt_err_t rt_sem_release(rt_sem_t sem)
This function will release a semaphore. If there is thread suspended on the semaphore,...
rt_err_t rt_sem_trytake(rt_sem_t sem)
This function will try to take a semaphore, if the semaphore is unavailable, the thread returns immed...
#define GET_MESSAGEBYTE_ADDR(msg)
#define RT_MUTEX_HOLD_MAX
#define RT_KERNEL_FREE(ptr)
#define RT_KERNEL_MALLOC(sz)
#define RTM_EXPORT(symbol)
#define RT_SCHED_DEBUG_IS_LOCKED
#define RT_THREAD_LIST_NODE(thread)
#define RT_SCHED_DEBUG_IS_UNLOCKED
#define RT_THREAD_LIST_NODE_ENTRY(node)
rt_ubase_t rt_sched_lock_level_t
unsigned short rt_uint16_t
struct rt_list_node rt_list_t
rt_uint8_t rt_sched_thread_get_curr_prio(struct rt_thread *thread)
rt_uint8_t rt_sched_thread_get_init_prio(struct rt_thread *thread)
rt_err_t rt_sched_thread_change_priority(struct rt_thread *thread, rt_uint8_t priority)
Update priority of the target thread
rt_err_t rt_sched_thread_ready(struct rt_thread *thread)
rt_uint8_t rt_sched_thread_is_suspended(struct rt_thread *thread)
rt_err_t rt_sched_lock(rt_sched_lock_level_t *plvl)
rt_err_t rt_sched_unlock(rt_sched_lock_level_t level)
rt_err_t rt_sched_unlock_n_resched(rt_sched_lock_level_t level)
struct rt_spinlock spinlock
struct rt_ipc_object parent
struct rt_list_node * next
rt_list_t suspend_sender_thread
struct rt_ipc_object parent
struct rt_spinlock spinlock
struct rt_ipc_object parent
rt_list_t suspend_sender_thread
struct rt_spinlock spinlock
struct rt_mq_message * next
struct rt_spinlock spinlock
rt_uint8_t ceiling_priority
struct rt_ipc_object parent
struct rt_spinlock spinlock
struct rt_ipc_object parent
rt_object_t pending_object
RT_SCHED_THREAD_CTX struct rt_timer thread_timer
rt_list_t taken_object_list