• 基于DOS的多任务系统的实现

    基于DOS的多任务系统的实现 #include<stdio.h> #include<stdlib.h> #include <time.h> #include<dos.h> /*定义TCB状态*/ #define FINISHED 0 #define RUNNING 1 #define READY 2 #define BLOCKED 3 #define NTCB 5 /*定义最大空闲TCB个数*/ #define TC 2 /*定义时间片长度*/ #define NBUF 6 /*定义缓冲区大小*/ #define GET_INDOS 0x34 #define GET_CRIT_ERR 0x5d06 struct TCB{ unsigned char *stack; /*线程堆栈起始地址*/ unsigned ss; /*堆栈段址*/ unsigned sp; /*堆栈指针*/ char state; /*线程状态*/ char name[15]; /*线程外部标识符*/ struct TCB *next; }tcb[NTCB]; /*初始化堆栈时使用*/ struct int_regs{ unsigned bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags, off, seg; }; char fpub[3]; int current= -1; /*定义一个当前TCB下标的全局变量*/ int timecount = 0; /*定义时间片*/ char far *indos_ptr = 0; /*该指针变量存放INDOS表示的地址*/ char far *crit_err_ptr = 0; /*该指针变量存放严重错误标志的地址*/ void interrupt (*old_int8)(void);/*旧的时钟中断处理程序*/ typedef int (far *codeptr)(void); /*定义了一个函数指针类型*/ int buffer[NBUF] = {-1,-1,-1,-1,-1,-1}; /*生产者消费者中的缓冲区*/ int in = 0; int out = 0; typedef struct{ int value; struct TCB *wq; }semaphore; semaphore mutex={1,NULL},empty={NBUF,NULL},full={0,NULL},Mutex2={1,NULL}; /*生产者消费者中的信号量*/ void InitDos(void) { union REGS regs; struct SREGS segregs; regs.h.ah = GET_INDOS; intdosx(&regs,&regs,&segregs); indos_ptr = MK_FP(segregs.es,regs.x.bx); if(_osmajor<3) crit_err_ptr = indos_ptr+1; else if(_osmajor==3 && _osminor==0) crit_err_ptr = indos_ptr-1; else{ regs.x.ax = GET_CRIT_ERR; intdosx(&regs,&regs,&segregs); crit_err_ptr = MK_FP(segregs.ds,regs.x.si); } } int DosBusy(void) { if(indos_ptr && crit_err_ptr) return (*indos_ptr || *crit_err_ptr); else return -1; } int finished(void) { int i; for(i=1; i<NTCB; i++) if(tcb[i].state != FINISHED) return 0; return 1; } int Seeknext() { int i,ks; i=current+1; ks=0; disable(); while(ks<NTCB) { if(tcb[i].state==READY) { return i; } i++; ks++; i=i%NTCB; } printf("Seeknext tcb is error!!\n"); enable(); } void interrupt my_swtch(void) { disable();/*开中断*/ /*保护正在执行的线程current的现场,暂停它的执行*/ tcb[current].ss=_SS; tcb[current].sp=_SP; if(tcb[current].state==RUNNING) tcb[current].state=READY; /*找到新的就绪线程i*/ current=Seeknext(); tcb[current].state=RUNNING; /*切换堆栈,恢复线程i的现场,把CPU分派给它*/ _SS=tcb[current].ss; _SP=tcb[current].sp; /*重新开始计时*/ timecount=0; enable();/*关中断*/ } void interrupt new_int8(void) { /*调用原来的时钟中断服务程序*/ (*old_int8)(); /*进行计时*/ timecount++; /*当前线程的时间片到否*/ if(timecount >= TC) if(!DosBusy()) { /*调用my_swtch进行重新调度*/ my_swtch(); } } void Destroy(int i) { if(tcb[i].state==RUNNING) { disable(); tcb[i].state=FINISHED; free(tcb[i].stack); enable(); } return; } void over(void) { Destroy(current); printf("%s is finished!\n", tcb[current].name); my_swtch(); } void tcb_state() { int i; printf("These are the information of all threads: \n"); for(i=0;i<NTCB-1;i++) { printf("the key word of the thread is : %d\n the name of thread is : %s\n the state of the thread is ",i,tcb[i].name); switch(tcb[i].state) { case (1): printf("Running \n");break; case (2): printf("Ready \n");break; case (3): printf("Blocked\n");break; case (0): printf("Finished\n");break; } } } /*创建线程*/ int create(char *name, codeptr code, int stacklen) { int i = 0; struct int_regs *temp; while(tcb[i].state != FINISHED) /*查找空闲TCB块*/ i++; if(i == NTCB) return -1; /*没有空闲TCB块可用*/ strcpy(tcb[i].name, name); tcb[i].state = READY; tcb[i].stack = (unsigned char*)malloc(stacklen); /*为新线程分配私有堆栈空间*/ tcb[i].stack = tcb[i].stack + stacklen; /*初始化新线程的私有堆栈*/ temp = (struct int_regs *)tcb[i].stack-1; temp->ds = _DS; temp->es = _ES; temp->flags = 0x200; temp->ip = FP_OFF(code); temp->cs = FP_SEG(code); temp->off = FP_OFF(over); /*将over函数压入堆栈,线程结束自动执行*/ temp->seg = FP_SEG(over); tcb[i].ss = FP_SEG(temp); tcb[i].sp = FP_OFF(temp); return i; } void block(semaphore *sem) { struct TCB *p; disable(); tcb[current].state = BLOCKED; p = sem->wq; if(p == NULL){ sem->wq = &tcb[current]; } else{ while(p->next != NULL) p = p->next ; p->next = &tcb[current]; } tcb[current].next = NULL; my_swtch(); enable(); } void wakeup(semaphore *sem) { struct TCB *p; disable(); p = sem->wq; if(p != NULL){ p->state = READY; sem->wq = sem->wq->next; } enable(); } void wait(semaphore *sem) { disable(); sem->value = sem->value - 1; if(sem->value < 0) { printf("\nthe thread of %s is blocked\n",tcb[current].name); block(sem); } enable(); } void signal(semaphore *sem) { disable(); sem->value = sem->value + 1; if(sem->value <= 0) wakeup(sem); enable(); } void proceducer() { int i, j, k; for(i = 1; i <=13;i++){ wait(&empty); wait(&mutex); buffer[in] = i*i; printf("%s puts a number of %d in the buffer \n",tcb[current].name, buffer[in]); /*for(j=0; j<10000; j++) for(k=0; k<10000; k++);*/ in = (in +1) % NBUF; signal(&mutex); signal(&full); } } void consumer() { int i, j, k; for(i = 1; i<=7;i++){ wait(&full); wait(&mutex); printf("consumer gets the number of %d from the buffer\n", buffer[out]); buffer[out] = -1; /*for(j=0; j<1000; j++) for(k=0; k<10000; k++);*/ out = (out+1) % NBUF; signal(&mutex); signal(&empty); } } void f1() { int i,j,k; wait(&Mutex2); strcpy(fpub,"f1"); signal(&Mutex2); for(i=1;i<=22;i++) { wait(&Mutex2); printf("%s is running !\n",fpub); signal(&Mutex2); for(j=0;j<10000;j++) for(k=0;k<10000;k++); } } void f2() { int i,j,k; wait(&Mutex2); /*做放入数的操作*/ strcpy(fpub,"f2"); signal(&Mutex2); for(i=1;i<=33;i++) { wait(&Mutex2); printf("%s is running !\n",fpub); signal(&Mutex2); for(j=0;j<10000;j++) for(k=0;k<10000;k++); } } void InitTcb()/*TCB的初始化*/ { int i; for(i=0;i<NTCB;i++) { tcb[i].state=FINISHED; tcb[i].name[0]='\0'; tcb[i].next=NULL; } } int main(void) { InitDos(); InitTcb(); old_int8 = getvect(8); strcpy(tcb[0].name, "main"); tcb[0].state = RUNNING; current = 0 ; create("proceducerOne", (codeptr)proceducer, 1024); create("consumer", (codeptr)consumer, 1024); /*create("proceducerTwo", (codeptr)proceducer, 1024); create("f1",(codeptr)f1,1024); create("f2",(codeptr)f2,1024);*/ tcb_state(NTCB); setvect(8, new_int8); my_swtch(); while(!finished()) ; strcpy(tcb[0].name, "\0"); tcb[0].state = FINISHED; setvect(8, old_int8); printf("\n"); tcb_state(NTCB); printf("\nMulti_task system terminated.\n"); getchar(); return 0; }

    0
    118
    7KB
    2011-11-20
    11
关注 私信
上传资源赚积分or赚钱