forked from osukaa/Proyecto-Sistemas-Operativos
/
project_SO.CPP
212 lines (198 loc) · 4.49 KB
/
project_SO.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*Implementa el primer algoritmo de exclusion mutua: Alternancia estricta*/
#include<dos.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
void interrupt myTimer(...);
void interrupt (*prev)(...);
struct process{
char id;
int quantum;
int status;
int stcPtr;
int offset;
};
/*Variables globales*/
process pcb[2];
const int quantum = 4;
int indexProcess = 0;
int stackPointerAux;
int stackPointer;
int indexOffset;
int indexAux;
int quantumProcess;
int actualProcess;
/*Procesos a controlar*/
void processA(...)
{
int color = 1;
while(1)
{
//tareas previas
while (actualProcess == 2)
//seccion critica
gotoxy(2,2);
textcolor(color);
cprintf("soy proceso A");
actualProcess = 2;
//otras tareas
color++;
color = color % 15;
}
}
void processB(...)
{
int color = 15;
while(1)
{
//tareas previas
while (actualProcess == 1)
//Seccion critica
gotoxy(2,4);
textcolor(color);
cprintf("soy proceso B");
actualProcess = 1;
//Otras tareas
color++;
color = color % 15;
}
}
void processC(...)
{
while(1)
{
gotoxy(2,6);
cprintf("soy C =) ");
}
}
void processD(...)
{
while(1)
{
gotoxy(2,8);
cprintf("soy D ;) ");
}
}
/*inicializar el pcb*/
void initPCB(...)
{
//Inicializa el primer nodo del PCB
pcb[0].offset = FP_OFF(processA);
pcb[0].quantum = quantum;
pcb[0].id = 'A';
pcb[0].status = 1;
pcb[0].stcPtr = 0;
//Inicializa el segundo nodo del PCB
pcb[1].offset = FP_OFF(processB);
pcb[1].quantum = quantum;
pcb[1].id = 'B';
pcb[1].status = 2;
//Guarda el SP de nuestro programa
asm mov stackPointer,sp
stackPointerAux = stackPointer;
//Realiza un corrimiento en la pila para el primer proceso
stackPointerAux = stackPointerAux - 512;
indexOffset = pcb[1].offset; //Direccion del proceso i
//Guarda todo el contexto del proceso 1
asm {
mov SP, stackPointerAux
pushf
push cs
push indexOffset
push ax
push bx
push cx
push dx
push es
push ds
push si
push di
push bp
mov stackPointerAux, SP
mov SP, stackPointer
};
//Guarda en el PCB el SP donde se encuentran el contexto del proceso
pcb[1].stcPtr = stackPointerAux;
indexProcess = 0;
quantumProcess =pcb[indexProcess].quantum;
}
/*Procemiento que reemplaza la interrupcion del timer con nuestro
codigo fuente.*/
void main()
{
clrscr();
initPCB();
prev=getvect(8); //Guarda la interrupci¢n antigua del timer
setvect(8,myTimer); //Inserta con nuestro c¢digo la interrupcion del time
actualProcess = 1;
processA();
clrscr();
while(1)
{}
}
/*Codigo fuente de nuestra interrupcion del timer*/
void interrupt myTimer(...)
{
disable(); //Apaga las demás interrupciones
(*prev)(); //Llama al antiguo c¢digo de interrupcion
//Espera una tecla y verifica si es la tecla Enter
if(kbhit() && getch() == 0xD)
{
//Devuelve la interrupción original
setvect(8,prev);
exit(0);
}
if (quantumProcess > 0)
{
//Si el proceso aun tiene quantum lo disminuye.
quantumProcess--;
}
else
{
//Salva el SP del proceso que se quedo sin quantum
asm mov stackPointer, SP
pcb[indexProcess].stcPtr = stackPointer;
if (pcb[indexProcess].status == 1)
{
pcb[indexProcess].status = 2;
}
//copia el valor que posee el quantum del proceso actual
int q = pcb[indexProcess].quantum;
if (q > 20)
{
//Si el quantum del proceso es mayor a 20 reinicia el quantum en su valor original
q = quantum;
}
else
{
/*Si el quantum del proceso actual no es mayor a 20 le aumenta uno para que a la siguiente ejecución
tenga un tick de reloj más*/
q++;
}
//Asigna el nuevo quantum al proceso.
pcb[indexProcess].quantum = q;
//Cambio de proceso.
indexAux = indexProcess;
indexProcess++;
indexProcess = indexProcess % 2;
if (pcb[indexProcess].status != 2)
{
indexProcess++;
indexProcess = indexProcess % 2;
}
//Guarda el quantum del nuevo proceso.
quantumProcess = pcb[indexProcess].quantum;
//revisa que no se repita el proceso que se acaba de quedar sin quantum
if (indexAux != indexProcess)
{
//Le indica que el nuevo proceso va estar en estado ejecutado.
pcb[indexProcess].status = 1;
stackPointer = pcb[indexProcess].stcPtr;
//Mueve el SP a donde esta el contexto del nuevo proceso que va ejecutar
asm mov sp,stackPointer
}
}
enable(); //Activa las demás interrupciones
}