(3)当前消息未满,但是当前没有等待队列,那么根据要求把消息压入循环队列,函数返回;
(4)当前消息未满,且存在等待队列,说明此时已经没有消息可读,
a)如果需要唤醒所有的等待线程,那么唤醒所有的线程,等待线程总数置为0;
b)如果只是唤起某一个线程,那么唤醒第一个等待线程,等待线程总数自减;
(5)调用系统调度函数,防止有高优先级的线程加入调度队列;
(6)线程再次得到运行的机会,函数返回。
看到上面的代码,我们发现只要梳理好了代码的逻辑,其实消息发送函数也是比较好理解的。当然,有消息的发送,就必然会存在消息的接受了。此时肯定也会出现没有消息、有消息两种情况了。
RAW_U16 raw_queue_receive (RAW_QUEUE *p_q, RAW_U32 wait_option, RAW_VOID **msg) { RAW_VOID *pmsg; RAW_U16 result; LIST *block_list_head; RAW_TASK_OBJ *blocked_send_task; RAW_SR_ALLOC(); #if (RAW_QUEUE_FUNCTION_CHECK > 0) if (raw_int_nesting) { return RAW_NOT_CALLED_BY_ISR; } if (p_q == 0) { return RAW_NULL_OBJECT; } if (msg == 0) { return RAW_NULL_POINTER; } #endif block_list_head = &p_q->common_block_obj.block_list; RAW_CRITICAL_ENTER(); /*if queue has msgs, just receive it*/ if (p_q->msg_q.current_numbers) { pmsg = *p_q->msg_q.read++; if (p_q->msg_q.read == p_q->msg_q.queue_end) { p_q->msg_q.read = p_q->msg_q.queue_start; } *msg = pmsg; /*if there are blocked_send_tasks, just reload the task msg to end*/ if (p_q->msg_q.blocked_send_task_numbers) { blocked_send_task = list_entry(block_list_head->next, RAW_TASK_OBJ, task_list); p_q->msg_q.blocked_send_task_numbers--; *p_q->msg_q.write++ = blocked_send_task->msg; if (p_q->msg_q.write == p_q->msg_q.queue_end) { p_q->msg_q.write = p_q->msg_q.queue_start; } raw_wake_object(blocked_send_task); RAW_CRITICAL_EXIT(); raw_sched(); return RAW_SUCCESS; } p_q->msg_q.current_numbers--; RAW_CRITICAL_EXIT(); return RAW_SUCCESS; } if (wait_option == RAW_NO_WAIT) { /* Caller wants to block if not available? */ *msg = (RAW_VOID *)0; RAW_CRITICAL_EXIT(); return RAW_NO_PEND_WAIT; } if (raw_sched_lock) { RAW_CRITICAL_EXIT(); return RAW_SCHED_DISABLE; } raw_pend_object(&p_q->common_block_obj, raw_task_active, wait_option); p_q->msg_q.blocked_receive_task_numbers++; RAW_CRITICAL_EXIT(); raw_sched(); RAW_CRITICAL_ENTER(); *msg = (RAW_VOID *)0; result = block_state_post_process(raw_task_active, msg); RAW_CRITICAL_EXIT(); return result; } |