Un distributore automatico è fornito di confezioni di biscotti e crackers.

Dispone di 50 cestelli, ognuno dei quali può ospitare una sola confezione.

Esistono 4 categorie di processi:

Quando un fornitore di cracker vuole inserire una confezione e ci sono cestelli liberi, non può farlo se sono valide entrambe le seguenti condizioni:

I fornitori che tentano di rifornire prodotti ma non possono farlo devono essere messi in attesa.

I consumatori che desiderano acquistare prodotti non presenti, rinunciano (non devono essere messi in attesa).

Programmare il sistema usando i semafori con la semantica tradizionale.

//semafori
sem mutex = 1, semBiscotti = 0, semCrackers = 0;

//variabili condivise
cestelliLiberi = 50, crackerIn = 0, biscottiIn = 0, attesaBiscotti = 0, attesaCracker = 0;

fornitoreBiscotti(){
	wait(mutex);
	if(cestelliLiberi > 0){
		cestelliLiberi--;
		biscottiIn++;
		signal(mutex);
	}else{
		attesaBiscotti++;
		signal(mutex);
		wait(semBiscotti);
	}
}

fornitoreCrackers(){
	wait(mutex);
	if(cestelliLiberi == 0 || (crackerIn >= biscottiIn && crackerIn >= 3)){
		attesaCracker++;
		signal(mutex);
		wait(semCrackers);
	}else{
		cestelliLiberi--;
		crackerIn++;
		signal(mutex);
	}
}

consumatoreBiscotti(){
	wait(mutex);
	if(biscottiIn > 0){
		if(attesaBiscotti > 0){
			attesaBiscotti--;
			signal(semBiscotti);
		}else if(attesaCracker > 0 && !(crackerIn >= biscottiIn-1 && crackerIn >= 3)){
			attesaCracker--;
			biscottiIn--;
			crackerIn++;
			signal(semCrackers);
		}else{
			biscottiIn--;
			cestelliLiberi++;
		}
	}
	signal(mutex);
}

consumatoreCrackers(){
	wait(mutex);
	if(crackerIn > 0){
		if(attesaBiscotti > 0){
			attesaBiscotti--;
			crackerIn--;
			biscottiIn++;
			signal(semBiscotti);
		}else if(attesaCracker > 0 && !(crackerIn >= biscottiIn && crackerIn >= 3)){
			attesaCracker--;
			signal(semCrackers);
		}else{
			crackerIn--;
			cestelliLiberi++;
		}
	}
	signal(mutex);
}