求指点迷津,帮忙找个错误,关于os的。

yyqyyqlove2 2010-12-10 10:14:49
#include <dos.h>
#include <alloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*#include "indos.c"
#include "exterr.c"*/

#define GET_INDOS 0X34
#define GET_GRIT_ERR 0X5D06

#define NTCB 5
#define NTEXT 20
#define NBUF 5
/*#define TL 3*/

/* state code */
/* null 0 not assigned */
#define FINISHED 0
#define RUNNING 1
#define READY 2
#define BLOCKED 3

int i1,i2,i3;


unsigned oldss,oldsp;
static int current=0; /* the tcb index of the current process */
int multstop=1;
int timecount=0;
int TL;
int n =0;
int buf1;

char far *indos_ptr = 0 ;
char far *crit_err_ptr = 0 ;
/* the pointer to the process's code */
typedef int (far *codeptr)(void);


typedef struct{
int value;
struct TCB *wq;
} semaphore;

semaphore mutexfb={1,NULL};/* buf[] is a critical resource */
semaphore sfb={NBUF,NULL};/* buf[] */
semaphore sa={1,NULL},sb={0,NULL};
semaphore mutex={1,NULL};
semaphore f1turn={1,NULL};
semaphore f2turn={0,NULL};


struct buffer {
int id;
int size;
char text[NTEXT];
struct buffer *next;
} buf[NBUF],*freebuf;

struct TCB {
int id; /* unique process id */
char name[10]; /* process's name given by user

*/
unsigned char *stack; /* the beginning address of the stack */
unsigned sp,ss;

char state; /* the state of process */
unsigned *chan; /* event process is awainting */
struct buffer *mq;
semaphore mutex;
semaphore sm;
struct TCB *next; /* link pointer */
} tcb[NTCB] ;


/* the registers pushed in the stack after entering an interrupt

funtion */


/*头文件的这个数据结构修改成这样 */
struct int_regs {
unsigned bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags,off,seg;
};

/*struct {
char name[10];
codeptr code;
}table[NTCB]={"f1",f1;
"f2",f2;
"f3",f3;
"f4",f4;
};
*/
void interrupt (*old_int8)(void);
void interrupt new_int8(void);
int create(char *name,codeptr code,int stck);
void destroy(int id);
void over(void);
void interrupt swtch(void);
int all_finished(void);
void free_all(void);
void tcb_state(void);
void InitTcb(void);

int DosBusy(void)
{
if(indos_ptr && crit_err_ptr)
return (*indos_ptr||*crit_err_ptr);
else
return(-1);
}/*用于判断当前DOS是否处于繁忙状态*/

void InitInDos()
{
union REGS regs;
struct SREGS segregs;
regs.h.ah=GET_INDOS; /*使用34H号系统功能调用*/
intdosx(®s,®s,&segregs);
indos_ptr=MK_FP(segregs.es,regs.x.bx);
if(_osmajor<3)
crit_err_ptr=indos_ptr+1; /*严重错误在INDOS后一字

节处*/
else if(_osmajor==3&&_osmajor==0)
crit_err_ptr=indos_ptr-1; /*严重错误在INDOS前一字

节处*/
else
{
regs.x.ax=GET_GRIT_ERR;
intdosx(®s,®s,&segregs);
crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
}
}/*初始化DOS,取得INDOS标志和严重错误标志地址*/

void InitTcb(void)
{
int i;
for(i=0;i<NTCB;i++){
tcb[i].stack=NULL;
tcb[i].state=FINISHED;
tcb[i].chan=NULL;
tcb[i].name[0]='\0';
tcb[i].next=NULL;
tcb[i].mq=NULL;
tcb[i].mutex.value=1;
tcb[i].mutex.wq=NULL;
tcb[i].sm.value=0;
tcb[i].sm.wq=NULL;
}
}


int create(char *name,codeptr code,int stck)
{
struct int_regs far *r;
int i,id=-1;
unsigned char *ptr;

for(i=0;i<NTCB;i++){
if(tcb[i].state==0){
id=i;
break;
}
}
if(id==-1) return(0);

disable();

tcb[id].stack=(unsigned char *)malloc(stck);
r=(struct int_regs *)(tcb[i].stack+stck-1);
r--;
tcb[id].ss=FP_SEG(r);
tcb[id].sp=FP_OFF(r);
r->cs=FP_SEG(code);
r->ip=FP_OFF(code);
r->ds=_DS;
r->es=_DS;
r->flags=0x200;
r->seg=FP_SEG(over);
r->off=FP_OFF(over);
tcb[id].state=READY;
for(i=0;i<10;i++,name++){
if((tcb[id].name[i]=*name)==NULL)
break;
}
tcb[id].name[9]='\0';

enable();
return(1);
}

void destroy(int id)
{
disable();

free(tcb[id].stack);
tcb[id].stack=NULL;
tcb[id].state=FINISHED;

tcb[id].name[0]='\0';

enable();

}

void over(void)
{
destroy(current);
swtch();
}

void block(unsigned *chan,struct TCB **qp)
{
int id;
struct TCB *tcbp;

id=current;
tcb[id].state=BLOCKED;
tcb[id].chan=chan;

if((*qp)==NULL) (*qp)=&tcb[id];
else {
tcbp=*qp;
while(tcbp->next!=NULL) tcbp=tcbp->next;
tcbp->next=&tcb[id];
}

tcb[id].next=NULL;
swtch();
}

void wakeup_first(struct TCB **qp)
{
int i;
struct TCB *tcbp;

if((*qp)==NULL) return;

tcbp=(*qp);
(*qp)=(*qp)->next;
tcbp->state=READY;
tcbp->chan=NULL;
tcbp->next=NULL;
}

void p(semaphore *sem)
{
struct TCB **qp;

disable();
sem->value=sem->value-1;
if(sem->value<0){
qp=&(sem->wq);
block((unsigned *)sem,qp);
}
enable();
}

void v(semaphore *sem)
{
struct TCB **qp;
disable();
qp=&(sem->wq);
sem->value=sem->value+1;
if(sem->value<=0)
wakeup_first(qp);

enable();
}


void interrupt swtch(void)
{
int loop=0;

disable();

/* save the old process */
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;

/* find a new process and restore it */
if(++current==NTCB) current=0;
while(tcb[current].state!=READY && loop++<NTCB-1){
current++;
if(current==NTCB) current=0;
}
if(tcb[current].state!=READY) current=0;


_SS=tcb[current].ss;
_SP=tcb[current].sp;
tcb[current].state=RUNNING;
timecount=0;
/* tcb_state();*/

enable();
}

int all_finished(void)
{
int i;

for(i=1;i<NTCB;i++)
if(tcb[i].state!=FINISHED) return(0);
return(1);
}

void free_all(void)
{
int i;

for(i=0;i<NTCB;i++){
if(tcb[i].stack){
tcb[i].name[0]='\0';
tcb[i].state=FINISHED;
free(tcb[i].stack);
tcb[i].stack=NULL;
}
}
}

void interrupt new_int8(void)
{
int loop=0;

(*old_int8)();
if(++timecount<TL) return;
if(DosBusy()) return;

disable();

tcb[current].ss=_SS;
tcb[current].sp=_SP;

if(tcb[current].state==RUNNING)
tcb[current].state=READY;

/* find a new process and restore it */
if(++current==NTCB) current=1;
while(tcb[current].state!=READY && ++loop<NTCB-1){
current++;
if(current==NTCB) current=1;
}
if(tcb[current].state!=READY) current=0;

_SS=tcb[current].ss;
_SP=tcb[current].sp;
tcb[current].state=RUNNING;
timecount=0;
/* tcb_state();*/

enable();
}

void tcb_state(void)
{
int i;
/*
if(!multstop) return;
*/

printf("\n");
for(i=0;i<NTCB;i++){
printf("proc %d(%9s): ",i,tcb[i].name);
switch(tcb[i].state){
case READY:printf("READY\n");break;
case RUNNING:printf("RUNNING\n"); break;
case FINISHED:printf("FINISHED\n"); break;
case BLOCKED:printf("BLOCKED\n"); break;
}
}
}

void init_buf(void)
{
int i;
for(i=0;i<NBUF-1;i++)
buf[i].next=&buf[i+1];
buf[i].next=NULL;
freebuf=&buf[0];
}

struct buffer *getbuf(void)
{
struct buffer *buff;
buff=freebuf;
freebuf=freebuf->next;
return(buff);
}




void f1(void)
{
while(i1<=10)
{
p(&f1turn);
p(&mutex);
printf("a thread f1 done now i1=%d \n",i1);
i1++;
v(&mutex);
v(&f2turn);
}
}



void f2(void)
{
while(i2<=10)
{
p(&f2turn);
p(&mutex);
printf("b thread f2 done now i2=%d \n",i2);
v(&mutex);
v(&f1turn);
i2++;
}
}


void main(void)
{
i1=1;
i2=1;
{
create("f1",(codeptr)f1,1024);
create("f2",(codeptr)f2,1024);
clrscr();
f1();
f2();
printf("\n\n\n\n\n\nholy shit!!!!!!!'b' always once more than 'a'!!!!

fuck!!! \n\n\n\n\n\n");
system("pause");
}
clrscr();
}


这是用3个型号量实现两个线程的互斥,
前面一大堆都是数据结构的定义。
结果有误,f2最后总是多运行一次,也就是在i2为11时f2居然还运行一次才结束.....
无从解决啊,求高手帮我看下哪里不对了,要怎么修改,谢谢了!!
...全文
104 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyqyyqlove2 2010-12-10
  • 打赏
  • 举报
回复
一楼二楼有道理!
其实我的疑惑在于两个线程的while语句,f2里面i2=11的时候f2却还能再做一次.....另外就是线程的撤销。
测试昵称666 2010-12-10
  • 打赏
  • 举报
回复
这么长代码,10个看有9个会直接走人。另外一个会像我一样,多说几句废话。
LZ别介意我这么说,因为你以后还会有更多问题要问,要想别人帮你,首先得学会帮自己。

你尝试着把错误缩小范围,然后再来提问,相信会有更多朋友帮助你的。另外,建议用CSDN发代码自带的代码高亮按钮。正数第七个,就是那个井号键。
licaiyuren 2010-12-10
  • 打赏
  • 举报
回复
这样子问问题,谁帮你看啊

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧