Por Favor, Ayuda en programa en C.

franck121003
26 de Octubre del 2008
Buenas tardes.
El presente tema de este foro, se centra en el problema que he tenido con un programa que encontré que simula la paginación que realiza un sistema operativo, lo he intendado corregir, pero como aún no poseo mucha experiencia con C, no lo he podido arreglar del todo. Agradecería de antemano,uncione. Gracias por su atención.

Aquí está el código fuente: si alguien me puede ayudar a que el programa:

include <time.h>
include <math.h>
include <limits.h>
include <stdio.h>
include <stdlib.h>
include <signal.h>
include <sys/sem.h>

define SEM_DD 0

int semid;
int tamano, tiempo;
int tamanoMemoria, tamanoDD;
int bitsMarco, bitsMemoria, bitsDD, noProcesos, noMarcos;
int *memoria, *dd, *pidAdmin;

// funciones semaforos

void semp (int semnum) {
struct sembuf operacion;
operacion.sem_flg = 0;
operacion.sem_num = semnum;
operacion.sem_op = -1;
semop(semid, &operacion, 1);
}

void semv (int semnum) {
struct sembuf operacion;
operacion.sem_flg = 0;
operacion.sem_num = semnum;
operacion.sem_op = 1;
semop(semid, &operacion, 1);
}

// administrar memoria

int ceros (int *memoriaX, int tamanoX) {
int i;

for (i = 0; i < tamanoX; i += 3) {
memoriaX[i] = 0;
memoriaX[i + 1] = 0;
memoriaX[i + 2] = 0;
}
}

int imprimir (int *memoriaX, int tamanoX) {
int i;

for (i = 0; i < tamanoX; i += 3) {
printf("%5d", memoriaX[i]);
printf("%5d", memoriaX[i + 1]);
printf("%5d", memoriaX[i + 2]);
printf("n");
}

printf("n");
}

int paginasDisponibles (int *memoriaX, int tamanoX, int tamanoP) {
int i, tamano = 0;

for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] == 0) {
tamano++;
if (tamano == tamanoP)
return 1;
}
}

return 0;
}

int meter (int *memoriaX, int tamanoX, int pid, int tamanoP) {
int i, pagina = 0;

semp(SEM_DD);
if (paginasDisponibles(memoriaX, tamanoX, tamanoP)) {
for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] == 0) {
memoriaX[i] = pid;
memoriaX[i + 1] = pagina++;
memoriaX[i + 2] = -1;
if (pagina == tamanoP)
break;
}
}
//imprimir (memoriaX, tamanoX);

semv(SEM_DD);
return 1;
}

semv(SEM_DD);
return 0;
}

void sacar (int *memoriaX, int tamanoX, int pid) {
int i;

semp(SEM_DD);
for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] == pid) {
memoriaX[i] = 0;
memoriaX[i + 1] = 0;
memoriaX[i + 2] = 0;
}
}
semv(SEM_DD);
}

int procesoMasDormido (int *memoriaX, int tamanoX) {
int i, pid = 0, quantum = INT_MAX;

for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] != 0 && memoriaX[i + 2] < quantum) {
pid = memoriaX[i];
quantum = memoriaX[i + 2];
}
}

return pid;
}

int procesoMenosDormido (int *memoriaX, int tamanoX) {
int i, pid = 0, quantum = 0;

for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] != 0 && memoriaX[i + 2] > quantum) {
pid = memoriaX[i];
quantum = memoriaX[i + 2];
}
}

return pid;
}
void dormirProceso (int *memoriaX, int tamanoX, int pid, int quantum) {
int i;

for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] == pid) {
memoriaX[i + 2] = quantum;
}
}
}

int tamanoProceso (int *memoriaX, int tamanoX, int pid) {
int i, tamano = 0;

for (i = 0; i < tamanoX; i += 3) {
if (memoriaX[i] == pid) {
tamano++;
}
}

return tamano;
}


// funciones procesos y administrador

void trabajoAdministrador () {
int pid, quantum = 0, adentro;

while (1) {
// proximo proceso a ejecutar
pid = procesoMasDormido(dd, tamanoDD);
if (pid == 0) continue;

printf(" DD: n");
imprimir(dd, tamanoDD);

if (tamanoProceso(memoria, tamanoMemoria, pid) == 0) {
// meter proceso en memoria porque no esta
adentro = 0;

do {
if ((adentro = meter(memoria, tamanoMemoria, pid, tamanoProceso(dd, tamanoDD, pid))) == 0) {
// no cabe, habra que quitar algun proceso
sacar(memoria, tamanoMemoria, procesoMenosDormido(memoria, tamanoMemoria));
}
} while (!adentro);
}

printf(" MEMORIA PRINCIPAL: n");
imprimir(memoria, tamanoMemoria);

// ejecutar proceso y dormir adminitrador
sleep(1);
kill(pid, SIGCONT);
kill(getpid(), SIGSTOP);

// actualizar datos de procesos
dormirProceso(dd, tamanoDD, pid, quantum);
dormirProceso(memoria, tamanoMemoria, pid, quantum);

// siguiente quantum
quantum++;
}
}

void trabajoProceso () {
int loop = 1;
//printf(" pid=%d tamano=%d tiempo=%d n", getpid(), tamano, tiempo);

while(! meter(dd, tamanoDD, getpid(), tamano)) {
sleep(1);
}

while (loop) {
kill(getpid(), SIGSTOP);

printf(" %d estoy trabajando n", getpid());

if(--tiempo == 0) {
sacar(memoria, tamanoMemoria, getpid());
sacar(dd, tamanoDD, getpid());
loop = 0;
}
sleep(1);
kill(*pidAdmin, SIGCONT);
}
}


int main (int argc, char* argv[]) {
int i, shmid, pid;
int maxTamano, maxTiempo = 3;
key_t llave;

srand(time(NULL));

// parámetros de entrada
if (argc < 5) {
fprintf(stderr, "Modo de empleo: %s bitsMarco bitsMemoria bitsDD noProcesos n", argv[0]);
fprintf(stderr, "Simular páginación. n");
exit(-1);
}

bitsMarco = atoi(argv[1]);
bitsMemoria = atoi(argv[2]);
bitsDD = atoi(argv[3]);
noProcesos = atoi(argv[4]);
noMarcos = pow(2, bitsMemoria - bitsMarco);
maxTamano = pow(2, bitsMarco) * noMarcos / 2;

// crear llave
llave = ftok(argv[0], 'a');

// crear un semaforo
semid = semget(llave, 1, IPC_CREAT | 0600);

// inicializar semaforo
semctl(semid, SEM_DD, SETVAL, 1);

// pedir zona de memoria compartida
tamanoMemoria = pow(2, bitsMemoria) * 3; // [pid][pagina][segundo=-1]
tamanoDD = pow(2, bitsDD) * 3;
shmid = shmget(llave, (tamanoMemoria + tamanoDD + 1) * sizeof(int), IPC_CREAT | 0600);
// unir zona de memoria compartida a nuestro espacio de direcciones virtuales
memoria = (int*) shmat(shmid, 0, 0);

// repartir zona de memoria compartida
dd = memoria + tamanoMemoria;
pidAdmin = memoria + tamanoMemoria + tamanoDD;
ceros(dd, tamanoDD);
ceros(memoria, tamanoMemoria);

//printf("yupi!");fflush(stdout);

// crear procesos
for (i = 0; i < noProcesos; i++) {
tamano = rand() % maxTamano + 1;
tiempo = rand() % maxTiempo + 1;

if ((pid = fork()) == -1) {
perror("fork");
exit(-1);
}
else if (pid == 0) {
trabajoProceso();
exit(0);
}
}

// crear administrador
if ((*pidAdmin = fork()) == -1) {
perror("fork");
exit(-1);
}
else if (*pidAdmin == 0) {
trabajoAdministrador();
exit(0);
}

// esperar procesos
for (i = 0; i < noProcesos; i++) {
printf(" :X %d n", wait(NULL));
}

// matar al administrador
kill(*pidAdmin, SIGINT);

// separar la zona de memoria compartida de nuestro espacio de direcciones virtuales
shmdt(memoria);

// borrar zona de memoria compartida
shmctl(shmid, IPC_RMID, 0);

// borrar semáforos
semctl(semid, 0, IPC_RMID, 0);
}