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

📄 jobs.h

📁 该模块包括作业调度的三个系统进程。P1、P2、P3进程功能的实现。 P1负责对用户作业预输入处理
💻 H
📖 第 1 页 / 共 4 页
字号:
函 数 名:  M_LOAD_JOB_FROM_HARDDISK_TO_MEMORY   (P2)
功    能:  负责从输入井调作业到用户存储区
入口参数:  无
出口参数:  无
调用关系:  被主模块调用
编    者:  陈俭(AP0006301)
编写日期:  2003-10-5
完成日期:  2003-10-6
*****************************************************************************/
M_LOAD_JOB_FROM_HARDDISK_TO_MEMORY()
{
    int need_page,i,current_page;
    int flag = TRUE;
    while(flag)
    {
        flag = FALSE;
        /* 如果 J_INPUT_JOB_HEAD = J_INPUT_JOB_TAIL 则表示无后备作业 */
        if(J_INPUT_JOB_HEAD == J_INPUT_JOB_TAIL)
        {
            /* P1 还没有销毁 */
            if(P_INPUT_PROCESS->p_status != Destory)
            {
                M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                return(FALSE);
            }
            else
            {
                /* 如果P1已经销毁,则P2也应该销毁,因为不存在后备作业,同时用户已不存输入作业了 */
                M_SET_SYSTEM_PROCESS_STATUS(RUNNING_QUEUE->p_next,Destory);
                return(FALSE);
            }
        }
        else if(J_INPUT_JOB_HEAD->j_next == J_INPUT_JOB_TAIL && P_INPUT_PROCESS->p_r == 1)
        {
            /* 上一个作业刚刚读入完成,但还可能存在数据段,且作业后备队列中只有一个该作业 */
                M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                return(FALSE);
        }
        switch(PC)
        {
            /* 为新作业申请用户内存区 */
            case 0 :
            case -1:
                {
                    /* 计算该作业需要占用几个内存页 */
                    if(J_INPUT_JOB_HEAD->j_next->j_length % 10 == 0)
                        need_page = J_INPUT_JOB_HEAD->j_next->j_length / 10;
                    else
                        need_page = J_INPUT_JOB_HEAD->j_next->j_length / 10 + 1;
                    /* 在当前内存页表中查找,是否存在足够的空闲的内存空间 */
                    if(M_GET_MEMORY_FREE_TABLE() < need_page )
                    {
                        /* 没有足够的内存空间来装入该作业 ,P2 睡眠,等待用户作业使用 H 释放资源*/
                        M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                        return(FALSE);
                    }
                    /* 如果存在足够的内存空间,修改内存页表状态,和该作业的页表 */
                    M_MALLOC_MEMORY_TABLE(need_page);
                    /* 申请内存成功后,将数据从输入井装入到内存中,,,直接引用下面的程序执行,所以此处不用break语句 */
                    /* 置已装入内存的数据长度为 0 */
                    J_INPUT_JOB_HEAD->j_next->j_loaded_length = 0;
                }
            /* 打开CHST[2],并从输入井读入数据到用户内存区 */
            case 1:
                {
                    
                    if(CHST[2].status == 'B')
                    {
                        /* 通道还处于忙状态,睡眠等待通道唤醒 */
                        M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,2);
                        M_MALLOC_INTERRUPT(2,SYSTEM_JOB_SCHEDUL);
                        return(FALSE);
                    }
            case 2:
                    /* 置当前通道忙状态 */
                    CHST[2].status = 'B';
                    CHST[2].time = 1;
                    M_MALLOC_INTERRUPT(2,SYSTEM_JOB_SCHEDUL);
                    M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,3);

                    break;
                }
            case 3:
                {
                    M_CHANGE_HARDDISK_LIGHT();
                    /* 显示数据从输入井到用户存储区 */
                    M_GET_JOB_CURRENT_HARDDISK_INDEX_AND_MEMORY_INDEX(1,&LINE_FROM_INPUT_BUF_TO_USERBUF[0],&LINE_FROM_INPUT_BUF_TO_USERBUF[1]);
                    M_G_DISPLAY_DATA_FROM_INPUT_BUF_TO_USER_MEMORY(LINE_FROM_INPUT_BUF_TO_USERBUF[0],LINE_FROM_INPUT_BUF_TO_USERBUF[1],COLOR3);
                    M_G_DISPLAY_OR_CLEAN_DATA_TAKEN_USERBUF(LINE_FROM_INPUT_BUF_TO_USERBUF[1],J_INPUT_JOB_HEAD->j_next->j_color);
                    /* 通道空闲,则利用通道装入作业数据 */
                    for(i=0;i<10 && J_INPUT_JOB_HEAD->j_next->j_loaded_length < J_INPUT_JOB_HEAD->j_next->j_length;i++)
                    {
                        J_INPUT_JOB_HEAD->j_next->j_loaded_length++;
                        current_page = J_INPUT_JOB_HEAD->j_next->j_loaded_length /10;
                        if(J_INPUT_JOB_HEAD->j_next->j_loaded_length % 10 == 0)
                            current_page = current_page;
                        else
                            current_page++;
                        /* 将作业的当前页转换成内存的页 */
                        current_page = J_INPUT_JOB_HEAD->j_next->j_job_table[current_page - 1];
                        /* current_page已指向当前内存的目标页 */
                        /* 转换硬盘的绝对读写地址 */
                        M_CHANGE_POSITION_OF_LENGTH_TO_POSITION_OF_HARDDISK(J_INPUT_JOB_HEAD->j_next);
                        /* 下面装入一个字到内存用户区中 */
                        /*MM[(current_page)*10 + i][0] = HD[J_INPUT_JOB_HEAD->j_next->j_index * 100 + (J_INPUT_JOB_HEAD->j_next->j_loaded_length - 1)][0]; */
                        MM[(current_page)*10 + i][0] = HD[HDWPOINTER][0];
                        MM[(current_page)*10 + i][1] = HD[HDWPOINTER][1];
                        MM[(current_page)*10 + i][2] = HD[HDWPOINTER][2];
                        MM[(current_page)*10 + i][3] = HD[HDWPOINTER][3];
                    }
                    M_CHANGE_HARDDISK_LIGHT();
                    M_G_DISPLAY_DATA_FROM_INPUT_BUF_TO_USER_MEMORY(LINE_FROM_INPUT_BUF_TO_USERBUF[0],LINE_FROM_INPUT_BUF_TO_USERBUF[1],0);
                    /* 如果作业已经全部装入,则为该作业建立PCB块,并将其加入用户作业的就绪队列中 */
                    if(J_INPUT_JOB_HEAD->j_next->j_loaded_length == J_INPUT_JOB_HEAD->j_next->j_length)
                    {
                        /* 清空该作业占用的输入井 */
                        M_CLEAR_HARDDISK_JOB_HAD_TAKEN(J_INPUT_JOB_HEAD->j_next);
                        /* 显示创建进程控制块 */
                        M_G_BUILD_PCB_AND_JOIN_IN_READY_QUEUE(J_INPUT_JOB_HEAD->j_next->j_job_table[0],J_INPUT_JOB_HEAD->j_next->j_color);
                        M_BUILD_JOB_PCB_AND_JOIN_INTO_READY_QUEUE();
                        M_G_DISPLAY_READY_QUEUE();
                        M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                        M_SET_SYSTEM_PROCESS_STATUS(P_JOB_SCHEDUL,Ready);
                        flag = TRUE;
                        continue;
                    }
                    /* 如果该作业读入还未完成,则继续 */
                    M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,1);
                    M_SET_SYSTEM_PROCESS_STATUS(P_JOB_SCHEDUL,Ready);
                    flag = TRUE;
                }
        }/* end of switch */
    }/* end of while */
}


/****************************************************************************
模块名称:  预输入模块
函 数 名:  M_OUTPUT_PROCESS   (P3)
功    能:  负责从输入井调作业到用户存储区
入口参数:  无
出口参数:  无
调用关系:  被主模块调用
编    者:  陈俭(AP0006301)
编写日期:  2003-10-5
完成日期:  2003-10-6
*****************************************************************************/
M_OUTPUT_PROCESS()
{
    JCB *deletejcb;
    int i,max,temp_pc;
    int flag = TRUE;
    char buf[5];
    while(flag)
    {
        flag = FALSE;
        /* 不存在缓输出的作业 */
        if(J_OUTPUT_JOB_HEAD == J_OUTPUT_JOB_TAIL)
        {
            /* 如果P1P2同时已撤消 */
            if(M_CHECK_SYSTEM_PROCESS_STATUS(P_INPUT_PROCESS) == Destory && M_CHECK_SYSTEM_PROCESS_STATUS(P_JOB_SCHEDUL) == Destory)
            {
                /* 如果也不存在用户进程 */
                if(READY_QUEUE->p_tick <= 0 && RUNNING_QUEUE->p_next->p_id < 0)
                {
                    /* P3销毁 */
                    M_SET_SYSTEM_PROCESS_STATUS(RUNNING_QUEUE->p_next,Destory);
                    M_G_DISPLAY_SYSTEM_PROCESS();
                    /* 打印系统各种数据 */
                    M_PRINT_SYSTEM_ENVIRONMENT();
                    /* 退出操作系统,系统关机 */
                    return(FALSE);
                }
                else
                {
                    /* 存在用户进程 */
                    M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                    return(FALSE);
                }
            }
            else
            {
                M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
                return(FALSE);
            }
        }
        /* 存在缓输出的作业 */
        M_SEPARATE_PC_I(PC,&max,&i,&temp_pc);
        switch(temp_pc)
        {
            case 0 :
            case -1:
                {
                    /* 申请打开 CHST[2] 通道 */
                    if(CHST[2].status == 'B')
                    {
                        /* 如果写进输入井的通道处于忙状态,则P1睡眠 */
                        M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,1);
                        M_MALLOC_INTERRUPT(2,SYSTEM_OUTPUT_PROCESS);
                        return(FALSE);
                    }
            case 1:
                
                    CHST[2].status = 'B';
                    if(CHST[2].waits == 0)
                        CHST[2].time = 1;
                    M_MALLOC_INTERRUPT(2,SYSTEM_OUTPUT_PROCESS);
                    /* 申请打开通道成功,准备传送数据 case 1 执行传送数据操作*/
                    M_CHANGE_HARDDISK_LIGHT();
                    M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,2);
                    M_G_DISPLAY_OR_CLEAN_DATA_FROM_OUTPUT_BUF_TO_SYSTEM_BUF(COLOR5);
                    M_G_DISPLAY_OR_CLEAN_SYSTEM_MEMORY(0,yellow_color);
                    break;
                }
            case 2:
                {
                    /* 通道使用计数加1 */
                    HARDDISK_TIMES++;
                    /* 将数据写入系统存取区的输出井缓冲 */
                    for(i=0;i<10 && J_OUTPUT_JOB_HEAD->j_next->j_loaded_length < J_OUTPUT_JOB_HEAD->j_next->j_length; J_OUTPUT_JOB_HEAD->j_next->j_loaded_length++,i++)
                    {
                        SYSTEM_OUTPUT_BUF[i][0] = J_OUTPUT_JOB_HEAD->j_next->j_print[i][0];
                        SYSTEM_OUTPUT_BUF[i][1] = J_OUTPUT_JOB_HEAD->j_next->j_print[i][1];
                        SYSTEM_OUTPUT_BUF[i][2] = J_OUTPUT_JOB_HEAD->j_next->j_print[i][2];
                        SYSTEM_OUTPUT_BUF[i][3] = J_OUTPUT_JOB_HEAD->j_next->j_print[i][3];
                    }
                    i--;
                    if(i<0)
                    {
                        i = 0;
                        max = 1;
                    }
                    else
                        max = 0;
                    M_CHANGE_HARDDISK_LIGHT();
                    M_G_DISPLAY_OR_CLEAN_DATA_FROM_OUTPUT_BUF_TO_SYSTEM_BUF(0);
                    /* 申请打开 CHST[1] 通道 */
                    if(CHST[1].status == 'B')
                    {
                        /* 如果写进输入井的通道处于忙状态,则P1睡眠 */
                        M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,3);
                        M_MALLOC_INTERRUPT(1,SYSTEM_OUTPUT_PROCESS);
                        return(FALSE);
                    }
            case 3:
                    CHST[1].status = 'B';
                    if(CHST[1].waits == 0)
                        CHST[1].time = 3;
                    M_MALLOC_INTERRUPT(1,SYSTEM_OUTPUT_PROCESS);
                    /* 执行打印操作是下面的case 3: */
                    M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max*100+i*10+5);
                    M_G_DISPLAY_OR_CLEAN_DATA_FROM_SYSTEM_BUF_TO_PRINTER(COLOR6);
                    break;
                }
            case 5:
                {
                    /* 打印机通道使用计数加1 */
                    PRINTER_TIMES++;
                    if(max ==0)
                    {
                        /* 模拟打印机的功能,打印出数据 */
                        for(max=0;max<=i;max++)
                        {
                            buf[0] = SYSTEM_OUTPUT_BUF[max][0];
                            buf[1] = SYSTEM_OUTPUT_BUF[max][1];
                            buf[2] = SYSTEM_OUTPUT_BUF[max][2];
                            buf[3] = SYSTEM_OUTPUT_BUF[max][3];
                            buf[4] = '\0';
                            /* 打印出数据 */
                            M_PRINT_ONE_LINE_OF_JOB_RESULT(&buf[0],0);
                        }
                    }
                    /* 从缓输出作业队列中删除该作业 */
                    deletejcb = J_OUTPUT_JOB_HEAD->j_next;
                    /* 缓输出队列是不是最后一个作业 */
                    if(deletejcb == J_OUTPUT_JOB_TAIL)
                    {
                        /* 是 */
                        J_OUTPUT_JOB_TAIL = J_OUTPUT_JOB_HEAD;

⌨️ 快捷键说明

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