Lenix消息机制源代码分析

对象定义及操作接口
typedef struct _msg_slot_t
{
    uint32_t                ms_pid;                         /*  发送进程id              */
    uint32_t                ms_type;                        /*  消息类型                */
    dword_t                 ms_param32;                     /*  32位消息参数            */
    qword_t                 ms_param64;                     /*  64位消息参数            */
}msg_slot_t;

typedef struct _message_t
{
    char                    msg_name[32];                   /*  消息对象名称            */
    lock_t                  msg_lock;
    proc_t              *   msg_send_wait;
    proc_t              *   msg_resv_wait;
    int                     msg_count;
    msg_slot_t          *   msg_buffer;
    int                     msg_send;
    int                     msg_resv;
}message_t;

#define MSG_MAX                     24

#define MSG_GLOBAL_LOCK()           Lck_lock(&msg_lock)
#define MSG_GLOBAL_FREE()           Lck_free(&msg_lock)

#define MSG_LOCK(msg)               Lck_lock(&((msg)->msg_lock))
#define MSG_FREE(msg)               Lck_free(&((msg)->msg_lock))

#define MSG_IS_FULL(msg)            ((((msg)->msg_send + 1) % (msg)->msg_count) == (msg)->msg_resv )
#define MSG_IS_EMPTY(msg)           ((((msg)->msg_resv + 1) % (msg)->msg_count) == (msg)->msg_send )
#define MSG_IS_VALID(msg)           ((msg)->msg_buffer)
#define MSG_SEND_FORWARD(msg)       do{ (msg)->msg_send = ((msg)->msg_send + 1) % (msg)->msg_count; }while(0)
#define MSG_RESV_FORWARD(msg)       do{ (msg)->msg_resv = ((msg)->msg_resv + 1) % (msg)->msg_count; }while(0)

void        Msg_initial(void);
message_t * Msg_create(const char * name,msg_slot_t * ms,int count);
message_t * Msg_get(const char * name);
result_t    Msg_destroy(message_t * msg);
result_t    Msg_send(message_t * msg,uint32_t type,dword_t param32,qword_t param64);
result_t    Msg_post(message_t * msg,uint32_t type,dword_t param32,qword_t param64);
result_t    Msg_resv(message_t * msg ,msg_slot_t * ms);

实现代码

static lock_t               msg_lock;
static message_t            msg_pool[MSG_MAX];

void        Msg_initial(void)
{
    memset(msg_pool,0,sizeof(message_t)*MSG_MAX);
    msg_lock = 0;
}

message_t * Msg_create(const char * name,msg_slot_t * ms,int count)
{
    int i;
    message_t   *   msg;
    
    msg = NULL;
    MSG_GLOBAL_LOCK();
    
    for( i = 0 ; i < MSG_MAX ; i++)
    {
        if( msg_pool[i].msg_buffer )
            continue;
        msg = msg_pool + i;
        msg->msg_buffer = (void *)-1;
        break;
    }
    
    MSG_GLOBAL_FREE();
    
    if( NULL == msg )
        return NULL;
        
    strcpy(msg->msg_name,name);
    msg->msg_lock       = 0;
    msg->msg_send_wait  = NULL;
    msg->msg_resv_wait  = NULL;
    msg->msg_buffer     = ms;
    msg->msg_count      = count;
    msg->msg_send       = 0;
    msg->msg_resv       = count - 1;
    
    return msg;
}

message_t * Msg_get(const char * name)
{
    int i;
    message_t   *   msg;
    
    msg = NULL;
    
    MSG_GLOBAL_LOCK();
    for( i = 0 ; i < MSG_MAX ; i++)
    {
        if( !MSG_IS_VALID(msg_pool + i))
            continue;
            
        if( strcmp(name,msg_pool[i].msg_name) == 0 )
        {
            msg = msg_pool + i;
            break;
        }
    }
    MSG_GLOBAL_FREE();
    
    return msg;
}

result_t    Msg_destroy(message_t * msg)
{
    MSG_GLOBAL_LOCK();
    
    MSG_LOCK(msg);
    
    msg->msg_buffer     = NULL;
    msg->msg_name[0]    = 0;
    
    Proc_wakeup_on(&msg->msg_send_wait);
    
    MSG_FREE(msg);
    
    MSG_GLOBAL_FREE();
    
    return RESULT_SUCCEED;
}

result_t    Msg_send(message_t * msg,uint32_t type,dword_t param32,qword_t param64)
{
    msg_slot_t *    ms;
    
    if( !MSG_IS_VALID(msg))
        return -1;
        
    MSG_LOCK(msg);
    
    while( MSG_IS_FULL(msg) )
    {
        MSG_FREE(msg);
        
        Proc_sleep_on(&msg->msg_send_wait); /*  缓冲区满,睡眠等待                  */
        
        if( !MSG_IS_VALID(msg))             /*  睡眠过后,消息对象可能已经销毁      */
            return -1;
        
        MSG_LOCK(msg);
    }
    
    ms = msg->msg_buffer + msg->msg_send;
    
    ms->ms_pid      = proc_current->proc_pid;
    ms->ms_type     = type;
    ms->ms_param32  = param32;
    ms->ms_param64  = param64;
    
    MSG_SEND_FORWARD(msg);
    
    MSG_FREE(msg);
    
    Proc_wakeup_on(&msg->msg_resv_wait);
    
    return RESULT_SUCCEED;
}

result_t    Msg_post(message_t * msg,uint32_t type,dword_t param32,qword_t param64)
{
    msg_slot_t *    ms;
    
    if( !MSG_IS_VALID(msg))
        return -1;
        
    MSG_LOCK(msg);
    
    if( MSG_IS_FULL(msg) )          /*  缓冲区满,丢弃消息返回  */
    {
        MSG_FREE(msg);
        
        return -1;        
    }
    
    ms = msg->msg_buffer + msg->msg_send;
    
    ms->ms_pid      = proc_current->proc_pid;
    ms->ms_type     = type;
    ms->ms_param32  = param32;
    ms->ms_param64  = param64;
    
    MSG_SEND_FORWARD(msg);
    
    MSG_FREE(msg);
    
    Proc_wakeup_on(&msg->msg_resv_wait);
    
    return RESULT_SUCCEED;
}

result_t    Msg_resv(message_t * msg ,msg_slot_t * ms)
{

    MSG_LOCK(msg);
    
    while( MSG_IS_EMPTY(msg) )
    {
        MSG_FREE(msg);
        Proc_sleep_on(&msg->msg_resv_wait);
        MSG_LOCK(msg);
    }
    
    MSG_RESV_FORWARD(msg);
    
    *ms = *(msg->msg_buffer + msg->msg_resv);
    
    MSG_FREE(msg);
    
    Proc_wakeup_on(&msg->msg_send_wait);
    
    return RESULT_SUCCEED;
}


测试代码

msg_slot_t                  ms_pool[16];
message_t               *   msg;


int     send1(void)
{
    int    i;
    
    message_t   *   msg;
    qword_t         p64;
    msg = Msg_get("msg");
    
    if( NULL == msg)
    {
        printf("can not found message box\n");
        return 1;
    }
    
    i = 0;
    
    while( i < 16 )
    {
        Clk_delay(20);
        if( RESULT_SUCCEED != Msg_send(msg,i*i,i,p64) )
            break;
        printf("send1 send msg\n");
        i++;
    }
    return 0;
}


int     send2(void)
{
    int    i;
    
    message_t   *   msg;
    qword_t         p64;

    msg = Msg_get("msg");
    
    if( NULL == msg)
    {
        printf("can not found message box\n");
        return 1;
    }
    
    i = 0;
    
    while( i < 16 )
    {
        Clk_delay(30);
        if( RESULT_SUCCEED != Msg_send(msg,i*i,i,p64) )    
            break;
        printf("send2 send msg\n");
        i++;
    }
    
    return 0;
}

int     resv(void)
{
    int i;
    msg_slot_t      ms;
    msg = Msg_create("msg",ms_pool,4);
    
    if( NULL == msg )
    {
        printf("can not create message\n");
        return -1;
    }
    
    Proc_create("send1",send1,0,MAKE_STACK(stack2,STACK_SIZE));
    Proc_create("send2",send2,0,MAKE_STACK(stack3,STACK_SIZE));

    i = 0;
    while( i < 8 )  
    {
        Msg_resv(msg,&ms);
        
        printf("resv data.from pid: %ld msg type: %8ld param32: %8ld\n",ms.ms_pid,ms.ms_type,ms.ms_param32);
        
        if( 0 == (i % 3) )
            Clk_delay(100);
        
        i++;
    }
    
    Msg_destroy(msg);
    printf("resv process end\n");
    return 0;
}



void main(void)
{
    Disable_irq();
    
    Machine_initial();
    
    Proc_initial();
    Clk_initial();
    Msg_initial();
    
    Enable_irq();
    
    Proc_create("message test",resv,0,MAKE_STACK(stack1,STACK_SIZE));
    
    for(;;)
    {
        Cpu_hlt();
    }
    
}

 

测试结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值