📄 jobs.h
字号:
/****************************************************************************
*****************************************************************************
文件名称: JOBS.H
模块名称: 作业管理模块
模块作用:
编写者一:
编写者二:
编写日期:
完成日期:
程序行数: 1100
*****************************************************************************
*****************************************************************************/
/****************************************************************************
模块名称: 预输入模块
函 数 名: M_INPUT_PROCESS (P1)
功 能: 负责用户从键盘键入作业,通过内存,最后存入用户虚拟硬盘(输入井)
入口参数: 无
出口参数: 无
调用关系: 被主模块调用
自身调用READ_LINE_FROM_KEYBOARD_TO_MEMORY读入作业到内存
编 者: 陈俭(AP0006301)
编写日期: 2003-10-5
完成日期: 2003-10-6
*****************************************************************************/
int M_INPUT_PROCESS()
{
/* -----------------------------------------------------------
读入用户的作业到虚拟硬盘中
1.启动CHST[0]通道,从用户键盘中读入10个字符到内存中
2.启动CHST[2]通道,将内存临时缓冲区中10个字符写到硬盘中
3.重复1,2步工作,直到用户作业输入完毕.
如果P1进程的现场保存为1时表示已打开CHST[0]通道,正等待CHST[0],发中断唤醒。
如果P1进程的现场保存为3时表示申请JCB表和申请输入井失败,等待P3发中断唤醒。
如果P1进程的现场保存为5时表示已打开CHST[2]通道,正等待CHST[2],发中断唤醒。
如果P1进程的现场保存为-1时表示。
-------------------------------------------------------------*/
/* 应该设立输入缓冲(系统内存中申请)*/
int type;
char *w;
int continue_i=0,max_i,temp_pc,index_table;
char buf[22];
int i,j,n;
int flag=TRUE;
w = &buf[0];
while(flag)
{
flag = FALSE;
/* PC 十位数是系统输入缓冲区的下标,个位数是上次中断的位置 */
M_SEPARATE_PC_I(PC,&max_i,&continue_i,&temp_pc);
switch(temp_pc)
{
case 0 : FILEOFFSET = 0;
case -1:
if(CHST[0].status == 'B')
{
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,0*10+(1));
M_MALLOC_INTERRUPT(0,SYSTEM_INPUT_PROCESS);
break;
}
case 1:
CHST[0].status = 'B';
if(CHST[0].waits == 0)
CHST[0].time = 3;
M_MALLOC_INTERRUPT(0,SYSTEM_INPUT_PROCESS);
/* 开始将数据从键盘读入到系统存取区的输入井缓冲区中 */
max_i = M_DEAL_KEYBOARD_TO_SYSTEM_MEMORY(INPUT_FILE,&FILEOFFSET,w);
/* 键盘使用计数加1*/
KEYBOARD_TIMES ++;
/* 等待CHST[0]完成发出中断,唤醒P1 */
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max_i*100+2);
/* 显示正在从键盘输入数据 */
M_G_INPUT_FROM_KEYBOARD_TO_SYSTEM_MEMORY();
return(FALSE);
case 2:
{
/* 键盘停止输入数据 */
M_G_KEYBOARD_INPUT_FINISH();
/* 申请打开 CHST[2] 通道 */
if(CHST[2].status == 'B')
{
/* 如果写进输入井的通道处于忙状态,则P1睡眠 */
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max_i*100+0*10+3);
M_MALLOC_INTERRUPT(2,SYSTEM_INPUT_PROCESS);
return(FALSE);
}
case 3:
{
CHST[2].status = 'B';
if(CHST[2].waits == 0)
CHST[2].time = 1;
M_MALLOC_INTERRUPT(2,SYSTEM_INPUT_PROCESS);
}
/* 申请打开通道成功,准备传送数据 case 3 执行传送数据操作*/
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max_i*100+0*10+4);
break;
}
case 4:
{
/* 数据正从系统存储区传送到输入井 */
M_CHANGE_HARDDISK_LIGHT();
LINE_FROM_SYSTEM_MEMORY_TO_INPUT_BUF_INDEX[1] = LINE_FROM_SYSTEM_MEMORY_TO_INPUT_BUF_INDEX[0];
M_G_DISPLAY_DATA_FROM_SYSTEM_BUF_TO_INPUT_BUF(LINE_FROM_SYSTEM_MEMORY_TO_INPUT_BUF_INDEX[1],COLOR2);
/* 通道使用计数加1 */
HARDDISK_TIMES++;
/* 因为启动一个通道可以读入多个字,所以用循环方式处理每个字 */
for(i=continue_i;i<=max_i;i++)
{
type = JUDGE_INSTRUCTION_TYPE(SYSTEM_INPUT_BUF[i]);
switch(type)
{
case JOB:
{
/* 整个作业流的开始 */
break;
}
case BEGIN:
{
/* 先检查是否要帮POE唤醒P2进程*/
if(P_INPUT_PROCESS->p_r == 1)
/* 唤醒P2 */
M_PROCESS_WAKE_UP_BY_NECESSARY(P_JOB_SCHEDUL);
P_INPUT_PROCESS->p_r = 0;
/* 先检查是否存在空的作业表 */
if(M_CHECK_WHETHER_HAVE_SPACE_IN_HARDDISK() == FALSE)
{
/* 申请JCB表失败,输入井全部被占用,P1睡眠等待P3唤醒 */
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max_i*100+i*10+3);
return(FALSE);
}
/* 如果是BEGIN语句 ,填写当前作业的信息*/
/* 当前作业占用作业表的序号 */
/*M_TAKE_UP_JOB_TABLE(index_table);*/
J_TEMP_JOB = (JCB*)malloc(sizeof(JCB));
/*J_TEMP_JOB->j_index = index_table;*/
J_TEMP_JOB->j_hd_table[0] = -1;
if(M_MALLOC_SPACE_FOR_JOB_FROM_HARDDISK(J_TEMP_JOB) == FALSE)
{
free(J_TEMP_JOB);
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,max_i*100+i*10+3);
return(FALSE);
}
J_TEMP_JOB->j_p_start = HDWPOINTER;
J_TEMP_JOB->j_length = 0;
J_TEMP_JOB->j_loaded_length = 0;
J_TEMP_JOB->j_color = M_G_MALLOC_COLOR();
GET_JOB_ATTRIBUTE(&SYSTEM_INPUT_BUF[i][0],J_TEMP_JOB->j_name,J_TEMP_JOB->j_runtime,J_TEMP_JOB->j_output_line);
break;
}
case POB:
{
/* 每一作业的程序段开始 */
J_TEMP_JOB->j_p_start = J_TEMP_JOB->j_length;
P_INPUT_PROCESS->p_c = 'P';
break;
}
case DATA:
{
/* 每一作业的数据段开始 */
J_TEMP_JOB->j_d_start = J_TEMP_JOB->j_length;
P_INPUT_PROCESS->p_c = 'D';
break;
}
case DOE:
{
/* 如果是数据段结束语句,刷新当前作业的信息 */
J_TEMP_JOB->j_d_end = J_TEMP_JOB->j_length;
J_TEMP_JOB->j_length = (J_TEMP_JOB->j_p_end - J_TEMP_JOB->j_p_start)+ (J_TEMP_JOB->j_d_end - J_TEMP_JOB->j_d_start);
/* 该作业的输入已完成,将作业挂入作业后备队列中,由于POE已经进行该操作了,所以这里不用,只是更新其数即可。*/
/* 唤醒P2 */
M_PROCESS_WAKE_UP_BY_NECESSARY(P_JOB_SCHEDUL);
P_INPUT_PROCESS->p_r = 0; /* 0 表示该进程已经唤醒P2。*/
break;
}
case POE:
{
/* 如果是程序段结束语句 ,刷新当前作业的信息*/
J_TEMP_JOB->j_p_end = J_TEMP_JOB->j_length;
J_TEMP_JOB->j_d_start = J_TEMP_JOB->j_length;
J_TEMP_JOB->j_d_end = J_TEMP_JOB->j_length;
J_TEMP_JOB->j_length = (J_TEMP_JOB->j_p_end - J_TEMP_JOB->j_p_start)+ (J_TEMP_JOB->j_d_end - J_TEMP_JOB->j_d_start);
/* 该作业的输入已完成,将作业挂入作业后备队列中 */
M_JION_JOB_TO_J_INPUT_JOB(J_TEMP_JOB);
/* 暂时不唤醒P2 */
P_INPUT_PROCESS->p_r = 1; /* 1 表示该进程可能要唤醒P2,还但未确定是否存在数据段时,还不能确定。*/
break;
}
case JOE:
{
/* 先检查是否要帮POE唤醒P2进程*/
if(P_INPUT_PROCESS->p_r == 1)
/* 唤醒P2 */
M_PROCESS_WAKE_UP_BY_NECESSARY(P_JOB_SCHEDUL);
P_INPUT_PROCESS->p_r = 0;
M_G_DISPLAY_OR_CLEAN_SYSTEM_MEMORY(3,0);
/* 传送结束,擦除传送的线条 */
M_G_DISPLAY_DATA_FROM_SYSTEM_BUF_TO_INPUT_BUF(LINE_FROM_SYSTEM_MEMORY_TO_INPUT_BUF_INDEX[1],0);
/* 如果是整个作业流结束语句,撤消P1 */
M_SET_SYSTEM_PROCESS_STATUS(RUNNING_QUEUE->p_next,Destory);
M_CLOSE_JOB_FILE();
return(FALSE);
}
default :
{
if(P_INPUT_PROCESS->p_c == 'D')
n = GET_DATA(SYSTEM_INPUT_BUF[i],&buf[0],&buf[5]);
else
n = 1;
for(j=0;j<n;j++)
{
/* 程序指令语句或数据语句,将数据写入在输入进中。*/
J_TEMP_JOB->j_length++;
J_TEMP_JOB->j_loaded_length++;
if(J_TEMP_JOB->j_length > 100)
/* 超过一个作业的最大长度,即超过100字 */
{
/* 该作业出错,撤消该作业,同时重置作业表状态,释放JCB结点。*/
free(J_TEMP_JOB);
/* 此处还不完善 */
break;
}
/* 现假设作业不会超过100字 */
/* 判断是否需要再申请一块磁空间 */
if(M_NECESSARY_MALLOC_NEW_HARDDISK_SPACE(J_TEMP_JOB) == TRUE)
{
M_MALLOC_SPACE_FOR_JOB_FROM_HARDDISK(J_TEMP_JOB);
}
/* 转换绝对地址 */
M_CHANGE_POSITION_OF_LENGTH_TO_POSITION_OF_HARDDISK(J_TEMP_JOB);
if(P_INPUT_PROCESS->p_c == 'P')
{
/* 用户作业程序代码 */
HD[HDWPOINTER][0] = SYSTEM_INPUT_BUF[i][1];
HD[HDWPOINTER][1] = SYSTEM_INPUT_BUF[i][2];
HD[HDWPOINTER][2] = SYSTEM_INPUT_BUF[i][3];
HD[HDWPOINTER][3] = SYSTEM_INPUT_BUF[i][4];
}
else
{
/* 用户作业数据代码 */
/* 将数据写入内存区中,每写入一个数据后,内存写指针后移一个单元*/
HD[HDWPOINTER][0]=buf[j*5+0];
HD[HDWPOINTER][1]=buf[j*5+1];
HD[HDWPOINTER][2]=buf[j*5+2];
HD[HDWPOINTER][3]=buf[j*5+3];
}
M_G_DISPLAY_OR_CLEAN_INPUT_BUF(HDWPOINTER/10,J_TEMP_JOB->j_color);
}
}
}/* end of switch */
} /* end of for */
/* 释放系统输入缓存 */
M_INIT_SYSTEM_INPUT_BUF();
M_CHANGE_HARDDISK_LIGHT();
/* 判断是否全部写入输入缓存结束。 */
if(i == max_i + 1)
{
/* 将数据从系统存取区的输入井缓冲存进输入井 */
M_G_DISPLAY_OR_CLEAN_SYSTEM_MEMORY(3,0);
/* 传送结束,擦除传送的线条 */
M_G_DISPLAY_DATA_FROM_SYSTEM_BUF_TO_INPUT_BUF(LINE_FROM_SYSTEM_MEMORY_TO_INPUT_BUF_INDEX[1],0);
/* P1睡眠等待CHST[2]中断唤醒P1 */
M_PROCESS_SLEEP_SETTING(RUNNING_QUEUE->p_next,-1);
M_SET_SYSTEM_PROCESS_STATUS(P_INPUT_PROCESS,Ready);
flag = TRUE;
break;
}
}
}/* end of switch */
}/* end of while */
}
/****************************************************************************
模块名称: 预输入模块
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -