嵌入式操作系统内核原理和开发(消息队列)

发表于:2012-9-27 09:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:feixiaoxing    来源:51Testing软件测试网采编

  (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;
   
  }
 

43/4<1234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号