⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 barber.c

📁 介绍ROCK OS操作系统.一般用于汽车电子,类似OCVX.里面是个DEMO文档,内附说明.
💻 C
字号:
/******************************************************************************
    Copyright (c) 2006 by RockOS.
    All rights reserved.

    This software is supported by the Rock Software Workroom only.

    Any bugs please contact the author with e-mail or QQ:
     E-mail : baobaoba520@yahoo.com.cn
         QQ : 59681888
*******************************************************************************
File name   : barber.c
Description : A classical IPC issue - barber's room
            : 
            : 
Auther      : sunxinqiu
History     :
  2006-03-15   first release.
******************************************************************************/
#include "os.h"

#define BARBERS 5    /* 提供服务的理发师数 */
#define CHAIRS  10   /* 为等候的顾客准备的椅子数. */

#define HAIRCUT_DURATION    5  /* 每个顾客的理发时长. */

HSEMA barbers;      /* 理发店的理发师数. */

HSEMA mutex;        /* 用于互斥. */
HSEMA customers;    /* 等候服务的顾客数. */
int waiting;        /* 等候服务的顾客数. */

enum
{
    WAITING      = 1,  /* 顾客在椅子上等待理发 */
    HAIRCUTTING  = 2,  /* 正在理发中         */
    HAIRCUT_OVER = 3   /* 理好了, 满意地离去  */
};

HQUEUE   hCustomQueue;
volatile int CustomerState[MAX_SYS_TASK];

int customer_come (int argc, char * argv[]);
void barber(void * p);
void customer(void * p);
void cut_hair (int employeeId, int customerId);
void get_haircut(void);

/* 为每个理发师创建一个任务. */
STATUS app_entry()
{
    int i;
    TASK_INFO taskInfo;

    hCustomQueue = q_create(OS_QUEUE_FIFO, CHAIRS, NULL_TASK, "customer queue");

    customers = semCreate(OS_SEMA_SYNC, 0, "waiting customers count");
    barbers = semCreate(OS_SEMA_SYNC, BARBERS, "barbers count");
    mutex = semCreate(OS_SEMA_MUTEX, 1, "waiting mutex");
    
    for (i = 0; i < BARBERS; i++)
    {
        taskInfo.priority = 10;
        sprintf(&taskInfo.name[0], "barber%d", i);
        taskInfo.taskEntry = barber;
        taskInfo.pData = (void*)i;
        taskInfo.msgQSize = 0;
        taskInfo.semaQSize = DEFAULT_MUTEX_Q_SIZE;
        taskInfo.stackSize = TICK_TASK_STACK_SIZE;
        taskInfo.option = OPT_TASK_DEFAULT;
        taskCreate(&taskInfo);
    }

    /* 在shell命令行执行"c"命令, 理发店里就来一个顾客 */
    regShellCmd(customer_come, "c", "Classic IPC: in barbers");

    return OS_SUCCESS;
}

/* 创建顾客任务, 由用户在Shell上输入"c"命令激活 */
int customer_come (int argc, char * argv[])
{
    TASK_INFO taskInfo;

    if (getTaskCount() >= MAX_SYS_TASK)
    {
        OS_printf("customer over flow.\n");
        return 0;
    }

    taskInfo.priority = 10;
    sprintf(&taskInfo.name[0], "customer");
    taskInfo.taskEntry = customer;
    taskInfo.pData = (void*)0;
    taskInfo.msgQSize = 0;
    taskInfo.semaQSize = DEFAULT_MUTEX_Q_SIZE;
    taskInfo.stackSize = TICK_TASK_STACK_SIZE;
    taskInfo.option = OPT_TASK_DEFAULT;
    taskCreate(&taskInfo);
    
    return MAX_SYS_TASK - getTaskCount();  /* 返回空闲的任务数, 如果空闲任务数为0, 就不能再加顾客了. */
}

/* 理发师的行为 */
void barber(void * p)
{
    int employeeId;
    int customerId;
    
    employeeId = (int)p;
    while(1)
    {
        semTake(customers, OS_WAIT_FOR_EVER);     /* 如果顾客数是0, 则睡觉 */
        semTake(mutex, OS_WAIT_FOR_EVER);         /* 要求进程等候         */
        waiting --;             /* 等候的顾客数减一     */
        q_enum(hCustomQueue, (HANDLE *)&customerId);  /* 该理发了 */
        CustomerState[customerId] = HAIRCUTTING;
        semGive(barbers);         /* 理发师现在开始理发了  */
        semGive(mutex);           /* 释放等候            */
        
        cut_hair(employeeId, customerId);   /* 理发, (非临界区操作) */
        OS_printf("Barber [%d]: Well, the next one.....\n", taskIdSelf());
    }
}

/* 顾客的行为, 只需要一次理发, 所以不需要循环 */
void customer(void * p)
{
    int customerId;

    (void)p;

    customerId = taskIdSelf();
    semTake(mutex, OS_WAIT_FOR_EVER);        /* 进入临界区 */
    
    if (waiting < CHAIRS)   /* 如果没有空的椅子, 就离开 */
    {
        waiting++;          /* 等候的顾客数加一        */
        CustomerState[customerId] = WAITING;
        q_add(hCustomQueue, customerId, 0);   /* 坐上椅子 */
        semGive(customers);   /* 如果必要的话,唤醒理发师  */
        semGive(mutex);       /* 释放访问等候           */
        semTake(barbers, OS_WAIT_FOR_EVER);     /* 如果理发师数为0, 就睡觉 */
        get_haircut();        /* 坐下等候服务           */
    }
    else
    {
        semGive(mutex);       /* 店里人满了, 走吧 */
        OS_printf("\nTNND, so many peoples, let\'s go.\n");
    }
}

/* 理发师正在理发. */
void cut_hair (int employeeId, int customerId)
{
    int duration;
    
    duration = HAIRCUT_DURATION;
    
    while (duration > 0)
    {
        /* 理发师在工作时, 每秒打印一次. */
        OS_printf("Barber [%d]: cutting hair for Custom [%d].....[%d] left.\n",
                    taskIdSelf(), customerId, duration);
        taskDelay(sec2Tick(1));
        duration--;
    }

    /* 理好了 */
    CustomerState[customerId] = HAIRCUT_OVER;
    OS_printf("Barber [%d]: cutting hair completed.\n", taskIdSelf());
}

void get_haircut()
{
    while(CustomerState[taskIdSelf()] != HAIRCUT_OVER)  /* 等待理发结束. */
    {
        taskDelay(sec2Tick(1));
    }
    
    OS_printf("Customer [%d]: Thanks, it\'s fine\n", taskIdSelf());  /* 理好了, 该走了. */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -