// v2_zad4.cpp // prevodjenje iz komandne linije: bcc -mh -Ic:\bc31\include -Lc:\bc31\lib v2_zad4.cpp //pretpostavljeni memorijski model: huge #include #include // zabranjuje prekide #define lock asm cli // dozvoljava prekide #define unlock asm sti struct PCB{ unsigned sp; unsigned ss; unsigned finished; int quantum; }; PCB *p[3]; volatile PCB* running; volatile int nextThread = 2; // rasporedjivac niti (scheduler) PCB* getNextPCBToExecute(){ if (nextThread == 1) nextThread = 2; else nextThread = 1; if (p[nextThread]->finished){ if (nextThread == 1) nextThread = 2; else nextThread = 1; if (p[nextThread]->finished) nextThread = 0; } return p[nextThread]; } // stara prekidna rutina unsigned oldTimerOFF, oldTimerSEG; // deklaracija nove prekidne rutine void interrupt timer(); // postavlja novu prekidnu rutinu void inic(){ asm{ cli push es push ax mov ax,0 mov es,ax // es = 0 // pamti staru rutinu mov ax, word ptr es:0022h mov word ptr oldTimerSEG, ax mov ax, word ptr es:0020h mov word ptr oldTimerOFF, ax // postavlja novu rutinu mov word ptr es:0022h, seg timer mov word ptr es:0020h, offset timer // postavlja staru rutinu na int 60h mov ax, oldTimerSEG mov word ptr es:0182h, ax mov ax, oldTimerOFF mov word ptr es:0180h, ax pop ax pop es sti } } // vraca staru prekidnu rutinu void restore(){ asm { cli push es push ax mov ax,0 mov es,ax mov ax, word ptr oldTimerSEG mov word ptr es:0022h, ax mov ax, word ptr oldTimerOFF mov word ptr es:0020h, ax pop ax pop es sti } } //pomocne promenljive za prekid tajmera unsigned tsp; unsigned tss; volatile int cntr = 20; volatile int context_switch_on_demand = 0; // nova prekidna rutina tajmera void interrupt timer(){ if (!context_switch_on_demand) cntr--; if (cntr == 0 || context_switch_on_demand) { asm { // cuva sp mov tsp, sp mov tss, ss } running->sp = tsp; running->ss = tss; // scheduler running = getNextPCBToExecute(); tsp = running->sp; tss = running->ss; cntr = running->quantum; asm { // restaurira sp mov sp, tsp mov ss, tss } } // poziv stare prekidne rutine // koja se nalazila na 08h, a sad je na 60h; // poziva se samo kada nije zahtevana promena konteksta // tako da se stara rutina poziva // samo kada je stvarno doslo do prekida if(!context_switch_on_demand) asm int 60h; context_switch_on_demand = 0; } // sinhrona promena konteksta void dispatch(){ lock context_switch_on_demand = 1; timer(); unlock } void exitThread(){ running->finished = 1; dispatch(); } void a(){ for (int i =0; i < 30; ++i) { lock cout<<"u a() i = "<quantum = 40; p[2] = new PCB(); createProcess(p[2],b); cout<<"Napravio b"<quantum = 20; p[0] = new PCB(); running = p[0]; unlock for (int i = 0; i < 30; ++i) { lock cout<<"main "<