www.pudn.com > Mos.rar > Mos_proc.cpp


// Mos_proc.cpp: implementation of the CMos_proc class. 
// Wrote by Wang Hao. Released March,2002. 
// Copyright (C) 2002 by Wang Hao. 
// All rights reserved. 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Mos.h" 
#include "Mos_proc.h" 
#include "Mos_io.h" 
#include "Mos_stor.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
extern PCB m_pcb; 
extern JCB m_jcb; 
extern CVCS m_cpu; 
extern CMos_io m_io; 
extern CMos_stor m_stor; 
CMos_proc::CMos_proc() 
{ 
 
} 
 
CMos_proc::~CMos_proc() 
{ 
 
} 
 
void CMos_proc::creat(pcbtype *p,jcbtype* pJ) 
//仅由jsw调用执行 
//仅用作创建用户进程。创建系统进程不在此列,另作处理 
//前提:PCB、内存已申请成功 
{	 
	p->errn = 0; 
	p->io = 0; 
	p->next = NULL; 
	p->mode = USERMODE; 
	p->flag = READY; 
	p->resultline = 0; 
	p->regc = '0';//初始化寄存器 
	p->regpc[0] = p->regpc[1] = '0'; 
	p->jcb = pJ; 
	p->cputime = 0;//time 
	for(int i = 0;i<=3;i++) 
		p->regr[i] = '0'; 
/////////////////////////////////////////初始化PCB////////////////////// 
	rearrange(p,m_pcb.readypcbhead,m_pcb.readypcbtail,p->mode,IDC_STATIC_CP);	//将p挂入就绪队列 
} 
 
void CMos_proc::halt(int e) 
{ 
////////////////////////////////////////////////////////回收内存//////// 
	int m=m_pcb.curr_pcb->regptr[1]-0x30+2;//memory:op2 
	int allocmem=(m_pcb.curr_pcb->regptr[2]-0x30)*10+m_pcb.curr_pcb->regptr[3]-0x30; 
	memtype* p=&m_stor.MEMTB[allocmem]; 
	m_stor.mem_free(m,p); 
	if(m_stor.MEMFRC==30) m_UI.UpdateListAll(IDC_LIST1); 
	else for(int i=0;i<(m-1)*11;i++) 
			m_UI.UpdateList(IDC_LIST1); 
	if(m_pcb.waitmem_head!=NULL) wakeup(MEMFULL); 
/////////////////////////////////////////////////////////填JCB////////// 
	m_cpu.time = 0;//用户进程撤销,time置零 
	m_pcb.curr_pcb->jcb->jc = m_cpu.C; 
	m_pcb.curr_pcb->jcb->jpc[0] = m_cpu.PC[0]; 
	m_pcb.curr_pcb->jcb->jpc[1] = m_cpu.PC[1]; 
	for(m=0;m<=3;m++) 
		m_pcb.curr_pcb->jcb->jr[m] =m_cpu.R[m]; 
	m_pcb.curr_pcb->jcb->jio = m_pcb.curr_pcb->io; 
	m_pcb.curr_pcb->jcb->resultline = m_pcb.curr_pcb->resultline; 
	m_pcb.curr_pcb->jcb->jcputime = m_pcb.curr_pcb->cputime; 
	m_pcb.curr_pcb->jcb->error = e; 
	if(e>0){ 
		int addr; 
		addr=(m_cpu.PC[1]-0x30)*10+m_cpu.PC[0]-0x30; 
		m_pcb.curr_pcb->jcb->eraddr = addr; 
	} 
///////////////////////////////将当前进程挂入自由队列<=>回收PCB表/////// 
	rearrange(m_pcb.curr_pcb,m_pcb.pcb_free_head,m_pcb.pcb_free_tail,0); 
	m_pcb.free_pcb_count++; 
	CString str; 
	str.Format("%d",PCBMAX-m_pcb.free_pcb_count); 
	m_UI.DealWithUI(str,IDC_STATIC_PN); 
	if(m_pcb.waitpcb_head!=NULL) wakeup(PCBFULL); 
/////////////////////////////////////////////////挂入输出作业队列/////// 
	if(m_jcb.out_head == NULL) 
	{ 
		m_jcb.out_head = m_jcb.out_tail = m_pcb.curr_pcb->jcb; 
		m_pcb.curr_pcb->jcb->jnext = NULL; 
	} 
	else{ 
			m_jcb.out_tail->jnext = m_pcb.curr_pcb->jcb; 
			m_jcb.out_tail = m_jcb.out_tail->jnext; 
			m_pcb.curr_pcb->jcb->jnext = NULL; 
	} 
	m_pcb.curr_pcb = NULL; 
	m_UI.DealWithUIEx(NULL,IDC_STATIC_CP); 
	if(m_pcb.waitout_head!=NULL) wakeup(OUTNULL); 
} 
 
void CMos_proc::sleep(int reason) 
{ 
	switch(reason)//挂睡眠队列 
	{ 
	case 1:rearrange(m_pcb.curr_pcb, 
			         m_pcb.restkb_head, 
					 m_pcb.restkb_tail,m_pcb.curr_pcb->mode,IDC_STATIC_RKB);break;//IORESTKB 
	case 2:rearrange(m_pcb.curr_pcb, 
			         m_pcb.restprt_head, 
					 m_pcb.restprt_tail,m_pcb.curr_pcb->mode,IDC_STATIC_RPRT);break;//IORESTPRT 
	case 3:rearrange(m_pcb.curr_pcb, 
			         m_pcb.restdsk_head, 
					 m_pcb.restdsk_tail,m_pcb.curr_pcb->mode,IDC_STATIC_RDSK);break;//IORESTDSK	 
	case 4:m_pcb.waitpcb_head = m_pcb.curr_pcb; 
		   m_UI.DealWithUIEx(m_pcb.waitpcb_head,IDC_STATIC_WPCB);break;//PCBFULL 
	case 5:m_pcb.waitjcb_head = m_pcb.curr_pcb; 
		   m_UI.DealWithUIEx(m_pcb.waitjcb_head,IDC_STATIC_WJCB);break;//JCBFULL 
	case 6:m_pcb.waitout_head = m_pcb.curr_pcb; 
		   m_UI.DealWithUIEx(m_pcb.waitout_head,IDC_STATIC_WOUT);break;//OUTNULL	 
	case 7:m_pcb.waitmem_head = m_pcb.curr_pcb; 
		   m_UI.DealWithUIEx(m_pcb.waitmem_head,IDC_STATIC_WMEM);break;//MEMFULL 
	case 8:rearrange(m_pcb.curr_pcb, 
			         m_pcb.dsk_head, 
					 m_pcb.dsk_tail,m_pcb.curr_pcb->mode,IDC_STATIC_WDSK);break;//DSKFULL 
	case 9:m_pcb.kbend_head = m_pcb.curr_pcb; 
		   m_UI.DealWithUIEx(m_pcb.kbend_head,IDC_STATIC_WJOB); 
		   break;//KBEND 
	case 10:m_pcb.jcbnull_head = m_pcb.curr_pcb; 
		    m_UI.DealWithUIEx(m_pcb.jcbnull_head,IDC_STATIC_WRJ); 
		    break;//JCBNULL 
	default:break; 
	} 
	if(m_pcb.curr_pcb->mode == USERMODE) 
	{ 
		m_pcb.curr_pcb ->regc = m_cpu.C;//保存现场 
		m_pcb.curr_pcb->regpc[0] = m_cpu.PC[0]; 
		m_pcb.curr_pcb->regpc[1] = m_cpu.PC[1]; 
		for(int i=0;i<=3;i++) 
			m_pcb.curr_pcb->regr[i] =m_cpu.R[i]; 
	} 
	m_pcb.curr_pcb->flag = SLEEP; 
	m_pcb.curr_pcb = NULL;//相当关键的一个处理! 
	m_UI.DealWithUIEx(NULL,IDC_STATIC_CP); 
} 
 
void CMos_proc::wakeup(int reason, int chno) 
{ 
	pcbtype* p = NULL; 
	CString str; 
	switch(reason)//取队首进程 
	{ 
	case 1:p =GetQueueHead(m_pcb.restkb_head,m_pcb.restkb_tail,IDC_STATIC_RKB); 
		   p->iorbp = NULL; 
		   break; 
	case 2:p =GetQueueHead(m_pcb.restprt_head,m_pcb.restprt_tail,IDC_STATIC_RPRT); 
		   p->iorbp = NULL; 
		   break; 
	case 3:p =GetQueueHead(m_pcb.restdsk_head,m_pcb.restdsk_tail,IDC_STATIC_RDSK); 
		   p->iorbp = NULL; 
		   break; 
	case 4:p = m_pcb.waitpcb_head; 
		   m_pcb.waitpcb_head = NULL; 
		   m_UI.DealWithUIEx(NULL,IDC_STATIC_WPCB); 
		   break;//PCBFULL 
	case 5:p = m_pcb.waitjcb_head; 
		   m_pcb.waitjcb_head = NULL; 
		   m_UI.DealWithUIEx(NULL,IDC_STATIC_WJCB); 
		   break;//JCBFULL 
	case 6:p = m_pcb.waitout_head; 
		   m_pcb.waitout_head = NULL; 
		   m_UI.DealWithUIEx(NULL,IDC_STATIC_WOUT); 
		   break;//OUTNULL 
	case 7:p = m_pcb.waitmem_head; 
		   m_pcb.waitmem_head = NULL; 
		   m_UI.DealWithUIEx(NULL,IDC_STATIC_WMEM); 
		   break;//MEMFULL 
	case 8:p =GetQueueHead(m_pcb.dsk_head,m_pcb.dsk_tail,IDC_STATIC_WDSK); 
		   break; 
	case 9:p = m_pcb.kbend_head; 
		   m_pcb.kbend_head = NULL; 
		   m_UI.DealWithUIEx(NULL,IDC_STATIC_WJOB); 
		   break;//KBEND 
	case 10:p = m_pcb.jcbnull_head; 
		    m_pcb.jcbnull_head = NULL; 
		    m_UI.DealWithUIEx(NULL,IDC_STATIC_WRJ); 
	default:break; 
	} 
	if(chno > 0&&m_io.CHHEAD[chno-1]!=NULL) 
	{ 
		m_cpu.CHST[chno-1] = BUSY; 
		if(chno < 3) 
			m_cpu.CHCOUNT[chno-1] = 3; 
		else m_cpu.CHCOUNT[chno-1] = 1; 
		str.Format("%d",m_cpu.CHCOUNT[chno-1]); 
		m_UI.DealWithUI(str,IDC_STATIC_IOKB-chno+KB); 
	} 
	p->flag = READY; 
	rearrange(p,m_pcb.readypcbhead,m_pcb.readypcbtail,p->mode,IDC_STATIC_RP); 
	//挂入就绪队列 
} 
 
void CMos_proc::rearrange(pcbtype* &p, pcbtype* &head, pcbtype* &tail, int tag,int ID) 
{ 
	if(head == NULL){ 
		head = tail = p; 
		p->next = NULL; 
	} 
	else{ 
			if(tag == 0){//user mode 
				tail->next = p; 
				tail = tail->next; 
				p->next = NULL; 
			} 
			else if(tag == 1){ 
				p->next = head; 
				head = p; 
			} 
	} 
	if(ID!=0) 
		m_UI.DealWithUIEx(head,ID); 
} 
 
pcbtype* CMos_proc::GetQueueHead(pcbtype* &queuehead,pcbtype* &queuetail,int ID) 
{ 
	pcbtype* p = NULL; 
	if(queuehead!=NULL){ 
		p=queuehead; 
		if(queuehead->next==NULL) 
			queuehead=queuetail=NULL; 
		else queuehead=queuehead->next; 
		p->next = NULL; 
	} 
	if(ID!=0) 
		m_UI.DealWithUIEx(queuehead,ID); 
	return p; 
}