0% encontró este documento útil (0 votos)
34 vistas44 páginas

Resumen SO

El documento abarca conceptos fundamentales de arquitectura de computadoras, sistemas operativos, procesos y hilos. Describe componentes clave como la ALU, registros, el ciclo de instrucciones, mecanismos de entrada/salida, y tipos de interrupciones, así como las funciones y capas de un sistema operativo. También se exploran los estados de un proceso, el cambio de contexto, la creación y finalización de procesos, y las ventajas y desventajas de los hilos en comparación con los procesos.

Cargado por

liaudatf
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
34 vistas44 páginas

Resumen SO

El documento abarca conceptos fundamentales de arquitectura de computadoras, sistemas operativos, procesos y hilos. Describe componentes clave como la ALU, registros, el ciclo de instrucciones, mecanismos de entrada/salida, y tipos de interrupciones, así como las funciones y capas de un sistema operativo. También se exploran los estados de un proceso, el cambio de contexto, la creación y finalización de procesos, y las ventajas y desventajas de los hilos en comparación con los procesos.

Cargado por

liaudatf
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

PPT 1: Repaso Arquitectura de Computadoras

PARTES DE LA COMPU
ALU: unidad aritmética lógica, donde se realizan las operaciones.

BUS: medio de comunicación entre los componentes de la computadora.

REGISTROS: medios de almacenamiento de la CPU. Estos son acotados (de baja capacidad), no
persisten los datos que aloja (al igual que la RAM, y a diferencia de los medios de
almacenamiento secundarios, si la computadora se apaga estos se pierden) y, debido a su gran
velocidad, son donde se guarda la información inmediata a procesar por la CPU.

Estos pueden ser:

- De uso general: son aquellos utilizados para guardar datos que se han de procesar por
la CPU.
- De segmento: son utilizados por una estrategia particular de memoria ya que permiten
saber dónde está el comienzo y el fin de cada segmento.
- De control: guardan la información que proviene del BUS (que se ha de alojar en
memoria para ser utilizada)
- De uso específico como:
o IP (Instruction Pointer) / PC (Program Counter): indican la dirección de
memoria de la próxima instrucción a ejecutar. En un programa, lo esperado, es
que su ejecución sea secuencial por lo que cuando termina de ejecutarse cada
instrucción se incrementa en 1 el IP para que así (luego de validar si las
interrupciones están habilitadas, si hay interrupciones que se han de ejecutar
y ejecutarlas si las hay) se ejecute la siguiente instrucción.
o PSW (flags): hay múltiples flags y entre ellos están, por ejemplo, el flag del
overflow, el de zero y muchos más que indican el modo de ejecución de las
instrucciones (del programa en sí).

ARQ VON NEUMANN


Permitió, al poder cargar datos y procesos en la computadora, la no utilización de múltiples
cables para realizar operaciones.

CICLO DE UNA INSTRUCCIÓN


1. Búsqueda de la instrucción en memoria a partir del IP/PC (ya que este apunta a la
ubicación en la que se encuentra la siguiente instrucción a ejecutarse en memoria).
2. Decodificación de la instrucción: se interpretan los bits, que se encuentran el IR
(Instruction Register), como un código de operación (únicamente los válidos).
3. Búsqueda de los operandos de la instrucción si es que tiene (depende del tipo de
instrucción, por ejemplo NOT no tiene).
4. Ejecutar la instrucción, cambiar los flags necesarios e incrementar en 1 el IP/PC.
5. Si las interrupciones están habilitadas y hay interrupciones que atender, atenderlas
según como el procesador lo indique**
6. Comenzar de nuevo.

** Puede ser que se ejecuten secuencialmente, es decir, una tras otra. Sino puede que la
forma de ejecutar las interrupciones sea de forma anidada (por prioridades donde se guarda el
contexto de la interrupción que se estaba ejecutando, además del IP de la próxima instrucción,
y luego de ser ejecutada aquella con mayor prioridad se determina si se vuelve a ejecutar la
que se interrumpió).

La ejecución de las instrucciones también puede ser secuencial o de forma “solapada”


(pipeline) en donde aumenta el throughput (rendimiento, numero de instrucciones ejecutados
por unidad de tiempo) de las instrucciones, se ejecutan más rápidamente pero el procesador
trabaja más (más cambios de contexto y guardar dichos cambios).

MECANISMOS DE IO
Consiste en los formatos en los que se puede hacer una E/S, como leer algo de un disco rigido.

E/S programada:

Es un mecanismo en el cual el procesador se encarga de todo: leer los datos del módulo de IO,
consultar continuamente sobre el estado del módulo IO (es decir, verificar si los datos se
encuentran disponibles) y pasar byte a byte los datos a memoria. Si es una transferencia de
pocos bytes permite que haya poco overhead (tiempo desperdiciado por el procesador para
realizar un cambio de contexto) de procesos más complejos, pero, en caso contrario, hace un
mal uso de la CPU (esta podría estar ocuapada realizando y ejecutando instrucciones de mayor
prioridad).

E/S basada en interrupciones:

Es otro tipo de mecanismo en el cual mantiene el hecho de que el procesador sigue leyendo
los datos del módulo de IO y pasándolos a memoria (sigue habiendo un mal uso de la CPU,
aunque en menor medida) pero no se encuentra continuamente verificando el estado del
módulo (si los datos se encuentran disponibles) sino que usa una interrupción para ello.
Entonces si no están los datos se ocupa de ejecutar instrucciones y en caso que estén una vez
ejecutada la instrucción con la que estaba (porque no se puede interrumpir el ciclo de una
instrucción) se ocupará de atender la interrupción.

E/S con DMA:

Mecanismo en el que se incorpora otro componente que tiene permitido copiar la información
directamente a la memoria (el DMA) y que se encarga de todo (permite que la CPU se ocupe
de otras cosas de mayor importancia) con el inconveniente de que debe compartir el BUS con
la CPU para cargar los datos a memoria (genera que sea más lenta al robarle ciclos de CPU).
Involucrar a este otro componente hace que el set up también sea más lento pero que la
transferencia en su totalidad, generalmente, sea más eficaz. Sigue utilizando las interrupciones
para la verificación del estado, solo que cuando los datos estén disponibles no le avisa a la CPU
sino a este componente intermediario. La CPU es avisada cuando toda la transferencia sea
completada.

INTERRUPCIONES
Son alteraciones del flujo normal del programa (la CPU no interrumpe el ciclo de una
instrucción sino que para atenderlas, si es que están habilitadas, espera a que se ejecute la
instrucción)

Estas pueden ser:

- Internas al procesador (por ejemplo si se pretende dividir por 0) o externas (aquella


que el DMA genera para avisarle a la CPU que se terminó la E/S)
- Sincronas (internas) o Asincronas
- Enmascarables (pueden obviarse) o no Enmascarables (se tienen que atender si o si)
- De HW o de SW

PPT 2: Introducción a SO
¿QUÉ ES UN SISTEMA OPERATIVO?
Software que se encuentra en un medio de almacenamiento secundario y que posee permisos
particulares. Su objetivo es coordinar todos los componentes para que se ejecuten
correctamente y administrar los recursos bien.

¿QUÉ DEBERÍA CUMPLIR UN SISTEMA OPERATIVO?


- Administrar los dispositivos IO
- Administrar memoria
- Administrar archivos
- Administrar la ejecución de programas
- Ser interfaz del usuario
- Ser interfaz de los dispositivos.
- Comunicación entre programas

CAPAS DE UN SISTEMA OPERATIVO


Desde la más externa (de más alto nivel) que es la comunicación con el usuario hasta la más
interna (de más bajo nivel) que es la comunicación con el hardware.

- Aplicaciones de usuario.
- Aplicaciones utilitarias: no son de uso final pero son muy útiles.
- Bibliotecas
- Syscalls: mecanismos dados por el sistema operativo para pedir algunos de sus
servicios (funcionalidades del kernel que no pueden ser accedidas directamente). Para
hacer el cambio de privilegios hay que hacerlo:
o Mediante interrupciones (que requiere un previo acceso a memoria, antes de
ser atendido por el interrupt handler que ya es parte del sistema operativo).
o Mediante fast syscalls, es decir, instrucciones específicas (más rápido porque
no requiere de un acceso a memoria).

Existen wrappers (envoltorios) función que encapsula a más de una syscalls, consisten
en un conjunto de syscalls que es más fácil de usar (nos abstraen de ciertas
complejidades) y más portable (si cambia algo el wrapper se encargará de adaptarse)
- Kernel: núcleo, parte central (más bajo nivel) con funcionalidades básicas de sistema
operativo. Si bien existen varias arquitecturas de kernel, todas ellas incluyen: la
comunicación con el hardware, la creación de procesos y la comunicación entre ellos.

MODOS DE EJECUCIÓN
Consiste en que se debe tener un esquema (con el fin de tener una mayor protección) en el
que haya instrucciones más privilegiadas que otras y ciertos modos de ejecución que puedan o
no acceder a realizarlas (modo kernel posee todos los privilegios, modo user no)

Entonces para pasar de modo user a modo kernel se puede realizar a través de:

- Interrupciones
- Syscalls:
o Interrupciones
o Fast Syscalls

Y para acceder de modo kernel a modo user:

- Instrucciones privilegiadas
- Restaurando el contexto.

TIPOS DE KERNEL
Existen distintas arquitecturas entre las cuales esta:

Monolítico: todas las funcionalidades del sistema operativo se encuentran dentro del kernel
por lo que es rápido a nivel ejecución y excelente en cuanto a la comunicación entre
componentes. Sin embargo presenta ciertas desventajas en el diseño tales como la seguridad,
la estabilidad, el encontrar un error ya que esta todo en modo kernel, entre ellas. Es el usado
hoy en día.

MicroKernel: en el kernel está únicamente lo esencial y lo demás en modo usuario. Si bien


presenta múltiples ventajas a nivel diseño (seguridad, estabilidad, facilidad de corregir errores,
etc.) a nivel ejecución y en cuanto a comunicación entre componentes es bastante lento.

Multi-Capa: teórico.

PPT 3: Hilos y Procesos


CONCEPTO PROCESO
Un proceso es un programa en ejecución que no solo incluye el código del mismo, es una
entidad activa (con ciclo de vida). Sus componentes son:

- PCB (Process Control Block): estructura que posee el sistema operativo con toda la
información del proceso para administrarlo. Siempre se encuentra en memoria a
diferencia de los demás componentes que puede que no lo estén.
- Stack: pila (estructura LIFO) que contiene las variables locales (los parámetros) de las
funciones utilizadas.
- Heap: memoria dinámica que se le pide al sistema operativo y que se tiene
responsabilidad de liberar una vez ya utilizada

Tanto el Stack como el Heap son dos estructuras cuyo tamaño no es fijo, sino que va variando.

- Datos: variables globales (que no se inicializan pero si se sabe su tamaño) y estaticas


(que se inicializan).
- Código: instrucciones que se han de ejecutar
- Imagen del proceso: todo lo que representa al proceso en memoria

ESTADOS DEL PROCESO


El proceso es una entidad activa y como tal tiene un ciclo. Este puede pasar por distintos
estados entre los cuales se encuentran:

 Nuevo: ya existe la abstracción del proceso pero eso no quiere decir que todos los
componentes estén en memoria (el PCB es el único que podemos asegurar que sí). Los
procesos en nuevo competirán por ser admitidos en el sistema (pasar a un estado
Listo).
 Listo: el proceso es admitido en el sistema, todos sus componentes pasan a estar en
memoria y se lo deja listo para ser ejecutado. Así como en nuevo los procesos
compiten por pasar a un estado listo, los procesos en listo compiten por estar en
ejecución.
 En ejecución: se ejecutan las instrucciones del proceso en cuestión.

Pueden pasar 3 cosas:

 Pasa a estar Finalizado cuando ejecuta toda sus instrucciones, para ello previamente se
deben liberar todos los recursos posibles (como el heap que es memoria dinámica
pedida al sistema operativo).
 Pasa a estar en una cola En Espera (donde se referencia al PCB del proceso) debido a
que debe esperar a que un evento ocurra o que se realice una IO. Cuando ocurre el
evento o la IO finaliza el proceso pasa a estar nuevamente en Listo.
 Pasa a estar En Listo debido a que desalojo voluntariamente o debido a que fue
interrumpido por el SO.

CAMBIO DE CONTEXTO
Un cambio de contexto de un proceso conlleva guardar el contexto de ejecución para luego
reanudarlo en el lugar donde fue interrumpido (el tiempo que comprende el cambio de
contexto es considerado overhead y debe minimizarse). Si dicha interrupción es temporal, el
contexto de ejecución se guarda en el stack (que conlleva un menor costo) pero si es más
permanente (por ejemplo si luego de la interrupción se comienza a ejecutar otro proceso) esta
se debe guardar en el PCB.

Los cambios de contexto se pueden dar por:

- Una interrupción.
- Una syscall.
- La ejecución de otro proceso.

PCB
Posee:

- Estado del proceso


- IP/PC: direcciones o punteros donde se encuentra la información en la RAM
- Registros CPU
- Información planificación CPU
- Información manejo de memoria
- Información contable para tener como input a futuro
- Información de E/S

CREACIÓN DE PROCESOS
Se realiza a través de una syscall llamada fork que devuelve un valor (que se almacena en el
stack) que debe ser validado (ya que esta puede fallar): en caso que sea 0 es el proceso hijo, en
caso que sea un valor positivo es el proceso padre.

El espacio de direccionamiento del proceso hijo a través de la syscall fork puede ser una copia
exacta a la del proceso padre o puede ser una imagen completamente nueva pasada por
parámetro. De todas formas a ambos procesos, en su ejecución, se los diferencia por su PID
(Process ID) siendo el del padre menor al del hijo.

En cuanto a la ejecución, al crear a un proceso hijo ambos procesos pueden seguir


ejecutándose concurrentemente o el proceso padre puede esperar a que el proceso hijo
finalice para hacerlo el.

FINALIZACIÓN DE PROCESOS
Los procesos, si desean finalizar deben hacer una syscall llamada exit que, en caso que tengan
un proceso padre le informará que fue finalizado con un wait y sus recursos serán liberados.

En caso que un proceso desee finalizar y tenga procesos hijos, según el sistema operativo
estos:

- Finalizan en cascada
- Pueden ser asignados al padre de su padre (abuelo) y seguir ejecutándose.

Un proceso padre puede finalizar la ejecución de sus hijos (abort) si:

- Los hijos consumen muchos recursos o tardan mucho en hacerlo.


- La tarea que deben hacer ya no es necesaria.
- Si el sistema operativo dispone que si el mismo finaliza los hijos deben finalizar en
cascada.

COMUNICACIÓN ENTRE PROCESOS


Los procesos no afectan ni deben ser afectados por otros procesos independientes.

Sin embargo, existen procesos que son cooperativos y tienen un fin en común. Para lograrlo
comparten recursos ya sea:

- Con un paso de mensajes lo cual es performante si los datos que deben de compartir
son pocos, pero dicho traspaso es muy lento
- Con memoria compartida (establecen una zona de memoria compartida por la cual
pueden comunicarse y compartir datos) lo cual es muy rápido pero puede generar
problemas si desean usar un recurso compartido al mismo tiempo o si se genera una
condición de carrera.

CONCEPTO HILOS
 Es la minima unidad de planificación
 Comparten datos, código y heap con otros hilos (por lo que no hay protección entre
ellos, un hilo puede escribirle a otro en el espacio de memoria compartida pero no
necesita mecanismos para inter-comunicación entre ellos)
 Cada hilo es administrado por un TCB (“PCB en hilos”) y tiene su propio sector de stack

VENTAJAS
➔ Permiten paralelismo dentro de un proceso o aplicación.

➔ Permiten la comunicación privada entre varios hilos del mismo proceso, sin solicitar
intervención del S.O. (es más rápida)

➔ Mayor eficiencia en el cambio entre hilos (del mismo proceso)

➔ Mayor eficiencia en la creación de un Hilo que en la creación de un Proceso Hijo.

➔ Un Proceso Multihilo puede recuperarse de la “muerte” de un Hilo, pues conoce los


efectos de esta, y toma su espacio de memoria (excepto para el main). Se puede recuperar de
la muerte de un hilo: si un hilo se muere el resto deberian de seguir ejecutandose (pero al
estar todos compartiendo recursos tambien genera desestabilidad en lo demas)

➔ Son más livianos

DESVENTAJAS
➔ Cuando un Proceso “muere” todos sus Hilos también, pues los recursos de Proceso son
tomados por el Sistema Operativo.

➔ Cuando un hilo muere, no se liberan automáticamente todos sus recursos

➔ Un problema en un hilo, puede afectar al resto

➔ No hay protección entre los distintos hilos

KLTs VS ULTs
KLT:

● El SO los conoce, por los que los puede planificar

● El cambio entre KLTs es más lento (interviene SO)

● Si un KLT se bloquea, cualquier KLT puede continuar

● Pueden ser ejecutados en paralelo en múltiples CPUs ya que son unidades


independientes de ejecución

ULT:

● El SO “no los ve”, sino que son administrados por una biblioteca en nivel de usuario

● El cambio entre ULTs (del mismo KLT) es más rápido (no interviene SO)

● Si un ULT se bloquea, todos los ULTs asociados a la misma unidad de planificación se


bloquean

● No permite aprovechar de ejecución en paralelo en caso de múltiples CPUs


PPT 4: Planificación Procesos
DIAGRAMA DE ESTADOS
Se le agrega los estados suspendido en espera y suspendido

SWAPPING
Permite aprovechar mejor la RAM (al quitarle procesos hay más espacio para otros procesos) y
un mejor uso de la CPU

CONCEPTOS Y CLASIFICACIÓN
El planificador tiene como objetivo asignar procesos para ser ejecutados de tal forma que se
cumplan los objetivos del sistema

PLANIFICADOR DE LARGO PLAZO


Aquel que se encarga de asignar los procesos nuevos y que estos sean admitidos por el sistema
(de un estado nuevo a listo). Además de que cuando terminan de ejecutar completamente
pasarlos a finalizados y liberar los recursos correspondientes.

PLANIFICADOR DE MEDIANO PLAZO


Aquel que se encarga de asignar aquellos procesos que ocupan un lugar en RAM y están
esperando que se cumpla cierto evento o que se haga cierta E/S, que pasen a estar
suspendidos en espera en un medio de almacenamiento secundario para una mejor
aprovechación de la CPU. También, una vez que el evento ocurrió se encarga de
pasarlos de suspendido listo a Listo.

PLANIFICADOR DE CORTO PLAZO


Se encarga de asignar los procesos ya admitidos en el sistema para que estos se ejecuten de tal
forma que el objetivo del sistema se cumpla (de pasar del estado listo a en ejecución)

PPT 5: Algoritmos de Planificación a corto plazo


FIFO
Algoritmo que atiende de acuerdo al orden de llegada (por lo que desde ese punto de vista es
bastante justo), es sin desalojo (únicamente se replanifica cuando la CPU es liberada
voluntariamente por el proceso o el proceso en cuestión finaliza). Tiene poco overhead, si los
procesos llegan de forma tal que están ordenados de menor ráfagas de ciclo de CPU hay poco
tiempo de espera (en caso contrario puede haber mucho) y es bastante simple.

SJF
Sin desalojo
Algoritmo sin desalojo que atiende a los procesos en base a cuál de ellos posee menor ráfaga
de CPU y ante un empate el orden de llegada desempata. Esto genera que se tenga en cuenta
el hecho de que no haya mucho tiempo de espera pero permite que en principio se pueda
generar starvation. Starvation, también conocido como inanición, consiste en negarle
continuamente los recursos a un proceso, lo cual puede surgir si continuamente se agregan
procesos de ráfagas más cortas que el proceso en cuestión este será continuamente aplazado
al darle prioridad a los otros. También, al igual que en FIFO, al ser sin desalojo puede generarse
que un proceso monopolice la CPU.

CS MS
CS MS => IO y FIN de IO
CS MS => FIN DE Q

Fin de Q se atiende primero a Fin de IO

Con desalojo (SRT)


Algoritmo que prioriza aquellos procesos con menor ráfaga de CPU y que replanifica cada vez
que un proceso llega, cuando un proceso libera voluntariamente la CPU, cuando un proceso
finaliza y cuando un proceso llega por una interrupción de E/S.

Con estimación (más real, sin estimación es una idealización):

Est(n+1) = 𝝰 R(n) + ( 1 - 𝝰 ) Est(n)

Cuanto menor sea el alfa más tiende a priorizar la historia general de ejecución (la estimación)
y no tanto las ráfagas reales más recientes. Por lo tanto las estimaciones tardan en adaptarse a
los nuevos tamaños de ráfagas. Mientras que con un alfa más grande la adaptación se produce
más rápido.

HRRN
Es un algoritmo en el que se tiene en cuenta el tiempo que se encuentra en espera cada
proceso y, además prioriza según las ráfagas de CPU. Es sin desalojo siempre porque sino
cambiaría continuamente el Response Ratio (RR) calculado y generaría mucho overhead (más
del que ya hace) al cambiar continuamente de procesos y hacer muchos cambios de contexto.

RR (Round Robin)
Algoritmo que desaloja los procesos según un Q (quantum) predeterminado, replanificando
únicamente si estos liberan la CPU voluntariamente o si se termina el quantum.

Si el quantum es pequeño puede generar mucho overhead (mucho context swich) pero si es
muy grande puede generar que un proceso monopolice la CPU. Este permite, con un quantum
moderado, que todos los procesos terminen ejecutándose (todos juntos, “a la par, no
literalmente”).

VRR
Algoritmo con desalojo en donde hay dos colas (con distinto quantum) permitiéndole dar
prioridad a los procesos con ráfaga más corta.
COLAS MULTINIVEL
En vez de tener una sola cola ready, tener varias a las que los procesos los vamos asignando a
las distintas colas según su prioridad. Para ello hay que identificar los tipos de procesos.

Cada cola tiene su algoritmo de planificación pero por fuera se realiza una meta planificación
con un algoritmo con desalojo por prioridades.

COLAS MULTINIVEL FEEDBACK


El objetivo es otro que las colas multinivel: a todos los procesos se los mete por la primer cola
(mas prioritaria), es decir, entran por el mismo canal y luego se determina su prioridad, y se
determina una condición para que baje o suba a otra cola menos/más respectivamente
prioritaria.

PPT 6: Planificación con hilos


Que ULT sigue? Depende quien haya hecho la syscall de IO

 El mismo Ult? Sigue el Ult que se estaba planificando antes, la biblioteca no puede
replanificar
 Un wrapper de la biblioteca => el Ult que, según el algoritmo de la biblioteca, tenga
que ejecutarse.

Al bloquearse un ULT se bloquea todo el KLT o Proceso asociado. Para que esto no ocurra no se
debería contar al SO que estamos bloqueados => Jacketing (mientras que un ULT pueda
ejecutar que lo haga).

PPT 7: Sincronización
DEFINICIÓN CONDICIÓN DE CARRERA
Situación en la que se encuentran aquellos procesos / hilos que manipulan de forma
concurrente datos compartidos de tal forma que el resultado de la ejecución depende de un
orden en particular en que se ejecutan.

¿CÓMO TIENE QUE SER LA REGIÓN CRÍTICA?


La región crítica debe ser:

- Lo más chica posible.


- Debe contener el recurso compartido y utilizado concurrentemente por los procesos /
hilos en cuestión.
- Debe de ejecutarse atómicamente

¿CUÁNDO PUEDO TENER UNA CONDICIÓN DE CARRERA?


Se puede tener una condición de carrera cuando AL MENOS uno de los procesos / hilos que
manipulan concurrentemente datos compartidos modifica alguno (lo escribe). Si la única
operación sobre dichos datos es Read entonces no puede haber condición de carrera.

TIPOS DE PROCESOS ¿CUÁLES PUEDEN LLEGAR A ESTAR EN


CONDICIÓN DE CARRERA?
Existen distintos tipos de procesos entre los cuales se encuentra:

- Procesos independientes: que no afectan ni deben ser afectados por los demás por lo
que no pueden llegar a estar en condición de carrera.
- Procesos cooperativos: que poseen un fin en común y para ello pueden comunicarse
de dos formas:
o Paso de mensajes: a través de syscalls lo cual es bastante lento pero impide
que pueda ocurrir estar en condición de carrera.
o Mediante memoria compartida: puede generar que los procesos estén en
condición de carrera si se manipulan los datos de forma concurrente y al
menos uno los escribe (modifica)
- Procesos competitivos: no tienen un objetivo en común pero si un sector de memoria
compartida que genera que puedan estar en condición de carrera.

REQUERIMIENTOS PARA SOLUCIONAR EL PROBLEMA DE LA


SECCIÓN CRÍTICA
Para solucionar el problema de la sección crítica se debe garantizar:

- Mutua exclusión: solamente un proceso / hilo puede acceder a la sección crítica,


- Progreso: consiste en que entre los procesos / hilos van a competir para acceder al
recurso que se encuentra en la sección crítica.
- Espera limitada: consiste en que si bien solo un proceso / hilo puede acceder a la
sección crítica y está bien que un proceso espere para poder hacerlo, en algún
momento pueda acceder (que la espera sea limitada, no infinita).
- Velocidad de los procesos: que la solución no dependa de la velocidad en la que los
procesos / hilos acceden a la sección crítica.

SOLUCIONES POSIBLES (NOMBRARLAS Y EXPLICARLAS UN


POCO) A NIVEL SW, HW Y SO
A nivel SW la solución de Peterson: cumple con los requerimientos pero se encuentra limitado
a dos procesos.

A nivel HW:

- Deshabilitar las interrupciones: debido al hecho de que para que ocurra una condición
de carrera debe pasar un cambio de hilo/proceso (generado por una interrupción)
definido por el planificador. Esta solución a bajo nivel en general es usada en entornos
de un procesador debido a su simplicidad (uno deshabilita las interrupciones, ejecuta
la sección critica, y luego las habilita). Pero en entornos de multiprocesador no se
aplica debido a que:
o En primer lugar es muy costoso enviarle a cada CPU una señal para que se
deshabiliten las interrupciones (el proceso tarda más en ingresar a la SC
debido hay que esperar que todas las CPU las deshabiliten) y luego habilitarlas.
o Generaría un retardo al no poder atender interrupciones y si una es de gran
importancia (no enmascarable) no se podría atender.
- Instrucciones atómicas (Test and Set): se ejecuta la instrucción como una unidad
(atómica) utilizando espera activa. Es por esto que son eficientes también en entornos
de multiprocesador y sencillas de usar pero no todos los sistemas tienen este soporte.

A nivel SO:

- Semáforos: son variables enteras que únicamente pueden ser utilizadas mediante dos
funciones atómicas (dos syscalls): wait y signal. Existen distintos tipos de semáforos
tales como los:
o Binarios: permiten que haya dos estados (ocupado 0 o disponible 1).
o Contadores: permiten que únicamente se pueda acceder a cierta cantidad de
instancias de un recurso.
o Mutex: permiten la mutua-exclusión. Siempre se inicializan en 1.

Los semáforos pueden utilizarse con espera activa o no (bloqueo).


¿Cuándo se debería usar la espera activa?
o Si la Región Crítica es muy chica (lo cual hace que la espera sea mínima).
o Si se pretende evitar que haya mucho overhead (al bloquear/desbloquear
procesos se generan muchos cambios de contexto).
o Si es un entorno multiprocesador, es decir, hay más de una CPU.

¿Cómo pueden utilizarse los semáforos?


o Para cumplir mutua-exclusión.
o Para una ejecución en un orden en específico.
o Para limitar la cantidad de accesos a un recurso.
o Para una ejecución donde haya procesos/hilos productores y otros
consumidores.

Hay que recalcar que a veces los semáforos pueden causar una inversión de
prioridades si el algoritmo utilizado por el planificador de corto plazo es por
prioridades (lo cual es un problema). Esto significa que un proceso P3 con mayor
prioridad que otro P2 no pueda ejecutar (se encuentre bloqueado) debido a que otro
proceso P1 desalojado previamente porque llego otro proceso con mayor prioridad P3
le bloquea algún recurso compartido que requiere y por lo tanto P2 teniendo menor
prioridad ejecute primero. Para resolver esta situación existe la herencia de
prioridades, en este caso P1 cuando P3 requiere el recurso compartido hereda la
prioridad de dicho proceso P3 termina de ejecutar (liberando dicho recurso) apra que
así el recurso con mayor prioridad ejecute antes que el otro con menor prioridad P2.
- Monitores: mecanismo que provee mutua exclusión al ser el único punto de acceso a
un recurso compartido (en vez de acceder directamente a la variable se accede a
través del monitor asegurando y abstrayendo la lógica de la sincronización). El monitor
va a tener en forma interna ese recurso compartido y expone de forma publica una
interfaz de lo que se pueda hacer sobre dicho recurso. De esta forma nos aseguramos
de que cada una de las funciones que afectan a la sección critica, estarán sincronizadas
en sí.

SEMÁFOROS IMPLEMENTACIÓN
Un semáforo es una variable entera que es accedida únicamente a través de 2 syscalls (2
funciones atómicas).

Esta solución se puede implementar con o sin espera activa (con bloqueo en caso que no).

¿CON ESPERA ACTIVA O CON BLOQUEO?


En ciertas situaciones es mejor utilizar la espera activa:

1. Debido a que usar los semáforos con bloqueo genera que haya muchos cambios de
contexto (más overhead) y ahorra el bloqueo/desbloqueo
2. Si hay más de una CPU
3. Cuando la sección crítica es muy chica y el tiempo que se espera en el while es más
corto.

TIPOS DE SEMÁFOROS
Mutex: permiten garantizar la mutua exlusión, se los inicializa siempre en 1.

Binarios: permiten garantizar cierto orden de ejecución (tienen dos estados únicamente: libre
u ocupado)

Contadores: cuando hay n instancias de un mismo recurso.

USOS DE SEMÁFOROS
- Mutua exclusión
- Ordenar una ejecución
- Limitar el acceso a cierta cantidad de instancias
- Producto-consumidor (donde un proceso consume y otro genera recursos)

INVERSIÓN DE PRIORIDADES EN SEMÁFOROS


En un sistema en el cual usa semáforos y además el algoritmo utilizado por el planificador a
corto plazo es por prioridades. Sin importar que nosotros con los semáforos definimos el orden
de ejecución de procesos (si acceden a una sección crítica), a veces puede generar problemas.
Es por esto que un proceso puede heredar prioridades de otro con tal que libere un recurso
que el otro proceso, con mayor prioridad, necesita para poder ejecutar.

PPT 8: Deadlock
RECURSOS DEL SISTEMA
Los sistemas poseen recursos limitados. Estos pueden ser:

- Recursos consumibles: una vez usados no pueden ser devueltos al SO una vez pedidos.
Por ejemplo: interrupción, señal, mensaje, info en IO buffers
- Recursos reusables: algo que le puedo pedir al sistema, que mediante una syscall lo da
(me los asigna), y luego lo puedo devolver una vez usados. Por ejemplo: Memoria,
archivos, dispositivos IO.

Los procesos para utilizar los recursos deben pedirlos y luego liberarlos a través de llamadas al
sistema:

- Recursos gestionados a través del SO -> open/close - malloc/free


- Recursos no gestionados por el SO -> wait /signal

Los recursos pueden tener más de una instancia (cualquiera satisface a un proceso por igual).
Esto quiere decir que entre recursos lo que importa es cuál es cuál, pero entre instancias
importa la cantidad.

DEFINICIÓN DEADLOCK
Situación en la que los procesos / hilos se encuentran en interbloqueo esperando que suceda
un evento producto de la actividad de otro de los procesos en cuestión (que también está
bloqueado).

GRAFOS DE ASIGNACIÓN DE RECURSOS


Modelo con arcos (flechas) y nodos (recursos y procesos/hilos) que representa la situación en
la que se encuentra un sistema en un momento determinado.
Si la flecha que va de un proceso/hilo a un recurso es una solicitud y flecha que va de un
recurso a un proceso/hilo es una asignación.

Si el grafo no contiene ningún ciclo → No hay deadlock

Si el grafo contiene un ciclo → Puede existir un deadlock (depende de la cantidad de instancias


de los recursos involucrados)

Si cada recurso tiene una instancia y hay un ciclo → Hay un deadlock

CONDICIONES NECESARIAS
Para que haya deadlock se deben cumplir todas estas condiciones:

- Exclusión mutua: un único proceso / hilo puede acceder al recurso compartido en


cuestión a la vez
- Retención y espera: el proceso / hilo en cuestión retiene recursos y se encuentra
esperando a que otros procesos / hilos con los que tiene una sección de memoria
compartida liberen recursos para seguir ejecutando.
- Sin desalojo: los recursos no pueden ser desalojados, los procesos que los retienen
deben hacerlo voluntariamente
- Espera circular: Debe existir un conjunto de procesos en espera, tal que cada uno
espere un recurso retenido por el siguiente.

TRATAMIENTO DE DEADLOCK
El deadlock puede tratarse de multiples maneras entre las cuales se encuentran:

- La prevención o evasión: evitar que el deadlock ocurra en el sistema.


- La detección y recuperación de este mismo: permitir que el sistema entre en estado de
deadlock, detectarlo y realizar una recuperación.

EN DONDE SE APLICA CADA TÉCNICA


PREVENCIÓN
En la petición de los recursos. Trata de evitar que se cumpla alguna de las condiciones
previamente dichas (con que una no se cumpla, no se produce deadlock) al definir políticas a la
hora de pedir recursos.

o Mutua exclusión: evitar la mutua exclusión sobre recursos compartibles. Ej:


apertura de archivos en modo lectura.

o Espera y retención
 Los procesos pidan y se le asignen previamente todos los recursos que
vaya a usar.
 Un proceso para pedir un nuevo recurso tenga que liberar todos los
que retiene (ineficaz)

o Sin desalojo
 Si un proceso pide un recurso que no está disponible, debe esperar y
se liberan todos los recursos que tenía asignados.
 Si un proceso pide un recurso retenido por otro proceso en espera, los
mismos son desalojados y asignados al primero (si un recurso que
necesito lo está usando otro que está bloqueado, se lo saco)

o Espera circular: requerir que los recursos se pidan en orden.

Estas estrategias de prevención para un sistema de uso normal (con múltiples procesos) no son
las más utilizados ya que la experiencia del usuario sería mala. Para ellos se utiliza más las
estrategias de evasión y detección. Sin embargo, Para un sistema cerrado en que se sabe que
cosas se deben hacer, en qué orden y que se necesita se utiliza la estrategia de prevención.

EVASIÓN
Asignación de los recursos en cuestión.

- El proceso debe indicarle al SO cuáles van a ser los recursos máximos que puede llegar
a solicitar durante su tiempo de vida.
- Ante cada solicitud, se analizará si se le asigna el recurso al proceso o si se lo hace
esperar. Para tomar una decisión se realiza una simulación (se utiliza el algoritmo del
banquero) teniendo en cuenta las posibles futuras solicitudes y liberaciones de
recursos por parte de todos los procesos del sistema.
- Mantiene al sistema siempre en Estado Seguro
o Un estado es seguro si el sistema puede asignar recursos a cada proceso (hasta
su máximo) en determinado orden sin que eso produzca un deadlock (existe
una secuencia segura). Con que haya una secuencia segura es suficiente
o Si el estado es seguro → no existe ni existirá deadlock
o Si el estado es inseguro → podría ocurrir deadlock
- Sólo se asigna un recurso si dicha asignación deja al sistema en estado seguro.
- Se podría utilizar un grafo de asignación de recursos para analizar el estado del sistema

ALGORITMO DEL BANQUERO


Los procesos al ingresar al sistema declaran la cantidad máxima de cada uno de los recursos
que podrá requerir.

Cuando un proceso solicita un conjunto de recursos, el sistema debe determinar si la


asignación de dichos recursos dejará al sistema en un estado seguro. En caso afirmativo, los
recursos se asignarán; en caso contrario, el proceso tendrá que esperar hasta que los otros
procesos liberen los suficientes recursos.

Estructuras necesarias:

- Matriz de peticiones máximas


- Matriz de recursos asignados
- Matriz de necesidad (PM – RA)
- Vector de recursos totales (Disponibles + Total Asignados)
- Vector de recursos disponibles

Ante cada solicitud se debe simular la asignación, actualizando las estructuras adecuadas, y
luego analizar si existe una secuencia segura.

DETECCIÓN
Supone un costo y se debe determinar la frecuencia en la que se verifica si el sistema se
encuentra en un estado seguro (con las matrices del algoritmo del banquero menos las
peticiones máximas)

Recuperación del deadlock:

- Puede ser mediante la finalización de todos los procesos.


- Finalización de procesos pero de a poco (eligiendo victimas que pueden ser
potencialmente aquellos que generan el deadlock)
- Desalojo de los recursos, asignárselos a cada proceso de a poco.

Todas estas posibilidades conllevan un costo muy alto.

LIVELOCK
Es una situación similar al deadlock en la cual un conjunto de procesos no puede progresar en
la ejecución de su trabajo pero, en este caso, los procesos siguen ejecutándose lo cual es más
difícil de detectar.

PPT 9 MEMORIA PRINCIPAL


¿QUÉ ES?
Es una gran matriz donde se alojan direcciones que pueden ser de instrucciones que se
ejecutan o de datos sobre los que se operan.

Esta tiene un espacio reservado para el sistema operativo (kernel space) y otro espacio para
distribuir los procesos de usuario (user space). Se tiene un espacio reservado para el sistema
operativo debido a que al saber que cosas va a estar utilizando le conviene utilizar otra
estrategia (de como guardar esa información y administrar dicha porción de memoria)
respecto a lo que usa para los procesos (que al ser más general no sabe que es lo que van a
necesitar).

VELOCIDAD DE ACCESO A LOS MEDIOS DE ALMACENAMIENTO


VISTO DESDE LA CPU
Registros: al ser el medio de almacenamiento más inmediato a la CPU, son los más rapidos.

Caché: almacenamientos intermedios que poseen un conjunto de subdatos, la idea es poder


tener una información reducida que se utiliza frecuentemente para poder agilizar esos
accesos.

RAM: es donde en general se cargan los procesos para poder ser ejecutados.

Disco: es bastante lento al ser mecánico.


REQUERIMIENTOS QUE DEBE CUMPLIR EL SO PAR DAR ALGÚN
SERVICIO EN MEMORIA
La gestión de memoria es una de las cosas que debe ser cumplida por el SO. Para ello van a
haber ciertos requerimientos:

- Realocación: dependiendo de cómo se asignen las direcciones en memoria…


o ¿Qué tanto le costará al SO mover procesos de un lugar a otro como por
ejemplo hacer swapping?
o ¿Dónde se guardará el proceso si es quitado de memoria (por ejemplo si es
llevado a disco y devuelto a memoria)? ¿En el mismo lugar de memoria donde
estaba o en otro?
- Protección que debe de garantizar el SO para asegurar que procesos no autorizados no
accedan al recursos ajenos (la memoria compartida debe de aclararse explícitamente)
- Compartir memoria: debe de explicitarse al SO y este mismo dar servicios para poder
realizarlo.
- Organización lógica: cómo se va a ver la estructura de la memoria lógicamente.
- Organización física: cómo va a estar realmente estructurada la memoria.

Para estas dos últimas: ¿Qué tan bien se ocupa el espacio?

REASIGNACIÓN DE DIRECCIONES Y TRADUCCIÓN DE LAS


MISMAS
Las direcciones en el código son simbólicas (no son absolutas de memoria).

¿En qué momento se pueden definir las direcciones? Es decir, ¿En qué momento se mapean
las direcciones simbólicas y pasan a ser representadas por direcciones absolutas?

La reasignación de direcciones (de instrucciones y datos) puede ser:

- En tiempo de compilación: en el momento que se compila el programa se reemplazan


las direcciones simbólicas por direcciones absolutas de memoria. En este caso, la
ejecución del programa sería muy rápida debido a que cuando se desee acceder a
cierta dirección de memoria, se hará directamente al ser ya una posiciones reales de
memoria (al traducción, el entendimiento que debe realizar en el medio seria directo).
Sin embargo, realizar la reasignación de direcciones en tiempo de compilación genera
ciertos problemas ya que no se desea ejecutar un determinado programa siempre en
un mismo lugar de memoria debido a que si no está disponible se debe:
1. esperar para poder ejecutarlo.
2. matar procesos para que se libere dicha sección de memora
3. recompilar para que se le asigne a cada recurso utilizado otra dirección de
memoria y así poder ejecutarlo. Lo cual podría generar que vuelva surgir el
problema.

La dirección lógica = dirección física.

- En tiempo de carga: luego de compilar las direcciones de memoria siguen siendo


reubicables (simbólicas, no son direcciones absolutas en memoria) y recién cuando se
las carga se reasignan las direcciones y pasan a ser absolutas. Esto tiene como ventaja
el hecho de que la ejecución sigue siendo muy rápida al igual que cuando se reubican
las direcciones en tiempo de compilación y cuando se cargue una dirección en un lugar
de memoria este no va a ser siempre el mismo (debido a que el código compilado no
posee una dirección absoluta de memoria). Sin embargo, tiene como desventaja que si
en el medio de la ejecución se desea mover un proceso de un lugar a otro (para por
ejemplo aprovechar mejor el espacio) no se podría, se debería volver a cargar dicho
proceso (y reemplazar todas las direcciones ya absolutas) y se perdería todo el avance
hecho.

La dirección lógica = dirección física.

- En el momento de ejecución: las direcciones absolutas se calculan recién en tiempo de


ejecución. Es decir, se tiene un programa. Lo primero que se hace es compilarlo (sigue
teniendo direcciones reubicables), luego se carga (siguen quedando como direcciones
relativas) y recién cuando se quiera ejecutar (cuando se desee acceder a algo en
memoria: buscar cierta instrucción/dato) se realiza la transformación (la reasignación)
para que la memoria entienda a que dirección nos referimos.

En caso que se reasigne en tiempo de ejecución la dirección lógica (DL) es distinta a la


dirección física (DF). Es decir, si se le pasa dicha DL a la RAM devolverá cualquier cosa, por
lo que se debe realizar una traducción en el medio para poder interpretarla. Para ello se
necesita un componente que traduzca: la Unidad de Manejo de Memoria (MMU) que
realiza la traducción de direcciones lógicas y físicas, es decir, es un componente que se
encuentra en medio del acceso de la CPU a una dirección y del paso de dicha dirección a
memoria, para que, una vez traducidos las direcciones lógicas, a la memoria principal le
llegue algo que entienda.

Direcciones lógicas (DL): son aquellas que cuando uno va ejecutando se trata de acceder.

Direcciones físicas (DF): direcciones válidas para el HW (memoria RAM)

ASIGNACIÓN CONTIGUA
Consiste en que toda la imagen del proceso debe de encontrarse junta en memoria, de forma
contigua.

PARTICIÓNES FÍJAS
Estrategia de memoria en la que la imagen del proceso se encuentra toda contigua en
memoria. La memoria se encuentra dividida en N particiones fijas de X tamaño y cada proceso
que se desea ejecutar se aloje en una de dichas particiones. El que haya N particiones fijas
hace que el máximo grado de multiprogramación sea de N (porque no podrán haber más de N
procesos en memoria) y que dichas particiones tengan un tamaño fijo hace que se limite el
tamaño que pueden tener los procesos (no pueden excederse de ese X tamaño). Además, los
procesos rara vez tendrán el mismo tamaño que las particiones por lo que seguramente se
generará un espacio que la memoria no aprovechará (no puede ser asignado a otro proceso),
es decir, habrá fragmentación interna.

Por otra parte, los procesos serán muy fáciles de manipular y encontrar ya que únicamente se
debe saber cuál es el tamaño de todas las particiones y en que partición se encuentra el
proceso (información que se guarda en el PCB del mismo).

PARTICIONES DINÁMICAS
Estrategia de memoria en la que la imagen del proceso se encuentra toda contigua en
memoria pero que, a diferencia de particiones fijas, la memoria no se encuentra dividida en
particiones sino que el proceso se cargará en memoria tal cual el tamaño que tenga. Esto hace
que no se limite ni el grado de multiprogramación ni el tamaño de los procesos (obviamente
que el espacio en memoria es limitante pero en si la estrategia de memoria no lo limita). Al
cargar todo el proceso con su tamaño (lo cual no es fijo porque no todos los procesos poseen
el mismo tamaño) hace que estos sean más complejos de manipular ya que ahora no se
requerirá únicamente de la base en la que se encuentra el proceso sino saber su tamaño para
ver si las direcciones de memoria a las que se pretenden acceder son válidas para él. Por otro
lado, si bien no habrá fragmentación interna, al ir cargando y finalizando procesos
seguramente queden huecos entre ellos que ninguno podrá aprovechar, es decir, habrá
memoria desperdiciada lo cual se denomina fragmentación externa. De vez en cuando, sin
abusarse porque es alto el costo, se puede ir compactando los procesos de tal forma que los
espacios libres en memoria queden todos juntos en un mismo lugar.

COMPACTACIÓN
ELECCIÓN DE DONDE ASIGNAR EL PROCESO
En cuanto a la elección de donde asignar el proceso esta se puede hacer:

- El primer espacio donde entre.


- Luego de la úlitma asignación, el primer espacio donde se encuentre.
- El mejor ajuste: consiste en cargarlo en el espacio más pequeño en memoria donde
entre, lo cual hace que (al seguramente no tener el mismo tamaño) se genere un
espacio bastante chico donde rara vez un proceso podrá entrar y así generará
fragementación externa.
- El peor ajuste: consiste en ubicarlo en el hueco más gran donde pueda entrar.

PAGINACIÓN
Estrategia de memoria donde la imagen del proceso ya no se debe de cargar de manera
contigua sino que puede dividirse. Esta consiste en dividir la memoria en frames (marcos) de
igual tamaño (que para administrar que está libre y que no se puede tener un vector de bits,
un bitmap de los marcos libres) y al proceso que se desea cargar en páginas de igual tamaño a
los frames. De esta forma, al igual que particiones fijas, habrá fragmentación interna pero en
menor medida ya que solo habrá fragmentación interna en la última página del proceso.
Obviamente dependiendo del tamaño de la página se tendrá mayor o menor fragmentación
interna (cuanto más chica menos y cuanto más grande más). Si son más chicas las páginas los
procesos van a tener más páginas por lo que las estructuras para administrarlas van a ser más
grandes por lo que...

- Que las páginas sean chicas sería una ventaja en cuanto a la fragmentación interna
pero una desventaja en cuanto a la administración de éstas (es más costoso).
- Lo contrario para las páginas grandes (administrarlas va a ser más sencillo debido a
que son menos pero potencialmente va a tener más fragmentación interna con la
limitación de que es solo la última página).

El costo de esta mejora es que el acceso a una dirección dentro de un proceso (pasar de una
DL a una DF) es más complejo (la traducción no será tan lineal):

Cuando se tiene particiones fijas, no se necesitaba la base sino que con saber el número de
partición se podía calcular (porque todos poseen el mismo tamaño). Para paginación es lo
mismo, no se requiere saber la base de cada página sino que con saber en qué marco está ya
se puede calcular la dirección de la base (se multiplica el número de marco por el tamaño de la
página que es igual al del marco). Sin embargo para esto se requiere de una tabla de páginas
(estructura que estará en una sección separada al proceso debido a que la primera va a ser una
estructura del SO) por cada proceso (cuya dirección en memoria será guardada en el PCB
inicialmente pero una vez creado el proceso y al querer cargar una DL, el puntero se trasladará
a los registros para que esté más al alcance) en dónde el índice sea el número de páginas y
cada página tenga asignada el frame correspondiente.

Por lo que para acceder a una página determinada en memoria se deben realizar 2 accesos a
memoria (1 al PCB y otra a la tabla de páginas) lo cual es más lento que en las otras estrategias.
Es por esto que para mejorar este tiempo se puede utilizar una caché (estructura extra a nivel
de HW que posee un espacio limitado) llamada TLB (Translation Look-aside Buffer) que
permite que el acceso a las páginas sea más rápido. La TLB es una memoria asociativa de alta
velocidad (caché HW) dónde se guardan las entradas de la tabla de páginas para agilizar el
proceso de traducción y el acceso efectivo a memoria. Puede, además, guardar en cada
entrada un identificador del proceso por protección de otros procesos y para no tener que
vaciar la caché al cambiar de proceso.

Por otro lado, en paginación compartir memoria, a diferencia de particiones fijas, es sencillo.
¿Por qué? Porque básicamente lo que se necesita que compartan es un frame. Entonces lo
único que se requiere es que a nivel traducciones (mapeo de tablas de páginas) dos páginas de
diferentes procesos apunten al mismo frame.

Entonces, si se requiere acceder a una dirección (que va a ser una DL) se debe interpretar la
página en la que está incluida y el desplazamiento dentro de esta misma (es decir, el offset). Y
una vez que se obtenga eso, con la página acceder a la tabla y recuperar el número de frame
para así calcular la base (con el tamaño de la página*frame) y con el desplazamiento la
dirección física dentro de la RAM.

Por último, si bien en paginación no se pretende limitar el tamaño de los procesos al ser las
tablas de páginas fijas y contiguas en memoria, limitan al proceso y quizás, si este es muy
grande, le impiden direccionar idealmente todo en la memoria. Es por esto que se realiza una
paginación jerárquica (lo cual complejiza aún más la estrategia), es decir, se pagína la tabla de
páginas.

TABLA DE PÁGINAS INVERTIDA


Es una estructura de tabla de páginas que ocupa menos espacio que las tablas de páginas
tradicionales.

Hay una tabla para todo el sistema (en lugar de una tabla por proceso) que está indexada por
marco en lugar de por página (hay tantas entradas como marcos en la memoria física). Es
decir, que el input (el índice) antes era el número de página y el output (el contenido) era el
frame en el que se carga y ahora es al revés.

El problema es que al cambiar el punto de acceso, nuestro dato sigue siendo el número de
página (cuando se accede a una dirección lógica lo que se obtiene de ella es el número de
página al que se está accediendo). Para solucionarlo lo que se hace en la tabla de páginas
invertida es buscar uno por uno la página, por lo que si bien ocupa menos espacio, el acceso no
es directo (es una búsqueda lineal). Por cada uno de los accesos se debería ir recorriendo
secuencialmente todas las entradas de la tabla (frames) para poder encontrar donde está.

Otro problema de este tipo de tablas, es el compartir memoria (a priori no lo soporta).


SEGMENTACIÓN
Estrategia de memoria donde la imagen del proceso no se carga de manera contigua en
memoria, está dividida lógicamente (de manera no transparente para el usuario) según sus
componentes por ejemplo: los datos por un lado, el código por otro, el stack por otro y así. A
diferencia de paginación no posee fragmentación interna sino que posee fragmentación
externa pero en menor medida que particiones dinámicas.

Cada segmento puede presentar distintos permisos (R, W , X).

La dirección lógica está compuesta por: NRO SEGMENTO + OFFSET

SEGMENTACIÓN PAGINADA
Se divide la RAM en frames y a la imagen de los procesos en segmentos (es decir, está dividida
lógicamente) que se encuentran paginados lo cual hace que únicamente haya fragmentación
interna (un poco más que en paginación porque no es en la última página de la imagen total
sino en la última página de cada segmento del proceso). Además permite que cada segmento
pueda tener permisos distintos (R, W, X). Sin embargo, su administración es mucho más
compleja.

PPT 10 BUDDY SYSTEM


Nueva técnica que asigna toda la imagen del proceso a una única partición (sigue siendo
contiguo) pero que al tener algunas particularidades de particiones fijas y particiones
dinámicas hereda sus problemas (fragmentación interna y externa) pero de forma mitigada.

Define el tamaño de partición a asignar dinámicamente pero con ciertos tamaños posibles
(potencia de 2):

Inicialmente, a la MP se la considera como un gran bloque libre. Cuando un proceso va a


cargarse en memoria se busca el bloque disponible potencia de dos más chico que permita
satisfacer la petición.

Cada vez que se divide en dos a un bloque para realizar la búsqueda los dos nuevos bloques
producto de la división serán buddies. Dos bloques A y B son buddies si:

- Poseen el mismo tamaño


- Están ubicados en forma contigua
- dirA = dirB XOR tamA && dirB = dirA XOR tamB

Al liberar un bloque, hay que chequear si su buddy está libre. En caso afirmativo, ambos
bloques se consolidan en uno y luego se vuelve a chequear por su buddy (y así hasta que no
pueda hacerse o hasta que se consolidó toda la memoria). Una liberación puede generar 0 o
varias consolidaciones -> no es determinístico

Un bloque se encuentra compuesto por un header donde está toda su información (si está
libre y su tamaño, que al ser todos potencia de dos solo necesita tener guardado el exponente)
y los datos por otro lado.
Es en el header donde se debe de mirar para ver verificar si un proceso es buddy de otro y si
ambos están libres, es decir, para realizar la consolidación.

Hay distintas estructuras que se pueden utilizar para realizar este esquema (técnica):

- Árboles binarios
- Listas de particiones libres de tamaño X
- Bitmap de bloques de orden i

VENTAJAS:

- Mayor velocidad de consolidación de bloques y por lo tanto compactación


o Los bloques son más fáciles de ubicar (XOR)
o Gracias a la rápida consolidación se requiere menos compactación.
- Utilización de bloques de tamaño controlado:
o Menor fragmentación interna que particiones fijas: Ya que se puede aproximar
en forma más precisa al tamaño de memoria requerido.
o Suele presentar menor fragmentación externa que particiones dinámicas: La
alocación es más controlada y no depende del tamaño exacto solicitado por el
proceso. (Se puede definir un límite mínimo)
o Menos espacio de administración: Al conocer el nodo del árbol (o el orden i del
bloque) ya se puede saber su dirección y su tamaño.
o Mayor velocidad de búsqueda de bloque libre.

DESVENTAJAS:

- Presenta los problemas de tanto particiones fijas como dinámicas


o Fragmentación interna y externa.
- A pesar de que la compactación es más rápida que en particiones dinámicas
igualmente hay que hacerla, con lo cual se genera un overhead.
- Una consolidación puede desencadenar una gran secuencia de consolidaciones si hay
muchos bloques libres, lo cual hace a la ejecución del algoritmo no determinística.

PPT 11 MEMORIA VIRTUAL


PROBLEMA
Realmente no siempre se tiene todo el proceso cargado en memoria o swappeado en disco.
Realizar eso trae ciertos problemas:

1. Nos limita el tamaño máximo de los procesos. Si se tiene procesos grandes no podrían
entrar.
2. Limita también el grado de multiprogramación: si se debe cargar a los procesos
enteros (de new a ready por ejemplo) no se podrán cargar muchos.

OVERLAYING
Dentro de las primeras soluciones está el overlaying que consiste en dividir el programa en
partecitas definidas por el programador (analogía con segmentación). Había algunas partes
que debían estar si o si en RAM como el overlay driver (que administra las partecitas en las que
se lo divide) y la sección principal del proceso. Y otras partes, los overlays seccions, se iban
swicheando.
Esta solución no es a nivel SO sino que es a nivel programación: se optimiza la cantidad de
RAM que se utiliza definiendo ciertas partes del proceso (programa) que se determina cuando
se desean cargar y descargar.

Sin embargo, lo que se buscaba era una solución a nivel SO: manejar este problema de alguna
manera más transparente para el programador, es decir, que este no tenga que definir que
cargar y que no en la RAM. Sino que se le engaña al proceso haciendo que tiene todo el
espacio en memoria que requiere y por atrás el SO maneje que está en RAM y que no.

MEMORIA VIRTUAL
- Todo lo que es memoria virtual se realizará con paginación: es más cómodo para poder
swippear el tener todo dividido en páginas que hacerlo de otra forma (como por
ejemplo con particiones dinámicas que es mucho más complejo para definir que se
trae y que no de disco).
- La idea es: en la tabla de páginas además de tener un bit de validez se tiene un bit de
presencia. En caso de que la página sea válida y esté en la RAM que el bit de presencia
(que indica si la página está en la RAM) dirá en que frame está.
- Las instrucciones que se deben ejecutar tienen que estar en RAM

PAGINACIÓN BAJO DEMANDA


- Las páginas se cargan a memoria física sólo cuando se necesita: cuando un proceso
pase a READY va a estar completamente en swap y solamente se van a ir cargando las
páginas a RAM cuando se las necesite.
- El swapping es “lazy”: en vez de mover un proceso entero entre MP y SWAP se
mueven páginas.

Tiene como ventaja el hecho de que el tiempo de carga de los procesos disminuye, es mucho
más rápido ya que cuando un proceso se encuentra en ready no se debe de esperar a que
cargue todo sino que cuando comienza a ejecutar se van cargando las páginas necesarias y
arranca.

Como desventaja cada vez que se quiera acceder a páginas que están en swap ese acceso va a
ser más lento, el proceso va a tener que esperar a que esta página se cargue de swap a RAM.
PROCESO DE TRADUCCIÓN DE UNA DL A UNA DF

Cuando un proceso pide una página

Esta se la busca en la TLB. Si acierta (se hace HIT) se obtiene la dirección física.

En caso que no acierte se la busca en la tabla de páginas (RAM). Si la página está en la TP (el bit
de presencia es 1), se carga la página en la TLB y se obtiene la dirección física de esta misma.

En caso que no esté en la TP (bit de presencia = 0) se lanza una interrupción PAGE FAULT (que
es bloqueante, es decir, el proceso va a quedar bloqueado hasta que lo resuelva) que genera
un mode switch haciéndose cargo el SO. Se atiende la interrupción y se comprueba si la
dirección es válida o inválida para dicho proceso -> ¿Está dentro del espacio de direcciones del
mismo?

1. Si la referencia es inválida hay dos opciones:


a. Se finaliza el proceso.
b. Se envía algún mensaje de error para que lo maneje y tal vez siga con la
siguiente referencia a memoria.
2. Si la referencia es válida se busca un frame libre en RAM.
a. En caso que haya se…
i. …dispara una orden de lectura en disco para que el DMA lea la página
deseada y la cargue en el marco seleccionado. Además, se marca al
frame como ocupado (para que asñí no lo ocupe otra página) lanzando
así una interrupción de Fin de IO volviendo a hacerse un mode switch.
Se pone al bit de presencia de la página como 1 y se la agrega a la TLB.

Se vuelve a ejecutar la instrucción, es decir, se reinicia (el proceso


vuelve a pedir la misma página, pero ahora estará en la TLB). Como la
interrupción de page fault es bloqueante, todo el tiempo el proceso
estuvo bloqueado. Recién cuando se agrega la entrada a la TLB se
desbloquea y el planificador debe volver a elegirlo para ejecutar.

b. En caso que no haya frames libres se elige un frame víctima (según el


algoritmo y la política de sustitución de páginas) para reemplazar la página. Si
la página que queremos sustituir para ocupar el frame en el que se encontraba
(y queremos cargar la página nueva)…
i. …no está modificada…
1. se marca al frame como libre (por un periodo corto de tiempo)
y la página ausente. Después el DMA hace 2.a.i
ii. …está modificada se dispara una operación de escritura al disco (no se
puede simplemente sobrescribir debido a que se perderían los
cambios hechos), se lanza una interrupción de Fin de IO y luego se
hace 2.b.i.1

POLÍTICAS DE ASIGNACIÓN/SUSTITUCIÓN DE FRAMES


➔ Asignación de frames

◆ Fija -> un proceso siempre tiene asignado un número fijo de frames

◆ Dinámica -> el número de frames que tiene asignado un proceso puede


aumentar o disminuir (puede ir variando)

➔ Sustitución de frames (se quiere sustituir dentro de los frames asignados al proceso
en cuestión o no)

◆ Local -> las víctimas a elegir deben estar dentro del conjunto de frames
asignados al proceso

◆ Global -> se puede elegir como víctima cualquier frame (puede ser de otro
proceso)

FIJA-LOCAL: La más simple y ordenada


DINÁMICA- LOCAL: El SO le puede dar o sacarle más o menos frames a un proceso, segun lo
considere necesario pero a la hora de sustituir lo hará sobre los que tiene asignados en el
momento.

GLOBAL-FIJA: No se puede garantizar una asignación fija si se tiene una sustitución global. Si
desde un principio el SO determina que un proceso tiene una asignación fija de 10 frames, si
otro proceso viene y me quita uno, ya no estaría teniendo esos 10 frames.

THRASHING/SOBREPAGINACIÓN
Todo proceso utiliza un conjunto de páginas activamente durante un lapso de tiempo y
necesita que las mismas estén cargadas, al mismo tiempo, en memoria durante dicho lapso.
Entonces necesita un mínimo e indispensable número de frames que el SO le debe de asignar.

En un sistema donde el grado de multiprogramación es bajo por lo que el nivel de uso de CPU
también lo es, el aumento de la multiprogramación está bien implementado siempre y cuando
también tenga en consideración la cantidad de page faults (el rate) que comience a tener al
poner más procesos en memoria. Esto es así ya que si no se tiene en cuenta esto puede
generar que los procesos en cuestión no tengan la cantidad de frames que requiere para
ejecutar.

Thrashing (sobrepaginación) es la situación en la que un proceso tiene menos frames de los


que necesita para ejecutar y por lo tanto realiza muchos PFs (acciones de paginación) sin
realizar ningún trabajo útil. Como todos los procesos requieren de la MMU, se bloquearán
esperando ser atendidos por la misma, haciendo que caiga el uso de CPU y aumente el tiempo
de acceso efectivo a memoria.

- ¿Cómo se puede solucionar thrashing?

Bajar el nivel de multiprogramación ya sea:

o Matando procesos.
o Suspendiendo de forma total a los procesos (que estén totalmente cargados
en memoria).
- ¿Cómo se puede prevenir o atacar lo antes posible?

Ir mirando el rate de page faults o ir aproximando el conjunto de trabajo

LOCALIDAD – CONJUNTO DE TRABAJO


El conjunto de páginas que un proceso referencia activamente en un intervalo de tiempo (que
va a necesitar que estén en a la vez en RAM, no necesariamente contiguas). Es decir, cuantas
páginas puede necesitar un proceso por un lapso de tiempo.

Si le damos frames suficientes para acomodar su localidad, el proceso no entrará en thrashing.

Para ello se debe aproximar viendo "hacia atras" las últimas n referencias que se hicieron. Es
decir, se debe definir el tamaño de la ventana en la que se mira para atrás (cantidad de
referencias que se deben tener en cuenta). Si se aproxima muy seguido se genera mucho
overhead pero si se hace cada poco tiempo existe la posibilidad de que los procesos se dejen
mucho tiempo bloqueados o en thrashing.

ALGORITMOS DE SUSTITUCIÓN DE PÁGINAS


Cada vez que ocurra un PF habrá una operación de carga de una página y quizá otra de
descarga (puede que no haya ningún frame libre y se requiera sustituir a otra página). Si se
tiene que sustituir, ¿qué página elijo como víctima dentro del conjunto de frames que puedo
sustituir (según la política de sustitución)?

ANOMALÍA DE BELAMY
Consiste en desmentir la creencia que cuantos más frames tenga un proceso menos page
faults generará. Algunos algoritmos ante determinadas secuencias de referencias al aumentar
el número de frames sin embargo incrementan la frecuencia de PFs. Por ejemplo: en el
algoritmo FIFO se da la anomalía de que a pesar de tener más frames asignados, ante la misma
cadena de referencia de páginas podes tener más Page faults que con menos frames
asignados. Es decir, la creencia de que si uno le da más recursos a un proceso se comportará
mejor en FIFO puede llegar a ser mentira.

FIFO
Elige como víctima a la página que está cargada en memoria hace más tiempo

Se puede implementar:

- Guardando el instante en el que la página fue cargada -> se elige la que tiene el menor
valor
- Cola FIFO -> se elige la página que primero se agregó a la misma

Sufre de la Anomalía de Belady (solamente este algoritmo de susticione de páginas lo hace)

ÓPTIMO
Elige como víctima a la página que no vaya a ser referenciada por un mayor período de tiempo

Genera la mínima tasa de PFs posibles

No sufre de la Anomalía de Belady

Se utiliza a fines comparativos -> se puede saber cuántos más PFs genera otro algoritmo
comparado al Óptimo

LRU
Elige como víctima a la página menos recientemente utilizada (hace más tiempo que no se
referencia) -> utiliza el pasado reciente como una aproximación del futuro

Se puede implementar:

- Guardando el instante de última referencia de cada página -> se elige al que tiene el
menor valor
- Pila con números de págs -> con cada referencia se coloca la pág superior, se elige
como víctima la pág de la parte inferior

No sufre de la Anomalía de Belady (el único que lo hace es FIFO)

CLOCK
Está basado en FIFO, con un bit de referencia (Bit de Uso) trata de aproximar el algoritmo LRU

Un puntero indica cuál es la siguiente posible víctima (la cola es circular)

Primero se mira el bit de uso

- Si U = 0 -> es la víctima -> se reemplaza y se avanza el puntero


- Si U = 1 -> Se le da una oportunidad
o Se pone U en 0
o Se avanza el puntero

CLOCK MODIFICADO
Tiene en cuenta además del bit de Uso, al bit de Modificado

Trata de minimizar las descargas de páginas a disco

Teniendo al par (U , M)

- Se busca (0,0) avanzando el puntero pero sin poner U en 0


- Si no se encuentra, se busca (0 , 1) avanzando el puntero poniendo U en 0
- Si no se encuentra, se vuelve al paso a)

PAGE BUFFERING
Se mantiene un pool de frames libres que se utilizarán como buffer para que la operación de
escritura en swap (del proceso que se pretende sustituir) y la operación de lectura de la nueva
página (que se pretende poner en el frame que ocupaba la página modificada) se hagan en
paralelo.

Si bien se tienen que dejar algunos frames libres para formar este pool de frames buffers, en
vez de darle unos frames más al proceso u otros procesos (lo cual es una pequeña pérdida),
permite optimizar esas operaciones de disco (gran ganancia) cada vez que haya un PF y la
víctima que hay que sustituir esté modificada.

LOCKEO DE PÁGINAS
Al iniciar la IO se puede permitir habilitar un bit lockeo sobre el frame para que no pueda ser
reemplazado durante la operación.

Al finalizar la misma, el frame dejará de estar lockeado y podrá ser elegido como víctima de
sustitución nuevamente

Es decir, al hacerse una IO, el SO antes de decirle al DMA "hace esto" lockea la/s página/s en
donde se va a hacer una E/S. Una vez que termine esa E/S, cuando maneje la interrupción, va a
deslockearla y será nuevamente una página que pueda estar dentro del scope de víctimas.

PPT 12 FYLESYSTEM
¿QUÉ ES?
Es una parte del sistema operativo que podía ser que esté dentro del kernel o no
(dependiendo el tipo de kernel) y está relacionado a dar servicio del uso de archivos. La utiliza
tanto el usuario final como también las aplicaciones utilitarias como el mismo SO para guardar
información.

OBJETIVOS
- Almacenar datos y poder operar con ellos.

El filesystem soporta ciertos tipos de archivos en forma nativa y existen un monton de


tipos de archivos que el filesystem no sabe cómo abrirlos (lo delega en alguna app).

Este también es quien decide el formato de los archivos, no al reves. Pero si uno
formatea dicho medio de almacenamiento (una memoria flash o un disco rigido por
ejemplo) con un formato en particular obviamente no lo va a poder interpretar.
Dependiendo del criterio del filesystem, el espacio de almacenamiento se divide
logicamente y lo administra de cierta forma.

- Garantizar (en lo posible) la integridad de los datos: para poder administrar el archivo
habrá muchas estructuras administrativas, entonces... ¿En qué estado quedan dichas
estructuras si hay alguna falla de algún dispositivo por ejemplo?
Apuntado a la consistencia, si están accediendo varios al mismo archivo.

- Optimizar desempeño
o Usuarios -> tiempo de respuesta
o Sistema -> aprovechamiento de los recursos

- Proveer soporte para distintos tipos de almacenamiento

La idea es que se pueda dar la interfaz de que se desea hacer sobre un archivo (crearlo,
escribir, leer, eliminarlo) sin importar el medio de almacenamiento (si es una memoria
flash, un disco rígido o en estado sólido) el filesystem debería funcionar en cualquiera.

Lo que si se verá es que quizás el filesystem realiza una optimización pensada para un
determinado almacenamiento pero esto no quiere decir que no se pueda utilizar en
otro tipo de almacenamiento.

Justamente el filesystem nos da esa fracción de lo que está guardado en x medio de


almacenamiento son archivos y con eso es suficiente.

- Minimizar o eliminar la pérdida o destrucción potencial de datos (relacionado con


garantizar en lo posible la integridad)

- Proveer una interfaz estandarizada para procesos de usuario

¿Qué API/syscalls se van a poder hacer para operar sobre los archivos?

- Soporte para múltiples usuarios -> ¿qué puede hacer un usuario con los archivos de
otro?

ARCHIVO
¿QUÉ ES?
Conjunto de datos /registros relacionados etiquetados con un nombre y almacenados en un
medio secundario. Es decir, datos que pueden estar almacenados en forma dispersa en disco
pero están relacionados. En si el nombre del archivo no es un atributo de él pero si tendrá un
identificador para el SO (filesystem).

- Existencia de larga duración (tiene durabilidad): uno podría crear un archivo temporal
en memoria pero por lo general cuando se crean se desea que se almacene de forma
durable.
- Compartible entre procesos -> archivo = nombre + permisos asociados: al querer
compartir archivos (para acceder a ellos) se debe conocer su nombre (el path, es decir,
la ubicación en toda la estructura del directorio) y tener un permiso para poder
acceder.
- Estructura -> FCB

¿CÓMO SE ADMINISTRA?
FCB (File Control Block): estructura que utiliza el SO para administrar el archivo (parecido al
PCB en procesos). Cada archivo tendrá un FCB.

Es una estructura que se desea tener a mano (en memoria) que cambia respecto al PCB debido
a que...

… el PCB (que siempre está en RAM) dura hasta que el proceso finalice (dicha
estructura no tiene más utilidad por lo que se libera y en todo caso se utilizará dicho
espacio para otro proceso). Por otro lado, en el caso del filesystem estos archivos
tienen existencia durable (por más que se apague la compu por ejemplo, seguirán
existiendo) lo que nos da una pauta de que el FCB tiene que existir en disco.

Es decir, el FCB estará en alguna parte de la partición dentro del filesystem y


obviamente en el momento en el que se esté accediendo a dicho archivo se necesitará
que esté en memoria. Y por lo tanto, todas las modificaciones que se hagan en el FCB
(porque se escribió en el archivo por ejemplo) se tendrán que bajar a disco.

Contiene:

- File permissions

¿Quién puede acceder? ¿Cómo?

- File dates (créate, Access, write)

También se podría encontrar como time stamps. Está relacionado a cuándo fue la última
vez que se hizo un acceso en particular (Se escribió, se leyó, etc.)

- File owner, group, ACL

Relacionado con los permisos

- File size

Información sobre el contenido: el tamaño

- File data blocks or pointer to file data blocks

Se necesitarán punteros que direccionen la ubicación en disco. Dependerá mucho de cómo


es la estrategia para administrar el espacio: dependiendo de eso se sabrá qué información
se tendrá que guardar en el FCB.

DIRECTORIO
Es un archivo que contiene un listado de nombres de otros archivos (que también podrían ser
directorios) y sus atributos asociados.

Uno por lo general identifica a un archivo por su nombre pero en realidad no es parte del
contenido ni identificación de ese archivo en sí. ¿Por qué? Porque hay otros tipos de archivos
(los directorios) cuyo objetivo es almacenar las referencias a otros archivos. El directorio no
posee el contenido de aquellos archivos a los que referencia.
Cuando uno crea un archivo, lo crean en algún lugar del filesystem (posicionados en algún
directorio). Siempre hay una estructura de directorio que puede tener diferentes formatos. En
el directorio donde lo creo, agrego como contenido de ese archivo directorio una entrada más.
Uno podría acceder al mismo archivo desde diferentes lugares y el nombre en sí, que uno le
da, en realidad no es parte del archivo. Es por eso que no es parte del FCB sino que dicho
nombre está almacenado en el directorio en el que se creó.

Permite realizar el mapeo entre nombres de archivos (conocidos por usuarios y aplicaciones) y
los archivos en sí. Nosotros como usuarios finales usamos dicho nombre para poder mapear lo
que conocemos de dicho archivo a algún contenido que está en el disco. Entonces el filesystem
hace ese mapeo para poder decir en definitiva en donde está.

Se puede implementar como (Distintas estructuras de cómo se puede generar un directorio


desde la más simple a la más compleja ya que cada vez su administración es más compleja y
poder recorrer en el directorio suma complejidad a la estructura utilizada.):

- Un nivel (todos los archivos juntos, no se pueden repetir nombres). Aun así hoy en día
hay algunas estructuras que no tendrían sentido como que para todo el filesystem se
tenga un único nivel.
- Dos niveles (un directorio por usuario). Tampoco es real hoy en día poner todos los
archivos de un usuario en un mismo directorio.
- Árbol: al tener mayor profundidad significa que podría tardar más en encontrar un
nodo (a más niveles uno tarda más). Para optimizar se busca una estructura que
permite minimizar esa cantidad de niveles y la búsqueda sea más rápida.
- Grafo acícilo
- Grafo general: uno puede volver y generar un ciclo, además de poder llegar a un
mismo archivo a partir de más de uno.

IMPLEMENTACIÓN DE DIRECTORIOS
Del más simple al más complejo: se tiene en cuenta que operaciones se desearán hacer en
dicho directorio: si quiere poder buscar ordenado, si quiere ordenar por diferentes criterios,
etc. Por lo general, para levantar el directorio también se debe tener información de los FCB

- Lista lineal
o Más fácil de programar
o Manipulación más compleja (buscar -agregar-eliminar)
o Requiere búsqueda lineal
- Lista enlazada ordenada
o Más complejo agregar/eliminar entradas
- Árbol-B
o Minimiza el tiempo de búsqueda
- Tabla de hash
o Lista lineal + estructura de hash
OPERACIONES SOBRE ARCHIVOS
- CREAR: consiste en definir un nuevo archivo, por lo que hay una abstracción de él,
asignándole un FCB y un espacio de almacenamiento, además de agregar una entrada
al directorio.
- ELIMINAR: consiste en liberar al FCB, además del espacio en almacenamiento, además
de eliminar la entrada del archivo del directorio donde se encontraba.
- OPEN: consiste en que un proceso abre un archivo existente obteniendo así su
identificador para realizar en él futuras operaciones (y poniendo su FCB en memoria
también). Para obtener el identificador del archivo se debe de recorrer todo el path del
mismo por lo que sería bastante ineficaz si lo hiciese cada vez que se pretende hacer
una operación en él.
- CLOSE: una vez que el proceso no pretende realizar ninguna operación más a futuro se
cierra el archivo abierto (se puede volver a abrir pero conlleva un costo: volver a
buscar su identificador). Si no se cerrase el archivo y se termina de ejecutar, se
liberaría junto con todos los recursos que el proceso debe liberar.
- LEER/ESCRIBIR: para leer o escribir sobre un archivo se utiliza el identificador del
mismo obtenido cuando se abrió previamente.
- TRUNCAR
- POSICIONAR PUNTERO FSEEK
- OPERACIONES COMPUESTAS:
o COPIAR: para copiar un archivo se requiere abrir y leer el archivo en cuestión,
y, en el lugar de destino donde se pretende copiar, crear un nuevo archivo y
escribir en él (lo que se leyó previamente).
o MOVER – CORTAR: tanto mover como cortar un archivo son operaciones de las
cuales depende dónde se haga el tiempo que tardara:
 Si se hace dentro del mismo file system donde se encuentra el archivo
en cuestión, lo único que se requiere es cambiar la entrada del archivo
en el directorio al lugar de destino donde se pretende mover o cortar.
 Si se hace de un file system a otro diferente es una operación más
compleja ya que consiste en copiar el archivo y eliminarlo del lugar de
origen.
o RENOMBRAR

LOCKS
Se utilizan:

- Principalmente para garantizar la integridad de los archivos.


- Para asegurar que dos procesos no escriban un archivo simultáneamente.
- Para asegurar que un proceso no lea un archivo desactualizado.

Puede ser:

- Exclusivo (lock de escritura): un proceso puede adquirirlo por vez, los demás se
bloquearan al intentar acceder al archivo.
- Compartido (lock de lectura): si el archivo no está siendo modificado, todo proceso
que desee acceder al archivo en modo lectura podrá. Si hay procesos que se
encuentran leyendo el archivo y un proceso pretende modificarlo, este debe de
esperar a que los procesos liberen el archivo (se bloquea). Es decir, muchos procesos
pueden adquirirlo concurrentemente. Un proceso no puede adquirir un lock exclusivo
mientras haya uno compartido.

¿Por qué se utilizan locks en vez de mutex?

1. Cuando se tienen casos que procesos van a acceder en modo lectura y otros en modo
escritura. Con mutex si uno quiere acceder al recurso compartido (en modo escritura o
lectura, es indiferente para el mutex) el resto se bloquea (sea que quiere hacer una
modificación o leerlo), pero los locks permiten que varios procesos puedan acceder en
modo lectura a la vez, y si uno pretende escribir se bloquea esperando que el archivo
sea liberado por los demás liberen al archivo. Cuando un proceso está en modo
escritura, aquellos que pretendan tanto leer o escribir no podrán y se bloquearán
hasta que el proceso termine de modificar al archivo.
Es por esta razón que se puede decir que los mutex hacen esperar más a los procesos.
2. Además otra característica que tienen los locks y que los mutex no es que uno puede
lockear una parte del archivo, es decir, no necesita lockear todo el archivo entero lo
cual es aún más óptimo.

En cuanto a la implementación esta puede ser:

- Obligatoria (mandatory): el SO operativo se encarga que ningún proceso pueda utilizar


los archivos a menos que cumpla con el lock. Si bien hace que el sistema se encuentre
siempre en un estado seguro, esto conlleva un alto costo.
- Sugerido (advisory): el SO brinda herramientas para poder hacer cumplir los locks pero
la responsabilidad de garantizar su integridad queda del lado del programador. Los
locks se deberán adquirir y liberar correctamente, sin generar deadlock (el SO no
valida).

MANIPULACIÓN DE ARCHIVOS
El FCB es la estructura por la cual el SO administra un archivo. Esta estará en un principio en
disco pero cuando se está accediendo a un archivo uno va a querer traerlo a memoria,
administrarlo y tener en cuenta que procesos van a querer acceder a él.

Cuando un proceso pretende abrir un archivo, lo que se quiere recuperar es su id y con él traer
a memoria el FCB (entonces todas las operaciones que se quieran hacer se realizaran a partir
de la información obtenida de ese FCB que ya se encuentra en RAM). Sin embargo, como
varios procesos pueden acceder a él (por el lock de lectura) puede que el FCB ya esté en RAM y
otro archivo haya accedido a él. Es por esto que cuando un proceso pretende abrir un archivo,
la apertura puede ser rápida (si el FCB ya está en RAM y otro archivo accedió a él primero
recuperando el id) o más lenta (si debe de recurperar el id recorriendo todo el path del archivo
en cuestión).

Para una mejor manipulación se necesita tener una tabla de archivos abiertos global y una
particular para cada proceso.

TABLA DE ARCHIVOS ABIERTOS


¿Por qué cada proceso debe tener una tabla de archivos abiertos y luego debe haber una tabla
de archivos abiertos global?
Por un lado porque a nivel global serian cuales son todos los archivos abiertos en el sistema
(teniendo id y el puntero a donde este cargado en memoria el FCB). Es la información válida
para todos los procesos.

Por otro lado, cada proceso podría estar accediendo a diferentes archivos y podría tener cosas
particulares (como el modo de apertura, por donde está leyendo, información de locks, etc.).
Aun así no sería necesario tener toda la información del FCB copiada debido a que sería
redundante, por lo que probablemente podría estar apuntando a la entrada de la tabla global
del/de los archivo/s a los que accede.

Entonces cuando se abre un archivo, primeramente se tiene que mirar si está en la tabla global
de archivos abiertos para ver si nos podemos ahorrar ir a buscarlo a la estructura directorio (y
traerlo a RAM). Es por esto que a veces abrir un archivo se hace más rápido y otras veces más
lento. Obviamente si un proceso abre un archivo, se agregará una entrada en su tabla de
archivos abiertos (la del proceso). Si el archivo ya está en la tabla global, desde la entrada del
proceso se podrá apuntar a esa global.

Al tener estas estructuras... ¿En qué momento se borrará una entrada en la tabla global y en
qué momento en la del proceso?

Cada vez que un proceso hace close de un archivo la entrada en su tabla de archivos abiertos
se borrará. En cuanto a la tabla global, para borrar la entrada de un archivo determinado habrá
que esperar a que ningún proceso tenga abierto el archivo en cuestión. Para eso se tendrá un
contador de aperturas por entrada (aumenta si un proceso abre un archivo y disminuye si lo
cierra). Cuando llegue a 0 significa que ningún proceso está accediendo a él y se podrá borrar
de la tabla global.

PROTECCIÓN
Puede ser:

- Acceso total: no se aplica ninguna estrategia de protección (todos los procesos pueden
acceder a cualquier archivo si tienen el path)

- Acceso prohibido: no se aplica ninguna estrategia de protección (todos los procesos


pueden acceder a cualquier archivo si tienen el path)

- Acceso controlado: indica quien puede operar y cómo (qué permisos tiene). Puede ser
con:
o Una matriz de acceso
o Propietario | grupo | universo (resto)
o ACL

PROPIETARIO | GRUPO | UNIVERSO (RESTO)


Consiste en una estructura que ocupa muy poco espacio (9 bits) y por lo tanto es fácil de
administrar. Consiste en que cuando se crea un archivo se definirá por un lado que permisos
tiene el propietario, después que permisos tiene el grupo al que pertenezco como propietario
y por último que permisos tiene el resto (no hay que especificar usuario por usuario). Tiene
como desventaja el hecho de que no se puede ser muy específico: por ejemplo no puede
asignarse permisos a un usuario particular o más de un grupo.
MATRIZ DE ACCESO
Es una estructura que ocupa mucho espacio pero es muy específico, con mucha granularidad.
Consiste que por cada usuario se le indica que tipos de accesos tiene por cada archivo. Esto
hace también que sea muy costoso: por cada usuario creado se le debe de especificar que
permisos tiene por cada archivo y lo mismo para los archivos (se le debe de especificar para
todos los usuarios que permisos tienen sobre él).

ACL (ACCESS CONTROL LIST)


Consiste en una lista en la que se pueden especificar permisos particulares tanto para el
dueño, para distintos grupos, usuarios y luego para los demás que no pertenezcan a ninguna
de esas categorías (others). Aun así es más complejo para administrar que OWNER | GROUP |
UNIVERSE (al ocupar más de 9 bits).

PROTECCIÓN EN LINUX
Consiste en usar como protección OWNER | GROUP | UNIVERSE pero con un bit más para
identificar el tipo de archivo (si es un directorio o no). Esto es así debido a que los accesos son
distitos:

- La lectura consiste en poder ver el contenido de un directorio (ls)


- La escritura consiste en modificar el contenido del directorio, es decir, poder crear o
eliminar entradas del mismo.
- La ejecución consiste poder posicionarse dentro del directorio (cd). Por más que se
tenga permiso de lectura, si no se tiene permiso de ejecución no nos podremos
posicionarlos en el directorio que se pretende leer.

Podría pasar que con el esquema de Propietario | Grupo | Resto no alcance para dar permisos
en forma adecuada para nuestra situación. Es por esto que se puede combinar dicha estrategia
con ACL en caso de ser necesario (lo cual agrega granularidad y con ello ocupa más espacio y
genera más complejidad). Cuando uno accede se le dará el permiso más específico.

ARCHIVOS MAPEADOS A MEMORIA


Objetivo: Tratar la E/S de archivo como si fueran accesos a memoria.

¿Por qué?

Uno al usar file system, cada vez que tiene que hacer una operación sobre un archivo (open,
un close, write, read, etc.) tiene que hacer una llamada al sistema, es decir, una syscall (que
conlleva un cambio de modo, el cambio de contexto). Entonces, uno puede mapear al archivo
(puede ser una parte, no hace falta que sea todo el archivo) al espacio de direcciones del
proceso que accedió a él (como si fuese una parte de la imagen del mismo) a través de una
syscall y acceder a él como si fuese cualquier parte de la memoria.

Obviamente se necesita esa syscall inicial para que el SO lo mapee, pero después todas las
operaciones se hará sin realizar syscalls. Simplemente se accederá a memoria cuando esté
cargado y, cuando no, realizará el PF y lo irá a buscar.

- Disminuye el overhead requerido.


- Favorece el share de archivos entre procesos -> comparten páginas (porq es facil
compartir memoria en paginación)
- Si bien el SO podría ir bajando esos cambios a disco de vez en cuando, recién en el
momento en que tenga que reemplazar la página realizará esos cambios en disco. Es
por eso que las escrituras hechas en el archivo (que generan cambios en la página en la
que está mapeado) serán más eficientes porque no van a tener que hacer la
modificación sincrónica en ese momento.

MÉTODOS DE ACCESO
- Secuencial: Un registro después del otro
- Directo: Se puede acceder a cualquier registro sin recorrer los anteriores
- Indexado: Se coloca un índice para acelerar búsquedas sobre archivos grandes
- Hashed: Para agilizar accesos directos. Se utiliza la función de hash para acceder
directamente al bloque deseado

ORGANIZACIÓN DE DATOS EN DISCO


Un disco puede tener varias particiones (dividirlo lógicamente) y a cada una aplicarle un
formato en particular (un file system).

Para esto, el disco posee un espacio pequeño para el MBR (master boot record) que nos dice la
mínima información del disco (que particiones hay, si poseen formato o no).

Cada partición posee un formato llamado volumen que tiene (según el file system será
diferente pero hay algo que si suelen mantener):

- Una parte adminsitrativa: información general del volumen a nimel configuración.


o Bloque de control de arranque de volumen
o Control de volumen (información gral del FS para que el SO lo pueda
administrar (siempre en memoria)
o META-DATA (por lo general está en memoria, pueden estarlo siempre o
parcialmente)
- Los archivos: espacio para almacenar todos los datos de los archivos.

ASIGNACIÓN DE ESPACIO EN DISCO A ARCHIVOS


¿Cómo se va a asignar la información del dispositivo al archivo?

En este caso el almacenamiento en disco va a ser por sectores. Sin importar el medio de
almacenamiento el file system administrará igual, porque siempre va interpretar que va a
tener un disco virtual con bloques lógicos (que van de 0 a n dependiendo del tamaño del
bloque lógico y de la capacidad de la partición en la cual estemos trabajando, en este caso el
disco físico).

Es decir, La unidad de asignación del FS será Bloque Lógico. Para ello se debe de tener una
estrategia para la asignación de bloques y la administración de los que se encuentren libres.

ASIGNACIÓN DE BLOQUES – ESTRATEGÍA: CONTIGUA


Se le asigna cierta cantidad de bloques contiguos del disco virtual a un archivo.

Lo que uno necesita para administrar un esquema así es poder decir: en donde empieza el
archivo (para saber desde donde acceder) y donde termina (además de no pasarse, si uno
quiere extender el archivo poder cambiarlo fácilmente). La otra opción es en vez de saber
dónde termina, saber la cantidad de bloques que ocupa (el tamaño) y de esa forma calcular
cual es el último.

VENTAJAS
- Sencillo de administrar.
- Si uno quiere acceder de forma secuencial puede, de forma directa también.
- Los reposicionamientos se encuentran relacionados a cómo es que se almacena la
información en los discos rígidos. Teniendo en cuenta de que si están cerca
probablemente estén en el mismo cilindro (moverse de un cilindro a otro es lo que
genera el movimiento mecánico del brazo del disco y es lo que toma más tiempo). Por
lo tanto los reposicionamientos en esta estrategia de asignación de bloques serán
mínimos ya que al tener los datos del archivo juntos en el disco lógico hace que sea
más probable que estén juntos en el disco rígido y por ende el brazo del disco rígido se
tendrá que mover menos.

DESVENTAJAS
- A priori cuando uno crear un archivo tendrá que saber cuántos bloques necesitará
(pre-alocacion), es decir, el tamaño del mismo.
- Si bien todos los datos del archivo están contiguos, entre bloques no. Estos se asignan
de forma dinámica lo cual genera que la administración entre bloques sea compleja y
además provoca fragmentación externa (que se puede solucionar con compactación
pero al ser movimientos en disco y no en memoria será mucho más lento).

ASIGNACIÓN DE BLOQUES - ESTRATEGÍA ENLAZADA/ENCADENADA


Romper con el esquema de los bloques lógicos contiguos conlleva a que no se deba pre-alocar
(se asignarán los bloques recién cuando se los necesite). Si ya no se tiene más espacio en cierto
lugar, comenzar por otro (definir una extensión).

Uno podría llevarlo al extremo e ir linkeandolos de a uno: estrategia enlazada.

La forma de entender cuál es el bloque que le sigue al actual es a traves de un puntero. Dicho
puntero estará almacenado dentro del bloque de datos.

Se necesita el bloque inicial y el final ya que si uno en vez de guardar el bloque final guarda el
largo, sería muy molesto para agregar nuevos bloques. Esto es así debido a que para agregar
un nuevo bloque uno debería modificar el puntero del último bloque enlazado y sabiendo
únicamente el largo se tendría que leer todos los bloques previos para ello.

VENTAJAS
- No hay problemas para aumentar el tamaño del archivo (no hay prealocación)
- No presenta fragmentación externa (importante para almacenamiento secundario)
- Es bueno para acceso secuencial

DESVENTAJAS
- Espacio ocupado por punteros: se está usando una parte del bloque (aunque pequeña)
para almacenar algo que no es datos (un puntero al siguiente bloque).
- Si hay un fallo en el disco y una de las partes intermedias se rompe se pierde la
trazabilidad del archivo.
- Los reposicionamientos del cabezal del disco pueden ser mayores (bloques dispersos).
Es preferible esto a tener fragmentación externa.
- Si se quiere leer directamente un bloque se tendrá que acceder a todos los anteriores
a él (que realmente no se querian) para obtener la dirección.

ASIGNACIÓN DE BLOQUES – ESTRATEGIA INDEXADA


Igual que la estrategia enlazada pero que permite hacer el acceso directo al tener todos los
punteros en un bloque lógico llamado índice (1 por archivo).

¿Qué tan grande o que tan chico va a ser este bloque de punteros?
- Si es muy chico desperdicio menos espacio pero estoy limitando el tamaño de mi
archivo.
- Pero si es muy grande seguramente tengamos para algunos bloques bastante
fragmentación interna.

¿Cómo se soluciona?

- Esquema enlazado. Cada bloque de índice ocupa normalmente un bloque de disco ->
puede leerse y escribirse directamente. Para que puedan existir archivos de gran
tamaño, enlazamos varios bloques de índice.
- Índice multinivel. utilizar un bloque de índice de primer nivel para apuntar a un
conjunto de bloques- de índice de segundo nivel, que a su vez apuntarán a los bloques
del archivo.
- Esquema combinado. mantener los primeros N punteros del bloque de índice en el
nodo del archivo siendo algunos ptrs a bloques de datos(BD) y otros a bloques de ptrs
(BP)
o Los archivos pequeños no necesitan un índice separado
o Se pueden aun así referenciar a muchos bloques de datos, por lo que no se
limita el tamaño del archivo.

VENTAJAS
- No hay problemas para aumentar el tamaño del archivo (no hay prealocación)
- No presenta fragmentación externa
- Es bueno para acceso secuencial y directo

DESVENTAJAS
- Los reposicionamientos del cabezal del disco pueden ser mayores ( bloques dispersos )
- Espacio ocupado por punteros es aún mayor (quizás haya entradas que no se utilicen)
- Corrupción de punteros es peor porque si se rompe el bloque de índices no se sabrá
dónde están los bloques del archivo en cuestión -> problema fiabilidad

ASIGNACIÓN DE BLOQUES – ESQUEMA ENLAZADO


Se usa el último puntero de los índices para extender la capacidad de direccionamiento de
archivo.

El acceso no será tan directo como en un principio que se tenía un índice y ay se tienen todos
los punteros a los bloques de datos. Se encadenan accesos (que aplicaba para bloques de
datos y ahora también para bloques de índices). Dependiendo que bloque de datos tenga que
acceder, serán menos o más accesos a bloques de punteros.

Si por ejemplo se quiere acceder al bloque 25 y la N=10, se sabe que la referencia al bloque se
encuentra en el índice 3. Es por esto que se tendrá que traer el bloque 1 (+1) para recuperar el
puntero al dos (+1), el bloque dos para recuperar el puntero al bloque 3 (+1) y recién ahí, ya en
el bloque 3 acceder a la 5ta posición (+1). (4 accesos).

Pero esto no significa que si quiere acceder al bloque de datos n°25 tengo que acceder a los 24
anteriores.

ASIGNACIÓN DE BLOQUES – ÍNDICE MULTINIVEL


Índice inicial cuyos punteros no referenciarán bloques de datos sino que apuntarán a otros
bloques de punteros.
Todos los bloques tienen el mismo tamaño (N).

A medida que la cantidad de niveles aumente, el nivel de direccionamiento aumentará


exponencialmente por lo que escala mucho más rápido que el enlazado.

A priori se debe determinar qué nivel de dirección se quiere, lo cual definirá cuanto se puede
direccionar (no será infinito).

Siempre el número de accesos será NIVEL + 1. Cuanto mayor sea el nivel, más serán los accesos
que se deberán hacer para acceder a un bloque de datos. + COSTOSO

ASIGNACIÓN DE BLOQUES – ESQUEMA COMBINADO


Si se tiene un archivo con un solo bloque, se podrá acceder a él directamente del FCB (sin
ningún acceso extra a disco). A medida que el archivo sea más grande se tendrán que hacer
más accesos (dependiendo a que bloque se quiera acceder).

GESTIÓN DE ESPACIO LIBRE


Bit vector: uno puede llegar a tener un detector de bits (bit map) para gestionar que bloques
están libres y cuáles no.

Bloques libres enlazados (lista)

Bloques indexados: espacio libre tratado como un archivo, todos los bloques libres
administrarlos con un índice

Lista de bloques: se almacena en los bloques libres las direcciones de los siguientes N-1
bloques libres

Lista de bloques contiguos: se almacena el # bloque inicial y el número de bloques contiguos


libres a partir del mismo. Es más costoso que un vector de bits pero si se tiene bloques
asignados de manera contigua podría servir (nos permite encontrarlos mucho más fácil).

JOURNALING
La información de las estructuras del FS por lo gral están más actualizadas en memoria que en
disco

Un fallo en el sistema (apagones repentinos por ejemplo, sino terminará lo que deba hacer) /
en el HW puede generar inconsistencias.

Para que esto no ocurra se usará un journal (un log en el cual uno va a ir escribiendo cuales son
las operaciones que se realizaron sobre las estructuras administrativas). Se va a guardar y se
usará en forma circular (no crecerá infinitamente sino que en algún momento los cambios se
bajarán a disco por lo que se va pisando en forma circular).

Se marcará con un flag/commit cuáles son las operaciones necesarias para que un cambio
quede consistente. Se aplican las transacciones que se encuentran completas (que hay un
commit debajo de todas sus microperaciones), y las que no se borran y no se aplican (no
quedan persistidas en disco). Si se llegó a escribir una transacción pero quedo incompleta se
tendrá que volver para atrás.

Cuando se deba modificar en disco, se tendrá un puntero que indicará cual es la última
operación actualizada.
PPT 13 IMPLEMENTACIONES EXT2 Y FAT
EXT
INODOS
Estructura muy importante que posee todas las propiedades del archivo en cuestión (como el
FCB).

Tiene una asignación indexada combinada (hay bloques directos, de un nivel, de dos niveles,
etc.), es decir, guardan punteros directos e indirectos (usa esquema mixto con punteros
directos a bloques y con esquema indexado)

ESTRUCTURA EXT2
¿Cómo organiza su volumen?

Se divide en bloques donde cada uno tendrá:

- Con un súper bloque con información general del file system: tanto para saber su
configuración como también para saber su estado (que bloques y que INODOS están
libres).
- Descriptores de grupo
- Bitmap bloques datos (para administrar los bloques de datos)
- Bitmap de nodos
- Tabla de inodos (Tipo, Dueño, Tamaño, TIMESTAMPS, NRo bloques, PTRs a BD y PTRS a
BP).
- BLOQUES DE DATOS

¿Por qué se divide el FS en grupos si vamos a generar información repetida?

Porque si bien los bloques de un archivo no estarán contiguos (al ser indexado), logrará que no
estén tan dispersos dentro del disco lo cual generará menos movimientos del cabezal del disco
y por ende va a ser más rápido leer el disco. Es decir, se realiza para optimizar el acceso en este
tipo de dispositivos.

DIRECTORIOS
La entrada de directorio posee el nombre (no es parte del archivo pero está) y el identificador
del FCB (en este caso el número de inodo para recuperarlo y operar en memoria).

TIPOS DE ARCHIVOS
En general los fyle system no poseen la lógica para interpretar todos los tipos de archivos
existentes. A priori interpreta un par de tipos nativamente y el resto se delega en un par de
aplicaciones

- Regular (-)
- Directorio (d)
- Links
o Soft/Symbolic Links (l)
o HardLinks (-) no lo distingue de un archivo regular.

SOFTLINK
- Análogo a “acceso directo” en Windows
- Es un archivo independiente al archivo original (al cual se está linkeando)-> posee su
propio inodo
- Su contenido posee la ruta a otro archivo al que apunta
- Puede realizarse entre distintos FSs (da cierta flexibilidad debido a que se puede hacer
un softlink de cualquier cosa debido a que es solo un path)

El acceso es más lento y costoso debido a que tiene un nivel de mayor indirecciones:

1. Se accede a través del SL

2. Se tiene que recuperar el INODO del SL

3. Con el INODO se debe recuperar el contenido: el path del archivo en cuestión

4. Recorrer el path hasta llegar al archivo

Y de acá mismos accesos que si accedieramos directamente al archivo:

5. Obtener el INODO y acceder al contenido.

Si uno cierra el archivo en cuestión se generará una inconsistencia (el SL seguirá estándo al ser
un archivo independiente y en su contenido habra un path no existente).

HARDLINK
- Es una nueva referencia (entrada de directorio) a un archivo que a punta al mismo
inodo
- Existe un único archivo con uno o más hardlinks (counter)
- No puede realizarse entre distintos FSs, solo tiene sentido dentro del mismo scope.
Tampoco se podrá hacer sobre directorios
Se necesitará administrar cuántas referencias tendrá ese archivo para saber cuándo se podrá
borrar. Si hay otro que está referenciando un archivo, al hacer un rm no debería borrarlo sino
que se debería borrar solo esa entrada a directorio.

¿Qué operación se tuvo que hacer a nivel file system?

- En el caso anterior, en SL, el archivo original no fue modificado de ninguna manera.


- En este caso, lo único que se hace es crear la entrada de directorio e incrementar en el
INODO el contador de links por lo que si genera una modificación en el original.

FAT
FAT (dile allocation table) se llama al file system y también a la tabla que utiliza.

Posee asignación enlazada.

➔ Variación de asignación encadenada: los punteros se guardan en la tabla FAT ( una


para todo el FS, no por archivo -- aunque puede haber copias)

➔ Permite acceso directo

➔ Hay una entrada por bloque (cluster = bloque lógico) de disco. Es decir, tiene tantas
entradas como bloques tiene el disco virtual (y el bloque coincide con el bloque
lógico).

➔ La entrada indica el bloque que le sigue (al bloque de dicho índice)

Las relaciones entre bloques no se encuentran en los bloques de datos sino en esta tabla que
probablemente siempre estará cargada en memoria. Es por esto que:

- Si bien hay que hacer todos los recorridos (al ser enlazados) se hará en la tabla (por lo
que no se tiene que hacer todos los accesos y traer los bloques de disco). por lo que
todos los accesos serán en memoria (menos costoso y lento)
- Si se pierde, se pierde el sentido entre los bloques de datos de esa partición. Entonces
lo más probable es que se tenga una copia o dos de esta estructura dentro del
volumen. Obviamente cuando se esté cargando en memoria se utilice solo una de
estas FAT's y se tendrá que linkear a disco (para actualizarse)

VOLUMEN
Está dividido en:

- Sector de arranque: dentro del sector de arranque se tiene la configuración (qué


tamaño tiene la entrada del directorio raíz, es decir, que tamaño de dirección puede
direccionar el file system). Lo cual termina limitando el tamaño del archivo por
ejemplo.
- FAT + copia/s
- Directorio raíz (un root): cantidad de entradas fijas de tamaño fijo
- Datos (Archivos + subdirectorios)

TAMAÑO ENTRADA
¿A qué hace referencia el número? Al tamaño de direccionamiento.

Cada entrada hace alusión a un bloque lógico de disco, por lo que se puede tener hasta 2^12
bloques.

➔ FAT 12

◆ Entradas de 12 bits

◆ Puede direccionar hasta 2^12 entradas

◆ Tam máx archivo = 32MiB

➔ FAT 16

◆ Entradas de 16 bits

◆ Puede direccionar hasta 2^16 entradas

◆ Tam máx archivo = 2GiB

➔ FAT 32

◆ Entradas de 32 bits

◆ Puede direccionar hasta 2^28 entradas (Cuando se diseñó dejaron un par de


bits para hacer otras cosas.)

◆ Tam máx archivo = 4GiB

¿Qué creen que limita el tamaño del archivo? ¿Qué tan grande puede ser un archivo en FAT?

En EXT nos limitaban los punteros que poseíamos en el INODO

La tabla tendrá tantas entradas como bloques pueda referenciar, entonces uno podría
direccionar más del espacio que se posee en la partición o al revés (que tenga una partición
más grande de lo que me permite direccionar el filesystem). La tabla va a tener las entradas
justas (lo que necesita).
Lo que limitará el tamaño del archivo es lo mismo que limita el tamaño del filesystem porque
se puede direccionar la cantidad de bloques que tenga ese file system.

Para saber el tamaño del archivo se le deberían restar el tamaño de las estructuras
administrativas pero se minimiza ese espacio que se descarta (se lo toma como 0 y se cuenta
únicamente los datos).

Pero no es como el EXT que hay otra configuración (como el INODO) que nos termina
limitando el tamaño del archivo. Lo mismo que permite direccionar (el tamaño de FAT) es lo
que limita.

También podría gustarte