-
Notifications
You must be signed in to change notification settings - Fork 0
/
PCB.cpp
104 lines (77 loc) · 2.81 KB
/
PCB.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* PCB.cpp
*
* Created on: Jun 1, 2021
* Author: OS1
*/
#include <dos.h>
#include <iostream.h>
#include "PCB.h"
#include "SCHEDULE.H"
#include "List.h"
#include "Kernel.h"
#include "Thread.h"
ID PCB::nextID = 0;
void PCB::wrapper(){
Kernel::runningPCB->myThread->run();
lock
Kernel::runningPCB->status = TERMINATED;
//for(Node * h = this->waitingList.head; h!=0; h=h->)
for(((PCB*)Kernel::runningPCB)->waitingList.toHead(); ((PCB*)Kernel::runningPCB)->waitingList.hasCurr(); ((PCB*)Kernel::runningPCB)->waitingList.toNext()){
PCB * p = ((PCB*)Kernel::runningPCB)->waitingList.getPointer();
p->status = READY;
Scheduler::put(p);
}
/*while(waitingList.hasCurr()){ //treba li ovo ? svakako samo jednom start metoda
waitingList.remove(); //tako da za ubuduce nije bitno
}*/
unlock
Kernel::dispatch(); //jer mu nismo dali callback mora
}
PCB::PCB(Thread * mmyThread, StackSize sstackSize, Time ttimeSlice) : myThread(mmyThread), timeSlice(ttimeSlice){
lock
this->deblockedBySignal = 0;
this->stackSize = sstackSize / sizeof(unsigned);
this->id = nextID++;
this->status = NEW;
this->stack = new unsigned[this->stackSize];
this->stack[this->stackSize - 1] = 0x200; //redosled - PSW pa PC (CS pa IP, jer niza adr = nizi bit)
#ifndef BCC_BLOCK_IGNORE
this->stack[this->stackSize - 2] = FP_SEG(PCB::wrapper); //pitamo se - sta je PC kad
this->stack[this->stackSize - 3] = FP_OFF(PCB::wrapper); //odgovor je funkcija Wrapper koju podmecemo da pozove run threada
#endif
//-1 do -11 registri ax, bx, cx, dx, es, ds, si, di.. za njih vrednost moze biti random na pocetku..
#ifndef BCC_BLOCK_IGNORE
this->ss = FP_SEG(this->stack + this->stackSize - 12);
this->sp = FP_OFF(this->stack + this->stackSize - 12);
#endif
this->bp = this->sp; //na pocetku BP pokazuje na SP
Kernel::allPCBs.add(this);
unlock
}
ID PCB::getID(){
return this->id;
}
void PCB::start(){
lock
if(status!=NEW) return; //ne moze vise puta da se pozove
status = READY;
//Kernel::allPCBs.add(this);
Scheduler::put(this); //stavljamo nasu nit koja je ready u scheduler
unlock
}
void PCB::waitToComplete(){ //blokira nit iz koje se poziva, dok nit nad kojom se poziva ne zavrsi izvrsavanje
lock //ne zelimo da nas neko prekine dok ne blokiramo nit
if(status != TERMINATED && this != Kernel::runningPCB){
Kernel::runningPCB->status = BLOCKED; //iz koje se poziva (running) se blokira
this->waitingList.add((PCB*)Kernel::runningPCB); //dodali smo u listu cekanja ove niti trenutnu runningPCB
Kernel::dispatch(); //zelimo nekom drugi preuzme
}
unlock //ako je nas status terminated, nista ne radimo, jer je nit gotova
}
PCB::~PCB(){
lock
status = TERMINATED;
if(stack) delete[] stack; //brisemo memoriju a to je stack
unlock
}