関数に実装されているコンテキスト スイッチをテストしていdispatch()
ます。私の理解では、割り込みタイマー内でディスパッチを呼び出すと問題が発生します。私がそれを行うと、コンパイルさえしません!奇妙なことに、タイマー割り込みとタイマーを呼び出してコンテキストを切り替えるためだけにディスパッチを実装すると、完全に機能します。マクロまたはインライン関数をディスパッチしようとしましたが、問題は同じです。ビルドしようとすると、予期しない例外が発生しますか?
何が悪いのか教えてもらうにはこれで十分ですか?
class PCB{ // this class represents a thread
public:
unsigned sp;
unsigned ss;
Status status;
Time kvant; // time slice
static PCB* running;
void createProcess(void (*body)());
};
PCB* PCB::running = 0;
void PCB::createProcess(void (*body)()){
unsigned* stek = new unsigned[1024];
st1[1023] =0x200; // PSW register with I flag setted to be 1
st1[1022] = FP_SEG(body);
st1[1021] = FP_OFF(body);
this->sp = FP_OFF(st1+1012); // space for registers ax,bx,cx,d,si,es,ds,di,bp
this->ss = FP_SEG(st1+1012);
this->status = NEW;
}
void interrupt timer(){
timer_counter--;
if (timer_counter == 0) dispatch();
else asm int 60h; // invoking the old routine
}
void interrupt dispatch(){
asm cli;
asm {
// store sp
mov tsp, sp
mov tss, ss
}
PCB::running->sp = tsp;
PCB::running->ss = tss;
cout<<"Context change!"<<endl;
if(PCB::running->status !=END){
PCB::running->status = READY;
Scheduler::put(PCB::running);
}
PCB::running=Scheduler::get();
PCB::running->status = RUNNING;
tsp = PCB::running->sp;
tss = PCB::running->ss;
timer_counter = PCB::running->kvant;
asm {
mov sp, tsp // restore sp
mov ss, tss
}
asm sti;
}