sábado, 3 de abril de 2010

Encrucijada (y II: Solución)

Y aquí os dejo con la ansiada respuesta que entregué y con la que saqué un 9 (por culpa de que leí mal el enunciado, pero bueno la vida es así). No os la pongo con comentarios porque no se dónde tengo la versión final con lo comentarios. Lo primero viene la situación de los semáforos, el esquema básico de sincronismo y el código en C. Espero que os resulte útil.
Siento mucho lo mal que se ve pero no podía hacer nada mejor...

Situación inicial de los semáforos:
procesos = Max_proc – 1;
C1 = 0;
C2 = 0;
P1 = 1;
P2 = 0;
Cruce = 1;
Nacer = 1;

Esquema de sincronización

Padre

Leer_línea_comandos();

Crea_IPCS();

Prepara_IPCS();

CRUCE_inicio();

W(procesos);

Nace_ciclo_semafórico();

Por siempre jamás{

W(procesos);

Nace_coche_o_peatón();

}

Acabar

Si padre{

CRUCE_fin();

W(max_proc-1)(procesos);

Destruye_IPCS();

Muere();

} Si no{

Muerte_hijo();

}

Muerte_hijo

S(procesos);

Muere();

Ciclo_semafórico

SemC2 = Rojo;

Por siempre jamás{

W(P1);

SemP1 = Rojo;

SemC1 = Verde;

SemP2 = Verde;

S(C1) S(P2);

Pausa⁶();

W(C1) W(P2);

SemC1 = Amarillo;

SemP2 = Rojo;

Pausa²();

W(Cruce);

SemC1 = Rojo;

S(Cruce);

SemC2 = Verde;

S(C2);

Pausa⁸();

W(C2);

SemC2 = Amarillo;

Pausa²();

W(Cruce);

SemC2 = Rojo;

S(Cruce);

SemP1 = Verde;

S(P1);

Pausa⁶();

Coche

CRUCE_inicio_coche();

Mientras(posicion_válida){

Mueve_coche();

Pausa();

}

Fin_coche();

Envia_mensajes_última_posición();

Muerte_hijo();

Mueve_coche

Si (pos = posC1){

W(C1) W(Cruce);

Recibe_mensajes_pos_sig();

avanza();

S(C1);

} Si No si (pos == posC2){

W(C2);

Recibe_mensajes_pos_sig();

avanza();

S(C2);

}Si no{

Si (pos == pos_cruce){

W(Cruce);

}

Recibe_mensajes_posicion_sig();

avanza();

}

Si (sales_del_cruce){

S(Cruce);

}

Si (pos_anterior_válida){

Envia_mensajes_pos_anterior();

}

actualiza_pos_anterior();

}

Peatón

W(Nacer);

Nace();

Recibe_mensaje_pos_nac();

Mientras(posición_válida){

Mueve_peatón();

Mueve_peatón();

Pausa();

}

Fin_peatón();

Envía_mensaje_última_pos();

Muerte_hijo();

Mueve_peatón

Si (sale_zona_nacimiento){

S(Nacer);

}

Recibe_mensaje_pos_sig();

Si (pos == posP1){

W(P1);

Muevete();

S(P1);

} Si no Si(pos == posP2){

W(P2);

Muevete();

S(P2);

} Si no{

Muevete();

}

Si (anterior_válido){

Envía_mensaje_pos_anterior();

}

Actualiza_anterior();


Código


#include "cruce.h"

#include

#include

#include

#include

#include

#include

#include

#include


#define EXERR 1


//#define _HPUX

#define _PEAT

#define _SEMA

#define _COCH

#define _MSGS


void morir(int sennal);

void terminar(int sennal);

void exhortizar(int sennal);

int nace_hijo();

void muerte_peat();

void muerte_coch();

void muerte_hijo();

void ciclo_semaforico();

void coche();

int pos_valida(struct posiciOn);

void peaton();

void error();


int semaforo = -1, mcomp = -1, buzon = -1;

int ppid;

char * pmem = NULL;

int max_proc;


#ifndef _HPUX

union semun{

int val;

struct semid_ds *buf;

ushort_t *array;

};

#endif


typedef struct mensaje{

long tipo;

char info;

} mensaje;


int main(int argc, char * argv[]){

struct sigaction manejadora;

struct sembuf procesos[1];

#ifndef _HPUX

union semun sem;

#endif

int vel, tipo;

int i, j;

long tipomen;

mensaje msg;


if(argc != 3){

printf("Error en el paso de argumentos.\n");

return 1;

}

max_proc = atoi(argv[1]);

vel = atoi(argv[2]);

ppid = getpid();


manejadora.sa_handler = morir;

if(sigfillset(&manejadora.sa_mask) == -1) return EXERR;

manejadora.sa_flags = 0;

if(sigaction(SIGINT, &manejadora, NULL) == -1)return EXERR;

manejadora.sa_handler = terminar;

if(sigemptyset(&manejadora.sa_mask) == -1)return EXERR;

manejadora.sa_flags = 0;

if(sigaction(SIGTERM, &manejadora, NULL) == -1)return EXERR;

if(signal(SIGCHLD, SIG_IGN) == SIG_ERR)return EXERR;


semaforo = semget(IPC_PRIVATE, 9, IPC_CREAT|0600);

if(semaforo == -1) error();

mcomp = shmget(IPC_PRIVATE, 256, IPC_CREAT|0600);

if(mcomp == -1)error();

pmem = (char *)shmat(mcomp, NULL, 0);

if(pmem == NULL) error();

buzon = msgget(IPC_PRIVATE, IPC_CREAT|0600);

if(buzon == -1) error();

#ifndef _HPUX

sem.val = max_proc-1;

if(semctl(semaforo, 1, SETVAL, sem) == -1)error();

sem.val = 0;

if(semctl(semaforo, 2, SETVAL, sem) == -1)error();

sem.val = 0;

if(semctl(semaforo, 3, SETVAL, sem) == -1)error();

sem.val = 1;

if(semctl(semaforo, 4, SETVAL, sem) == -1)error();

sem.val = 0;

if(semctl(semaforo, 5, SETVAL, sem) == -1)error();

sem.val = 1;

if(semctl(semaforo, 6, SETVAL, sem) == -1)error();

sem.val = 1;

if(semctl(semaforo, 7, SETVAL, sem) == -1)error();

#else

if(semctl(semaforo, 1, SETVAL, max_proc-1) == -1)error();

if(semctl(semaforo, 2, SETVAL, 0) == -1)error();//Semáforos C1

if(semctl(semaforo, 3, SETVAL, 0) == -1)error(); //C2

if(semctl(semaforo, 4, SETVAL, 1) == -1)error(); //P1

if(semctl(semaforo, 5, SETVAL, 0) == -1)error(); //P2 según como estarían al acabar la ultima fase

if(semctl(semaforo, 6, SETVAL, 1) == -1)error(); //CRUCE

if(semctl(semaforo, 7, SETVAL, 1) == -1)error(); //NACE

#endif


for(i = 0; i <= 16; i++){

for(j = 0; j <= 50; j++){

msg.tipo = 1 + i*100 + j;

msg.info = 'v';

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1)error();

}

}


procesos[0].sem_num = 1;

procesos[0].sem_op = -1;

procesos[0].sem_flg = 0;


CRUCE_inicio(vel, max_proc, semaforo, pmem);

#ifdef _SEMA

if(semop(semaforo, procesos, 1) == -1)error();

switch(nace_hijo()){

case 0:

ciclo_semaforico();

return 1;

}

#endif

while(1){

if(semop(semaforo, procesos, 1) == -1)kill(0, SIGTERM);

tipo = CRUCE_nuevo_proceso();

switch(nace_hijo()){

case 0:

switch (tipo){

#ifdef _COCH

case COCHE:

coche();

#endif


#ifdef _PEAT

case PEAToN:

peaton();

#endif

default:

muerte_hijo();

}

default:

break;

}

}

}


void error(){

struct shmid_ds buf;

if(semaforo != -1) semctl(semaforo, 0, IPC_RMID);

if(mcomp != -1){

shmdt(pmem);

shmctl(mcomp, IPC_RMID, &buf);

}

if(buzon != -1) msgctl(buzon, IPC_RMID, NULL);

_Exit(EXERR);

}


void morir(int sennal){

struct sembuf sem[1];

struct shmid_ds buf;

sem[0].sem_flg = 0;

if(getpid() == ppid){

CRUCE_fin();

sem[0].sem_num = 1;

sem[0].sem_op = -(max_proc - 2);

if(semop(semaforo, sem, 1) == -1) kill(0, SIGTERM);

if(semaforo != -1) if(semctl(semaforo, 0, IPC_RMID) == -1) kill(0, SIGTERM);

if(mcomp != -1){

if(shmdt(pmem) == -1) kill(0, SIGTERM);

if(shmctl(mcomp, IPC_RMID, &buf) == -1) kill(0, SIGTERM);

}

if(buzon != -1) if(msgctl(buzon, IPC_RMID, NULL) == -1) kill(0, SIGTERM);

}

else{

muerte_hijo();

}

_Exit(0);

}


void terminar(int sennal){

struct shmid_ds buf;

if(getpid() == ppid){

CRUCE_fin();

if(semaforo != -1) semctl(semaforo, 0, IPC_RMID);

if(mcomp != -1){

shmdt(pmem);

shmctl(mcomp, IPC_RMID, &buf);

}

if(buzon != -1) msgctl(buzon, IPC_RMID, NULL);

}

else{

muerte_hijo();

}

_Exit(EXERR);

}


void muerte_hijo(){

struct sembuf procesos[1];

procesos[0].sem_num = 1;

procesos[0].sem_op = 1;

procesos[0].sem_flg = 0;

if(semop(semaforo, procesos, 1))kill(0, SIGTERM);

_Exit(0);

}


int nace_hijo(){

int pid;

if(ppid == getpid()){

pid = fork();

switch(pid){

case -1:

kill(0, SIGTERM);

break;

case 0:

return 0;

default:

return pid;

}

}

}


void ciclo_semaforico(){

struct sembuf pon_sem[3];

pon_sem[0].sem_flg = 0;

pon_sem[1].sem_flg = 0;

pon_sem[2].sem_flg = 0;


CRUCE_pon_semAforo(SEM_C2, ROJO);

while(1){

pon_sem[0].sem_num = 4;

pon_sem[0].sem_op = -1; //P1

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

CRUCE_pon_semAforo(SEM_P1, ROJO);

pon_sem[0].sem_num = 2;

pon_sem[0].sem_op = 1;//C1

pon_sem[1].sem_num = 5;

pon_sem[1].sem_op = 1; //P2

CRUCE_pon_semAforo(SEM_C1, VERDE);

CRUCE_pon_semAforo(SEM_P2, VERDE);

if(semop(semaforo, pon_sem, 2))kill(0, SIGTERM);

pausa();

pausa();

pausa();

pausa();

pausa();

pausa();

pon_sem[0].sem_num = 2;

pon_sem[0].sem_op = -1;//C1

pon_sem[1].sem_num = 5;

pon_sem[1].sem_op = -1; //P2

if(semop(semaforo, pon_sem, 2))kill(0, SIGTERM);

CRUCE_pon_semAforo(SEM_C1, AMARILLO);

CRUCE_pon_semAforo(SEM_P2, ROJO);

pausa();

pausa();

pon_sem[0].sem_num = 6; //CRUCE

pon_sem[0].sem_op = -1;

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

CRUCE_pon_semAforo(SEM_C1, ROJO);

pon_sem[0].sem_op = 1;

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);


CRUCE_pon_semAforo(SEM_C2, VERDE);

pon_sem[0].sem_num = 3; //C2

pon_sem[0].sem_op = 1;

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

pausa();

pausa();

pausa();

pausa();

pausa();

pausa();

pausa();

pausa();

pon_sem[0].sem_num = 3;

pon_sem[0].sem_op = -1;//C2

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

CRUCE_pon_semAforo(SEM_C2, AMARILLO);

pausa();

pausa();

pon_sem[0].sem_num = 6;

pon_sem[0].sem_op = -1;

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

CRUCE_pon_semAforo(SEM_C2, ROJO);


pon_sem[0].sem_op = 1; //amar

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);


CRUCE_pon_semAforo(SEM_P1, VERDE);

pon_sem[0].sem_num = 4; //P1

pon_sem[0].sem_op = 1;

if(semop(semaforo, pon_sem, 1))kill(0, SIGTERM);

pausa();

pausa();

pausa();

pausa();

pausa();

pausa();

}

}


struct posiciOn mueve_coche(struct posiciOn pos, struct posiciOn * anterior){

struct sembuf procesos[1], semc1[2], semc2[2], amarillo[1];

struct mensaje msg, msg_ant;

long tipo;

struct posiciOn sig;

semc1[0].sem_num = 2;

semc1[0].sem_op = -1;

semc1[0].sem_flg = 0;

semc2[0].sem_num = 3;

semc2[0].sem_op = -1;

semc2[0].sem_flg = 0;

semc2[1].sem_num = 6; //CRUCE

semc2[1].sem_op = -1;

semc2[1].sem_flg = 0;

semc1[1].sem_num = 6; //CRUCE

semc1[1].sem_op = -1;

semc1[1].sem_flg = 0;

amarillo[0].sem_num = 6;

amarillo[0].sem_op = -1;

amarillo[0].sem_flg = 0;

#ifdef _SEMA

if((pos.y == 6) && (pos.x == 33)){

if(semop(semaforo, semc1, 2))kill(0, SIGTERM);

#ifdef _MSGS

tipo = 1 + pos.y*100 + (pos.x);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 1);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 2);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 3);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 4);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

#endif

sig = CRUCE_avanzar_coche(pos);

semc1[0].sem_op = 1;

if(semop(semaforo, semc1, 1))kill(0, SIGTERM);

}

else if((pos.y == 10) && (pos.x == 13)){

if(semop(semaforo, semc2, 1))kill(0, SIGTERM);

#ifdef _MSGS

tipo = 1 + (pos.y)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-1)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-2)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-1)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-2)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

#endif

sig = CRUCE_avanzar_coche(pos);

semc2[0].sem_op = 1;

if(semop(semaforo, semc2, 1))kill(0, SIGTERM);

}else{

#ifdef _MSGS

if (pos.x == 33 && pos.y == 6){

amarillo[0].sem_num = 6;

amarillo[0].sem_op = -1;

if(semop(semaforo, amarillo, 1))kill(0, SIGTERM);

} else if(pos.x == 23 && pos.y == 10){

amarillo[0].sem_num = 6;

amarillo[0].sem_op = -1;

if(semop(semaforo, amarillo, 1))kill(0, SIGTERM);

}

if(pos.x == 33 && pos.y == 10 && anterior->y == 10 && anterior->x == 31){

tipo = 1 + (pos.y + 1)*100 + (pos.x);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y + 1)*100 + (pos.x + 1);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y + 1)*100 + (pos.x + 2);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y + 1)*100 + (pos.x + 3);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y + 1)*100 + (pos.x + 4);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

}

else if(pos.x < y ="="">

tipo = 1 + (pos.y)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-1)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-2)*100 + (pos.x + 5);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-1)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + (pos.y-2)*100 + (pos.x + 6);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

}

else if(pos.y <= 16 ){

tipo = 1 + pos.y*100 + (pos.x);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 1);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 2);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 3);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

tipo = 1 + pos.y*100 + (pos.x + 4);

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

}

#endif

sig = CRUCE_avanzar_coche(pos);

}

#else

sig = CRUCE_avanzar_coche(pos);

#endif


if(pos.x == 33 && pos.y == 13){

amarillo[0].sem_op = 1;

if(semop(semaforo, amarillo, 1) == -1) kill(0, SIGTERM);

}

if((anterior->x != -1) && (anterior->y != -1)){

if(pos.x == 33 && pos.y == 10 && anterior->y == 10 && anterior->x == 31){

msg.tipo = 1 + (anterior->y - 2)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 1)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 2)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 1)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

}

else if(anterior->x <= 31 && anterior->x == 1){

msg.tipo = 1 + (anterior->y - 2)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 1)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

}

else if(anterior->x <= 31 && anterior->x >= 3){

msg.tipo = 1 + (anterior->y - 2)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 1)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 2)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 1)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

}

else if (pos.x == 33 && pos.y == 12 && anterior->y == 10 && anterior->x == 33);

else if (anterior->y > 4 && anterior->x >31 && pos.y <>

msg.tipo = 1 + (anterior->y - 4)*100 + (anterior->x + 4);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 4)*100 + (anterior->x + 3);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 4)*100 + (anterior->x + 2);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 4)*100 + (anterior->x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior->y - 4)*100 + (anterior->x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

}

}

if (pos.x == 33 && pos.y == 10 && anterior->y == 10 && anterior->x == 31){

anterior->x = 33;

anterior->y = 10;

}else{

anterior->x = pos.x;

anterior->y = pos.y;

}

return sig;

}


void coche(){

struct sembuf procesos[1];

struct posiciOn pos, anterior = {-1, -1};

struct mensaje msg;

procesos[0].sem_num = 1;

procesos[0].sem_op = 1;

procesos[0].sem_flg = 0;

pos = CRUCE_inicio_coche();

while(1){

pos = mueve_coche(pos, &anterior);

if(!pos_valida(pos)) break;

pausa();

}

CRUCE_fin_coche();

msg.tipo = 1 + (anterior.y - 4)*100 + (anterior.x + 4);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior.y - 4)*100 + (anterior.x + 3);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior.y - 4)*100 + (anterior.x + 2);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior.y - 4)*100 + (anterior.x + 1);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

msg.tipo = 1 + (anterior.y - 4)*100 + (anterior.x);

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

muerte_hijo();

}


int pos_valida(struct posiciOn pos){

if(pos.y <>

else return 1;

}


struct posiciOn mueve_peaton(struct posiciOn pos, struct posiciOn * anterior){

struct posiciOn sig;

struct sembuf semp2[1], semp1[1], semnac[1];

struct mensaje msg, msg_ant;

static int critica = 1;

long tipo;

semp2[0].sem_num = 5;

semp2[0].sem_flg = 0;

semp2[0].sem_op = -1;

semp1[0].sem_num = 4;

semp1[0].sem_flg = 0;

semp1[0].sem_op = -1;

semnac[0].sem_num = 7;

semnac[0].sem_flg = 0;

semnac[0].sem_op = -1;


tipo = 1 + pos.x + pos.y*100;

if(((anterior->y == 16 && anterior->x <>x == 0 && anterior->y <= 16 && anterior->y > 11)) && (critica == 0)){

semnac[0].sem_op = -1;

if(semop(semaforo, semnac, 1) == -1) kill(0, SIGTERM);

critica = 1;

} else if ((anterior->y <= 15 && (anterior->x > 0)) && (critica == 1)){

semnac[0].sem_op = 1;

if(semop(semaforo, semnac, 1) == -1) kill(0, SIGTERM);

critica = 0;

}

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

#ifdef _SEMA

if((pos.x <> 20) && (pos.y == 11)){

if(semop(semaforo, semp2, 1) == -1) kill(0, SIGTERM);

sig = CRUCE_avanzar_peatOn(pos);

semp2[0].sem_op = 1;

if(semop(semaforo, semp2, 1) == -1) kill(0, SIGTERM);

}

else if((pos.y <> 12) && (pos.x == 30)){

if(semop(semaforo, semp1, 1) == -1) kill(0, SIGTERM);

sig = CRUCE_avanzar_peatOn(pos);

semp1[0].sem_op = 1;

if(semop(semaforo, semp1, 1) == -1) kill(0, SIGTERM);

}

else sig = CRUCE_avanzar_peatOn(pos);

#else

sig = CRUCE_avanzar_peatOn(pos);

#endif

if((anterior->x != -1) && (anterior->y != -1)){

msg_ant.tipo = 1 + anterior->x + anterior->y*100;

if(msgsnd(buzon, &msg_ant, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

}

anterior->x = pos.x;

anterior->y = pos.y;

return sig;

}


void peaton(){

struct sembuf procesos[1], semnac[1];

struct posiciOn pos, anterior = {-1, -1};

struct mensaje msg;

long tipo;

procesos[0].sem_num = 1;

procesos[0].sem_op = 1;

procesos[0].sem_flg = 0;

semnac[0].sem_num = 7;

semnac[0].sem_op = -1;

semnac[0].sem_flg = 0;

if(semop(semaforo, semnac, 1) == -1) kill(0, SIGTERM);

pos = CRUCE_inicio_peatOn_ext(&anterior);

tipo = 1 + anterior.y*100 + anterior.x;

if(msgrcv(buzon, &msg, sizeof(mensaje), tipo, MSG_NOERROR) == -1) kill(0, SIGTERM);

while(1){

pos = mueve_peaton(pos, &anterior);

if(!pos_valida(pos)) break;

pos = mueve_peaton(pos, &anterior);

if(!pos_valida(pos)) break;

pausa();

}

msg.tipo = 1 + anterior.x + anterior.y*100;

msg.info = 'v';

CRUCE_fin_peatOn();

if(msgsnd(buzon, &msg, sizeof(mensaje) - sizeof(long), 0) == -1) kill(0, SIGTERM);

muerte_hijo();

}

3 comentarios:

Raiden dijo...

En primer lugar agradecerte el haber colgado este ejercicio, solución y explicaciones adjuntas; resulta muy interesante. Me gustaría saber si puedes enviarme por correo el código, pues leyendo del blog es una locura dada la estructura del mismo: raiden [arroba] raiden.tk

También hay algún detalle de la práctica que me gustaría aprovechar para comentarte.

Gracias por compartir tu tiempo.

Un saludo.

Raiden dijo...

Retiro lo dicho, te puedes imaginar porqué...uno pregunta antes de buscar ;-) ¡Muchas gracias de nuevo!

twisen dijo...

¡Me alegro que a alguien le resulte interesante! :)
Si necesitas cualquier otra cosa, sin problemas