PROGRAM EF2012_3 -------------------------- MONITOR PELUQUERÍA -------------------------- MONITOR Peluqueria VAR sillonesOcupados: ARRAY [1..3] OF INTEGER; salaEspera: INTEGER; condSalaEspera: CONDITION; PROCEDURE Ingresar(sillon: OUT INTEGER): BOOLEAN; BEGIN sillon := 1 WHILE sillon <= 3 AND sillonesOcupados[sillon] DO sillon := sillon + 1; END; IF sillon == 4 THEN IF salaEspera == 5 THEN RETURN FALSE; ELSE salaEspera := salaEspera + 1; condSalaEspera.WAIT; salaEspera := salaEspera - 1; sillon := 1 WHILE sillon <= 3 AND sillonesOcupados[sillon] DO sillon := sillon + 1; END; END; END; sillonesOcupados[sillon] := TRUE; RETURN TRUE; END; PROCEDURE Egresar(sillon: IN INTEGER); BEGIN sillonesOcupados[sillon] := FALSE; condSalaEspera.SIGNAL; END; BEGIN FOR i := 1 TO 3 DO sillonesOcupados[i] := FALSE; END; salaEspera := 0; END; -------------------------- MONITOR ÁREA TRABAJO -------------------------- MONITOR AreaTrabajo VAR clienta: ARRAY [1..3] OF CONDITION; peluquera: CONDITION; colorista: CONDITION; coloristaOcupada: BOOLEAN; cantCondCorte: INTEGER; cantCondBrushing: INTEGER; cantCondTinta: INTEGER; colaCorte: COLA OF INTEGER; colaTinta: COLA OF INTEGER; colaBrushing: COLA OF INTEGER; PROCEDURE Clienta (sillon: IN INTEGER; corte: IN BOOLEAN; tinta: IN BOOLEAN; brushing: IN BOOLEAN) BEGIN IF corte THEN cantCondCorte := cantCondCorte + 1; colaCorte.put(sillon); peluquera.SIGNAL; clienta[sillon].WAIT; END; IF tinta THEN cantCondTinta := cantCondTinta + 1; colaTinta.put(sillon); IF coloristaOcupada THEN peluquera.SIGNAL; ELSE colorista.SIGNAL; END; clienta[sillon].WAIT; END; IF brushing THEN cantCondBrushing := cantCondBrushing + 1; colaBrushing.put(sillon); colorista.SIGNAL; clienta[sillon].WAIT; END; END; PROCEDURE ObtenerTrabajoPeluquera(sillon: IN INTEGER; tipoTrabajo: IN {CORTE, TINTA}) BEGIN IF cantCondCorte == 0 AND cantCondTinta == 0 THEN peluquera.WAIT; END; IF cantCondCorte > 0 THEN cantCondCorte := cantCondCorte - 1; tipoTrabajo := CORTE; sillon := colaCorte.get(); ELSE cantCondTinta := cantCondTinta - 1; tipoTrabajo := TINTA; sillon := colaTinta.get(); END; END; PROCEDURE ObtenerTrabajoColorista(sillon: IN INTEGER; tipoTrabajo: IN {TINTA, BRUSHING}) BEGIN IF cantCondTinta == 0 AND cantCondBrushing == 0 THEN coloristaOcupada := FALSE; colorista.WAIT; coloristaOcupada := TRUE; END; IF cantCondBrushing > 0 THEN cantCondBrushing := cantCondBrushing - 1; tipoTrabajo := BRUSHING; sillon := colaBrushing.get(); ELSE cantCondTinta := cantCondTinta - 1; tipoTrabajo := TINTA; sillon := colaTinta.get(); END; END; PROCEDURE Finalizar(sillon: IN INTEGER) BEGIN clienta[sillon].SIGNAL; END; BEGIN coloristaOcupada := FALSE; cantCondCorte := 0; cantCondBrushing := 0; cantCondTinta := 0; END; -------------------------- PROCEDIMIENTOS -------------------------- PROCEDURE Clienta() VAR corte: BOOLEAN; tinta: BOOLEAN; brushing: BOOLEAN; sillon: INTEGER; BEGIN IF Peluqueria.Ingresar(sillon) THEN queServicios(corte, tinta, brushing); AreaTrabajo.Clienta(sillon, corte, tinta, brushing); Peluqueria.Egresar(sillon); pagar(); END; END; PROCEDURE Peluquera() BEGIN LOOP AreaTrabajo.ObtenerTrabajoPeluquera(sillon, tipoTrabajo); IF tipoTrabajo == CORTE THEN cortarPelo(sillon); ELSE hacerTinta(sillon); END; AreaTrabajo.Finalizar(sillon); END; END; PROCEDURE Colorista(); BEGIN LOOP AreaTrabajo.ObtenerTrabajoColorista(sillon, tipoTrabajo); IF tipoTrabajo == TINTA THEN hacerTinta(sillon); ELSE hacerBrushing(sillon); END; AreaTrabajo.Finalizar(sillon); END; END; -------------------------- PROGRAMA PRINCIPAL -------------------------- BEGIN COBEGIN Peluquera(); Peluquera(); Colorista(); Clienta(); ... Clienta(); COEND; END.