Академический Документы
Профессиональный Документы
Культура Документы
Solución
Una solución podría ser la siguiente:
______
dma.c
#include <u.h>
#include <libc.h>
#include <thread.h>
enum{
Nmaxcli = 10,
};
long putsendsem;
long getsendsem;
long getsstartsem;
long putsstartsem;
long devmutex = 1;
int ncli;
void
put(void)
{
int t;
semacquire(&devmutex, 1);
print("put\n");
t = nrand(100);
sleep(t);
if(++ncli == Nmaxcli){
semrelease(&putsendsem, 1);
ncli = 0;
}
semrelease(&devmutex, 1);
}
void
get(void)
{
int t;
semacquire(&devmutex, 1);
print("get\n");
t = nrand(100);
sleep(t);
if(++ncli == Nmaxcli){
semrelease(&getsendsem, 1);
ncli = 0;
}
semrelease(&devmutex, 1);
}
-3-
void
run(void)
{
int t;
semacquire(&devmutex, 1);
print("run\n");
t = nrand(100);
sleep(t);
semrelease(&devmutex, 1);
}
void
deviceproc(void *)
{
threadsetname("deviceproc");
for(;;){
semrelease(&putsstartsem, Nmaxcli);
semacquire(&putsendsem, 1);
run();
semrelease(&getsstartsem, Nmaxcli);
semacquire(&getsendsem, 1);
}
}
void
userproc(void *v)
{
char *name;
int id;
id = (int) v;
name = smprint("userproc: %d", id);
threadsetname(name);
void
threadmain(int, char *[])
{
int i;
srand(time(0));
proccreate(deviceproc, nil, 8*1024);
for( i = 0; i < 5*Nmaxcli; i++){
proccreate(userproc, (void *)i, 8*1024);
}
}
-4-
Aunque se podría poner un sólo semáforo para sincronizar el proceso del dispositivo, hemos decidido poner
dos para que sea más fácil de entender: putsendsem, getsendsem. Estos tres semáforos los utiliza el último
cliente para avisar al dispositivo de que ya han acabado los puts o los gets. Por otro lado, putsstartsem y
getsstartsem se utilizan para dar paso a Nmaxcli clientes para que hagan los puts o los gets. Finalmente
devmutex se utiliza para evitar el acceso concurrente al dispositivo, incluyendo la variable del dispositivo
que controla cuantos clientes han acabado con la operación actual, ncli.
-5-
C) (1,5 puntos) Suponiendo la siguiente tabla FAT, indique los clusters en orden que forman el fichero
cuya entrada de directorio indica que el cluster inicial es 4.
Cluster
_ ___________
1 5
_ ___________
2 3
-1
_ ___________
3
9
_ ___________
4
6
_ ___________
5
8
_ ___________
6
_ ___________
7 -1
7
_ ___________
8
2
_ ___________
9
... ...
-6-
Solución
A) Al reservar y liberar muchas estructuras de tamaños dispares va a haber una gran cantidad de
fragmentación externa si la implementación del asignador de memoria no contempla esta posibilidad.
Este tipo de fragmentación se produce cuando, como en este caso quedan huecos cada vez menores
dispersos y no va a haber espacio para las estructuras de tamaño mayor.
Como hay uno de los tamaños reservados que es pequeño, también habrá fragmentación interna si el
tamaño mínimo que reserva el asignador es mayor que él. Esto se resuelve bajando el tamaño mínimo
que se reserva. Esto a su vez es posible que aumente la fragmentación externa.
La estrategia que podemos utilizar para mejorar la fragmentación externa dado el tipo de programa
que se nos presenta requiere aprovecharse de la regularidad en los tamaños reservados. Una política
que implemente algún tipo de segregación de las peticiones para esos tamaños comunes funcionará
bien en este caso. Un ejemplo de política que funcionaría bien es quick-fit, que implementa una caché
para huecos de tamaño común. De esta forma se minimizaría la fragmentación al impedir que los
huecos grandes se dividiesen. Adicionalmente se obtendría el beneficio de que sería más rápido
encontrar estos huecos, obteniéndose un incremento en la velocidad de ejecución además de mini-
mizar el uso de la memoria.
B) Si suponemos que el texto del programa cabe en una página la pila en otra y que puede haber otra en
la que quepan los datos inicializados y el BSS (que pueden compartir página), el programa utilizará
en el arranque tres marcos de memoria física. Los marcos para estas páginas se reservarán al arrancar
el programa mediante sus correspondientes fallos de página.
La llamada malloc sólo apuntará la memoria como reservada pero no incrementará el uso de
memoria física. Más adelante al hacer el memset habrá un fallo de página y se utilizará otra marco
adicional. Hay que recordar que en un PC como el del laboratorio, las páginas son de 4Kbytes, con lo
que los datos del memset caben perfectamente en una página. Hemos supuesto que el memset cae
alineado dentro de una página, si no, podrían necesitarse dos.
El sistema intervendrá (cuando el programa ya está ejecutando, es decir, descontando los fallos de
página iniciales), dos veces. La primera, al hacer un malloc de un tamaño de memoria tan grande
que no cabe en las direcciones virtuales asignadas en el arranque al BSS, el asignador tendrá que lla-
mar a la llamada al sistema brk para pedir que el sistema haga crecer el segmento. Más adelante,
cuando se haga el memset, habrá un fallo de página y el sistema tendrá que intervenir para asignar
un marco para respaldar la página asociada a esa región de memoria.
C) Siguiendo las entradas en la tabla FAT, los clusters que formarán el fichero serán en este orden 4 9 2
3. El 3 es el cluster final porque tiene como entrada -1 o 0xffffffff.