Skip to content

Instantly share code, notes, and snippets.

@ichramm
Last active May 11, 2020 13:49
Show Gist options
  • Save ichramm/9fb699861c9abcb7ef09ed4286f76a05 to your computer and use it in GitHub Desktop.
Save ichramm/9fb699861c9abcb7ef09ed4286f76a05 to your computer and use it in GitHub Desktop.
p05e09
monitor coso_mojo
bool enviando;
condition cond_enviar;
int cant_esperando;
int cant_pendientes;
condition cond_recibir;
TMensaje mensaje_actual;
void enviar_sinc_mult(cant_destinos: in integer, mensaje: in TMensaje) {
if cant_destinos <= 0 {
// ERROR;
}
// si ya hay un envio en proceso, espero
if (enviando) {
cond_enviar.wait();
}
// marco como que estoy enviando asi los demas quedan bloqueados en el wait
enviando = true;
mensaje_actual = mensaje;
cant_pendientes = cant_destinos;
// si no hay gente suficiente, espero
if (cant_esperando < cant_pendientes) {
cond_recibir.wait();
}
// notifico al siguiente (o al primero), notar que no es un else
if (cant_pendientes > 0) {
cond_recibir.signal();
}
}
void recibir_sinc_mult (mensaje: out TMensaje) {
cant_esperando = cant_esperando + 1;
// un receptor espera si no hay nadie enviando, o si aun no hay suficientes lectores
if (!enviando || cant_esperando < cant_pendientes) {
cond_recibir.wait();
}
// si lo despiertan es porque hay mensaje
mensaje = mensaje_actual;
// le resto a los dos, parece redundante pero en realidad no lo es porque
// cant_esperando puede ser arbitrariamente grande, cant_pendientes se
// inicializa con cant_destinos
cant_esperando = cant_esperando - 1;
cant_pendientes = cant_pendientes - 1;
if (cant_pendientes == 0) {
// si cant_pendientes es cero, entonces se terminó con este batch
enviando = false;
cond_enviar.signal();
} else {
// si cant_pendientes no es cero, entonces, por contrucción, aún no se
// termino de despertar a todo el mundo
cond_recibir.signal();
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment