第25章 实现进程间通信(IPC)

目标:实现系统调用

int send_msg(int pid, struct msg *msg);

int receive_msg(struct msg *msg);

消息结构如下所示:

#define TASK_MSG_NR    10
struct msg{
    int pid;        //消息的发送者
    int type;
    int size;
    union{
    char c;
    int i;
    long l;
    void *p;
    }x;
};

struct msgbox{
    unsigned long msg_nr;  //信箱中有多少条信息
    int msg_start;
    int msg_end;
    struct msg box[TASK_MSG_NR];  //循环数组
};

#define DEFAULT_STACK_SIZE  4096
struct task_struct{
    struct tss_struct    tss;
    unsigned long long tss_descriptor;
    unsigned long long ldt_descriptor;
    unsigned long long ldt[2];
    unsigned int task_function;
    void * stack0;
    void * stack3;
    unsigned int stack0_size;
    unsigned int stack3_size;
    int state;
    int priority;
    int time_slice;
    int pid;
    int ppid;
    struct task_struct *next, *prev;
    struct task_struct *hnext, *hprev;
    struct prio_array *py;
    struct timer timer;
    struct msgbox msgbox;
};

发送消息函数和接收消息函数如下所示

int sys_send_msg(int pid, struct msg *msg)
{
    
    int ret = 0;
    struct task_struct *task = NULL;

    cli();
    if(pid < 0 || !msg)
    {
      ret = 1;
      goto end;
    }
    
    //查询是否存在这个pid的任务
    task = query_task_from_hash(pid);
    if(!task)
    {
      ret = 2;
      goto end;
    }

    //查看任务的信箱是否有空位
    if(task->msgbox.msg_nr < TASK_MSG_NR) //有空位
    {
      //复制消息到任务的信箱的空位中
      task->msgbox.msg_end = ++(task->msgbox.msg_end)%TASK_MSG_NR;
      task->msgbox.box[task->msgbox.msg_end] = *msg;

      //消息数目增1
      ++(task->msgbox.msg_nr); 
    }
    else //无空位
    {
      ret = 3;
      goto end;
    }
end:
    sti();
    return ret;
}


int sys_receive_msg(struct msg *msg)
{
    int ret = 0;

    cli();
    if(!msg)
    {
      ret = 1;
      goto end;
    }

    //查看任务的信箱是否有消息
    if(current->msgbox.msg_nr > 0) //有消息
    {
      //复制任务信箱中的消息到msg中
      current->msgbox.msg_start = ++(current->msgbox.msg_start)%TASK_MSG_NR;
      *msg =     current->msgbox.box[current->msgbox.msg_start];

      //消息数目减1
      --(current->msgbox.msg_nr); 
    }
    else //无消息
    {
      ret = 2;
      goto end;
    }
end:
    sti();
    return ret;
}

Leave a Reply

Your email address will not be published. Required fields are marked *