rt-thread的IPC机制之事件源码分析(二)

2014-11-24 07:52:34 · 作者: · 浏览: 1
st_resume_all(&(event->parent.suspend_thread));//唤醒所有因此事件而挂起的线程
/* detach event object */
rt_object_detach(&(event->parent.parent));//脱离事件的内核对象
return RT_EOK;
}
3.4 删除事件
[cpp]
/**
* This function will delete an event object and release the memory
*
* @param event the event object
*
* @return the error code
*/
rt_err_t rt_event_delete(rt_event_t event)
{
/* parameter check */
RT_ASSERT(event != RT_NULL);
RT_DEBUG_NOT_IN_INTERRUPT;//确保此函数不是在ISR中使用
/* resume all suspended thread */
rt_ipc_list_resume_all(&(event->parent.suspend_thread));//唤醒所有因此事件而挂起的线程
/* delete event object */
rt_object_delete(&(event->parent.parent));//删除事件的内核对象
return RT_EOK;
}
3.5 发送事件
[cpp]
/**
* This function will send an event to the event object, if there are threads
* suspended on event object, it will be waked up.
*
* @param event the event object
* @param set the event set
*
* @return the error code
*/
rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
{
struct rt_list_node *n;
struct rt_thread *thread;
register rt_ubase_t level;
register rt_base_t status;
rt_bool_t need_schedule;
/* parameter check */
RT_ASSERT(event != RT_NULL);
if (set == 0)//无任何事件,则直接返回
return -RT_ERROR;
need_schedule = RT_FALSE;//需要调度标志初始化为不需要
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(event->parent.parent)));
/* disable interrupt */
level = rt_hw_interrupt_disable();//关中断
/* set event */
event->set |= set;//事件的接收事件集或上发送的事件,即在事件控制块内保存接收到的事件
if (!rt_list_isempty(&event->parent.suspend_thread))//如果事件的挂起线程链表不为空
{
/* search thread list to resume thread */
n = event->parent.suspend_thread.next;//遍历所有挂起的线程
while (n != &(event->parent.suspend_thread))
{
/* get thread */
thread = rt_list_entry(n, struct rt_thread, tlist);//得到挂起的线程控制块
status = -RT_ERROR;
if (thread->event_info & RT_EVENT_FLAG_AND)//如果此挂起的线程为事件过滤方式为逻辑与
{
if ((thread->event_set & event->set) == thread->event_set)//即判断所有事件是否者触发
{
/* received an AND event */
status = RT_EOK;
}
}
else if (thread->event_info & RT_EVENT_FLAG_OR)//事件过滤方式为逻辑或
{
if (thread->event_set & event->set)//判断是否触发任一关心的事件
{
/* save recieved event set */
thread->event_set = thread->event_set & event->set;//将接收到的事件保存到线程中
/* received an OR event */
status = RT_EOK;
}
}
/* move node to the next */
n = n->next;//指向下一挂起的线程
/* condition is satisfied, resume thread */
if (status == RT_EOK)//符合唤醒条件
{
/* clear event */
if (thread->event_info & RT_EVENT_FLAG_CLEAR)//是否需要清除接收到的事件
event->set &= ~thread->event_set;//清除接收到的事件
/* resume thread, and thread list breaks out */
rt_thread_resume(thread);//唤醒此线程
/* need do