# SOA: LAB P2
## Ejemplo de ejecución de gen_traza
### 5 elementos, burbuja, estado inicial ascendente
```
SOA@LE05U00:~/SOA/p02$ ./gen_traza BUB ASC 5
T5
L0 L1 C L2 C L3 C L4
C Ordenado ;-)
```
### 5 elementos, burbuja, estado inicial descendente
```
SOA@LE05U00:~/SOA/p02$ ./gen_traza BUB DES 5
T5
L0 L1 C E0 E1 L2 C E1
E2 L3 C E2 E3 L4 C E3
E4 L0 L1 C E0 E1 L2 C
E1 E2 L3 C E2 E3 L0 L1
C E0 E1 L2 C E1 E2 L0
L1 C E0 E1 Ordenado ;-)
SOA@LE05U00:~/SOA/p02$
```
---
## Figuras conjunto de trabajo (Working Set)









## Práctica 2: sim_pag_aleatorio.c
```C=
/*
sim_pag_aleatorio.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sim_paginacion.h"
// Función que inicia las tablas
void iniciar_tablas (ssistema * S)
{
int i;
// Páginas a cero
memset (S->tdp, 0, sizeof(spagina)*S->numpags);
// Pila LRU vacía
S->lru = -1;
// Tiempo LRU(t) a cero
S->reloj = 0;
// Lista circular de marcos libres
for (i=0; i<S->nummarcos-1; i++)
{
S->tdm[i].pagina = -1;
S->tdm[i].sig = i+1;
}
S->tdm[i].pagina = -1; // Ahora i == nummarcos-1
S->tdm[i].sig = 0; // Cerrar lista circular
S->listalibres = i; // Apuntar al último
// Lista circular de marcos ocupados vacía
S->listaocupados = -1;
}
// Funciones que simulan el hardware de la MMU
unsigned sim_mmu (ssistema * S, unsigned dir_virtual, char op)
{
unsigned dir_fisica;
int pagina, marco, desplazamiento;
//TODO:
//Calculamos el numero de pagina que sera el cociente
pagina = dir_virtual / S->tampag;
//Calculamos el desplazamiento que sera el resto
desplazamiento = dir_virtual % S->tampag;
//comprobar que el acceso al numero de pagina especificado es legal
if (pagina < 0 || pagina >= S-> numpags){
S->numrefsilegales++;
return ~0U; //Devolver dir . física FF ... F
}
if (!S->tdp[pagina].presente){ //Comprobamos si la pagina en cuestion esta cargada en memoria fisica
tratar_fallo_de_pagina (S, dir_virtual); //Si no esta cargada en memoria física, la funcion tratar_fallo_de_pagina se encargara de cargar la página en algun marco de memoria.
}
//Calculamos la dirección física traduciendo la direccin virtual
marco = S->tdp[pagina].marco;
dir_fisica = marco * S->tampag + desplazamiento;
referenciar_pagina (S , pagina , op ); //Marcamos como referenciada la página
//Imprimir la información del acceso a memoria en caso de que el usuario ordenara ejecutar el simulador en modo detallado.
if (S -> detallado ){
printf ("\t%c%u==P%d(M%d)+%d\n", op, dir_virtual, pagina, marco, desplazamiento);
}
return dir_fisica;
}
void referenciar_pagina (ssistema * S, int pagina, char op)
{
if (op=='L') // Si es una lectura,
S->numrefslectura ++; // contarla
else if (op=='E')
{ // Si es una escritura,
S->tdp[pagina].modificada = 1; // contarla y marcar la
S->numrefsescritura ++; // página como modificada
}
}
// Funciones que simulan el sistema operativo
void tratar_fallo_de_pagina (ssistema * S, unsigned dir_virtual)
{
int pagina, victima, marco, ult;
//TODO:
S->numfallospag ++;
pagina = dir_virtual / S->tampag;
if (S->detallado){
printf("@ FALLO DE PÁGINA EN P%d \n!", pagina);
}
if(S->listalibres!=-1)
{ //Si hay marcos libres
ult = S-> listalibres; //Ultimo de la lista
marco = S->tdm[ult].sig; //Tomal esl sig. (el primero)
if(marco == ult){ //Si son el mismo, es que
S->listalibres = -1; //solo quedaba uno libre
}else{
S->tdm[ult].sig = S->tdm[marco].sig; //Si no, puentear
}
ocupar_marco_libre (S, marco, pagina);
}
else
{ //Si todos los marcos estan ocupados
victima = elegir_pagina_para_reemplazo(S); //seleccionamos una página para el remplazo
reemplazar_pagina(S, victima, pagina); //es remplazada por la nueva página
}
}
static unsigned aleatorio (unsigned desde, unsigned tam) { // <<--- aleatorio
unsigned n;
n = desde + (unsigned)(rand()/(RAND_MAX+1.0)*tam);
if (n>desde+tam-1) // Estas comprobaciones no
n = desde+tam-1; // deberían ser necesarias,
else if (n<desde) // pero es mejor no fiarse
n = desde; // mucho de las operaciones
// en coma flotante
return n;
}
int elegir_pagina_para_reemplazo (ssistema * S)
{
int marco, victima;
marco = aleatorio (0, S->nummarcos); // <<--- aleatorio
victima = S->tdm[marco].pagina;
if (S->detallado)
printf ("@ Eligiendo (al azar) P%d de M%d para "
"reemplazarla\n", victima, marco);
return victima;
}
void reemplazar_pagina (ssistema * S, int victima, int nueva)
{
int marco;
marco = S->tdp[victima].marco;
if (S->tdp[victima].modificada)
{
if (S->detallado)
printf ("@ Volcando P%d modificada a disco para "
"reemplazarla\n", victima);
S->numescrpag ++;
}
if (S->detallado)
printf ("@ Reemplazando víctima P%d por P%d en M%d\n",
victima, nueva, marco);
S->tdp[victima].presente = 0;
S->tdp[nueva].presente = 1;
S->tdp[nueva].marco = marco;
S->tdp[nueva].modificada = 0;
S->tdm[marco].pagina = nueva;
}
void ocupar_marco_libre (ssistema * S, int marco, int pagina)
{
if (S->detallado)
printf ("@ Alojando P%d en M%d\n", pagina, marco);
//TODO:
S->tdm[marco].pagina = pagina;
S->tdp[pagina].marco = marco;
S->tdp[pagina].presente = 1;
}
// Funciones que muestran resultados
void mostrar_tabla_de_paginas (ssistema * S)
{
int p;
printf ("%10s %10s %10s %s\n",
"PÁGINA", "Presente", "Marco", "Modificada");
for (p=0; p<S->numpags; p++)
if (S->tdp[p].presente)
printf ("%8d %6d %8d %6d\n", p,
S->tdp[p].presente, S->tdp[p].marco,
S->tdp[p].modificada);
else
printf ("%8d %6d %8s %6s\n", p,
S->tdp[p].presente, "-", "-");
}
void mostrar_tabla_de_marcos (ssistema * S)
{
int p, m;
printf ("%10s %10s %10s %s\n",
"MARCO", "Página", "Presente", "Modificada");
for (m=0; m<S->nummarcos; m++)
{
p = S->tdm[m].pagina;
if (p==-1)
printf ("%8d %8s %6s %6s\n", m, "-", "-", "-");
else if (S->tdp[p].presente)
printf ("%8d %8d %6d %6d\n", m, p,
S->tdp[p].presente, S->tdp[p].modificada);
else
printf ("%8d %8d %6d %6s ¡ERROR!\n", m, p,
S->tdp[p].presente, "-");
}
}
void mostrar_informe_reemplazo (ssistema * S)
{
printf ("Reemplazo aleatorio " "(no hay info. específica)\n"); // <<--- aleatorio
}
```
## Práctica 2: sim_pag_lru.c
```C=
void referenciar_pagina (ssistema * S, int pagina, char op)
{
// ::::::
S->tdp[pagina].timestamp = S->reloj;
S->reloj++;
//::::::
/* Comprobar el desbordamiento */
}
int elegir_pagina_para_reemplazo (ssistema * S)
{
int marco, victima, i, tiempoMenor;
/* Selecionar marco que contiene la página con menor timestamp */
return victima;
}
```
## Práctica 2: sim_pag_fifo.c
```C=
int elegir_pagina_para_reemplazo (ssistema * S)
{
int marco, victima, ultimo;
/*
Elegir el siguiente al último de lista ocupados
Actualizar listaocupados
*/
return victima;
}
void ocupar_marco_libre (ssistema * S, int marco, int pagina)
{
int primero, ultimo;
if (S->detallado)
printf ("@ Alojando P%d en M%d\n", pagina, marco);
// TODO:
S->tdm[marco].pagina = pagina;
S->tdp[pagina].marco = marco;
S->tdp[pagina].presente = 1;
/* Actualizar listaocupados */
/* Esta función se ejecuta los N primeros */
/* fallos de página, hasta que se asignan */
/* todos los marcos. Luego ya no hay marcos */
/* libres. */
if(S->listaocupados == -1){ //Si listaocupados esta vacia
primero = 0;
ultimo = primero;
}else{
ultimo = S->listaocupados; //Guardamos el ultimo valor de la lista
primero = S->tdm[ultimo].sig; //Guardamos el siguiente valor
}
//Insertamos el marco
S->tdm[marco].sig = primero;
S->tdm[ultimo].sig = marco;
S->listaocupados = marco;
}
```
# Práctica 2: sim_pag_fifo2op.c
```C=
int elegir_pagina_para_reemplazo (ssistema * S)
{
int marco, victima, ultimo, condicion = 1;
/*
Elegir el siguiente al último de lista ocupados
Mientras la página esté referenciada avanzar en la lista de ocupados
Actualizar listaocupados
*/
return victima;
}
```
-->