Examen resuelto de Sist. Operativos Junio 99 Sandoval 1.A ) // Para que la lista de procesos activos mantenga un estado consistente hay que encadenar P2 a P4. Ptemp: = Pactivo.Ppuntero_procesodcha ( Apunta a P2) Ptemp: = Ptemporal.puntero_procesodcha ( Apunta a P3 ) Psuspendido: = Ptemporal ( Psuspendido à P3 ) // Si hubiesemos encadenado P2 a P4 sin controlar antes P3 lo hubiesemos // perdido. // Ahora a partir de P3 modificar P2 y P4. Psuspendido.puntero_procesoizq.Puntero_procesodcha: = Psuspendido.puntero_procesodcha P2 P3 P4 Psuspendido.puntero_procesodcha.Puntero_procesoizq: = Psuspendido.puntero_procesoizq P2 P3 P4 // Sólo Queda actualizar los punteros de P3. Psuspendido.puntero_procesodcha: = Psuspendido Psuspendido.puntero_procesoizq: = Psuspendido P1 P2 P4 P3 Página: I Examen resuelto de Sist. Operativos Junio 99 Sandoval 1.B ) Hay que tener en cuenta: - - Un proceso se puede suspender a si mismo. Eso implica pasar otro proceso a EJECUCION. Se suspende a un proceso que está activo pero no es el que está en ejecución. Simplemente se desencadena en la lista de activos y se encadena en la lista de suspendidos. El proceso a suspender no está activo. Se termina sin hacer nada. Queda sin resover el caso de suspender al último proceso activo. Suspender ( Id ) Si quiensoy ( ) = Id // se suspende el proceso en ejecución Ptemp: = Pactivo Pactivo: = Pactivo.puntero_procesodcha Ptemp: = puntero_procesoizq.puntero_procesodcha: = Ptemp.puntero_procesodcha Ptemp.puntero_procesodcha.puntero_procesoizq: = Ptemp.puntero_procesoizq // Desenganchado de la lista activa. // Empieza el cambio de contexto. Push (DX ) Push ( AX ) Ptemp.punteropila: = PP PP: = Pactivo.punteropila POP(AX) POP(DX) // Encadenar el proceso suspendido en Psuspendido. Si Psuspendido: = NULL // Estaba vacia. Psuspendido: = Ptemp Psuspendido.puntero_procesodcha: = Psuspendido Psuspendido.puntero_procesoizq: = Psuspendido // Encadeno a la dcha. Es // equivalente a la izq. Sino Ptemp.puntero_procesodcha: = Psuspendido.puntero_procesodcha Psuspendido.puntero_procesodcha.puntero_procesoizq: = Ptemp Psuspendido.puntero_procesodcha: = Ptemp Ptemp.puntero_procesoizq: = Psuspendido Página: II Examen resuelto de Sist. Operativos Junio 99 Sandoval Sino // Buscamos el proceso Ptemp. = Pactivo.puntero_procesodcha // Recorremos la lista hasta el principio “ Ptemp <> Pactivo “ o hasta que // encontramos el proceso “ Ptemp.id <> id “ While ((Ptemp<> Pactivo) and (Ptemp.ident_proceso<> id) ) Ptemp: = Ptemp.puntero_procesodcha Si Ptemp.ident.proceso = id // Encontrado. Desenganchamos de lista activa Ptemp.puntero_procesoizq.puntero_procesodcha: = Ptemp.puntero_procesodcha Ptemp.puntero_procesodcha.puntero_procesoizq: = Ptemp.puntero_procesoizq // Enganchamos a lista de suspendidos Si Psuspendido = NULL Psuspendido: = Ptemp Psuspendido. puntero_procesodcha: = Psuspendido Psuspendido. puntero_procesoizq: = Psuspendido Sino Ptemp.puntero_procesodcha: = Psuspendido.puntero_procesodcha Psuspendido.puntero_procesodcha.puntero_procesodcha: = Ptemp Psupendido.puntero_procesodcha: =Ptemp Psupendido.puntero_procesoizq: =Psuspendido 2.A ) Variables: EspacioLibre: Semaforo: = 10 // El espacio libre del buffer EspacioOcupado: Semaforo: = 0 // El espacio ocupado del buffer Acceso : Semaforo: = 1 // Sincronismo Productores While TRUE Otro_código Wait ( EspacioLibre ) Wait ( Acceso ) Introducir Signal ( Acceso ) Signal ( EspacioOcupado) Consumidores While TRUE Otro_código Wait ( EspacioOcupado) Wait ( Acceso ) Retirar Signal ( Acceso ) Signal ( EspacioLibre ) Página: III Examen resuelto de Sist. Operativos Junio 99 Sandoval 2.B ) Con esta instrucción se puede implementar un semáforo BINARIO. Pero hay que tener en cuenta que Testandset marca la variable a 1. Por tanto el valor de semáforo libre ( que permite el paso ) es 0 y semáforo ocupado es 1 (al contrario de cómo se suele implementar un semáforo). Waits) : Testandset s Si zero = FALSE goto Signal(s): S: = 0 2.C ) Se puede construir un semáforo entero copiando la variable semáforo a una variable temporal (a) y, en la misma operación atómica, marcando el semáforo a 0 (XCHG). Con esa instrucción nos quedamos con el valor del semáforo en “a” y a la vez lo marcamos a 0 para que nadie lo toque mientras lo modificamos (lo incrementamos en Wait y lo decrementamos en Signal. Wait(s) : Variable temporal a a: = 0 XCHG a , s Si a = 0 goto a: = a – 1 XCHG a , s Signal(s): Variable temporal a a:=0 XCHG a,s Si a = 0 goto a:=a+1 XCHG a,s 3.A ) 0 0 110 7800 110 id 0 110 110 1170 0 1600 id 1 0 1600 1600 400 110 4000 id 2 110 4000 4000 800 1600 4800 id 3 4800 1600 4800 3000 4000 0 id 5 4000 7800 Pocupado Plibre 1280 1280 320 7800 200 id X 2000 1280 2000 2000 1280 7800 id X 7800 7800 10000 2000 1280 id X 2000 Página: IV Examen resuelto de Sist. Operativos Junio 99 Sandoval 7800 3.B ) EstáLibre ( Dirección ) Si Plibre = NULL // si toda la memoria está ocupada Return FALSE // está claro que esa dirección no está libre Sino Ptemp: = Plibre Loop Si dirección< Ptemp.inicio + Ptemp.longitud AND Dirección >= Ptemp.inicio Retornar TRUE Ptemp: = Ptemp.Pdcha Hasta que Ptemp = Plibre // ó mientras Ptemp <> Plibre Retornar FALSE 3.C ) Ptemp: = Pocupado.Pizq // Apunta al proceso 5 // Desenganchamos Ptemp.Pizq.Pdcha: = Ptemp.Pdcha Ptemp.Pdcha.Pizq: = Ptemp.Pizq Ptemp.dcha: = Plibre.dcha // Enganchamos justo a la derecha de Plibre Ptemp.Pizq: = Plibre Plibre.Pdcha.Pizq: = Ptemp Plibre.Pdcha: = Ptemp // Compactar bloques 7 y 8 => Desenganchar el bloque 8 y sumar su long. al 7 Variable temporal L : = Ptemp.Pdcha.Longitud Ptemp.Pdcha.Pdcha.Pizq: = Ptemp Ptemp.Pdcha: = Ptemp.Pdcha.Pdcha Ptemp.Longitud: = Ptemp.Longitud + L Página: V Examen resuelto de Sist. Operativos Junio 99 Sandoval 3.D ) LiberarProceso ( ID ) Ptemp: = Pocupado // Buscamos el bloque While Ptemp.IDProceso <> ID Ptemp: = Ptemp.Pdcha // Se desengancha Ptemp.Pizq.Pdcha : = Ptemp.Pdcha Ptemp.Pdcha.Pizq: = Ptemp.Pizq // Buscamos su posición en la lista de libres. Hay un caso especial cuando es el bloque // libre más alto de la memoria o el más bajo. Loop Si Plibre.inicio < Ptemp AND Plibre.Pdcha.inicio > Ptemp.inicio Terminar bucle // Entre el Plibre y el siguiente // ahora se contempla un caso especial: Plibre apunta al bloque más alto de la // memoria. En ese caso se comprueba si el bloque nuevo es más alto o el más // bajo de la memoria Si Plibre.inicio > Plibre.Pdcha.inicio Si Plibre.inicio < Ptemp.inicio OR Plibre.Pdcha.inicio > Ptemp.inicio Terminar bucle // Mas alto ó mas bajo Plibre:= Plibre.Pdcha End Loop // Plibre apunta al anterior bloque // Enganchamos en su sitio Ptemp.Pdcha: = Plibre.Pdcha Ptemp.Pizq : = Plibre Plibre.Pdcha.Pizq: = Ptemp Plibre.Pdcha: = Ptemp // Hay que comprobar si hay dos bloques libres contiguous para compactar // se comprueba primero con el de su derecha Si Ptemp.Inicio+Ptemp.Longitud = Ptemp.Pdcha.Inicio UnirDosBloques(Ptemp) // se comprueba el de su izquierda. Ptemp:= Ptemp.Pizq Si Ptemp.Inicio+Ptemp.Longitud = Ptemp.Pdcha.Inicio UnirDosBloques(Ptemp) UnirDosBloques(Punt) Punt.Longitud := Punt.Longitud+Punt.Pdcha.Longitud Punt.Pdcha.Pdcha.Pizq := Ptemp Punt.Pcha := Punt.Pcha.Pcha Página: VI