12345678910111213141516171819202122232425262728293031323334353637383940414243openStduneopenCoretype'at={writers:('a*unitk)Queue.t;readers:'akQueue.t;mutablevalue:'aoption}(* Invariant enforced on mvars. We don't actually call this function, but we
keep it here for documentation and to help understand the implementation: *)let_invariantt=matcht.valuewith|None->Queue.is_emptyt.writers|Some_->Queue.is_emptyt.readersletcreate()={value=None;writers=Queue.create();readers=Queue.create()}letcreate_fullx={value=Somex;writers=Queue.create();readers=Queue.create()}letreadtk=matcht.valuewith|None->suspend(funk->Queue.pusht.readersk)k|Somev->(matchQueue.popt.writerswith|None->t.value<-None;kv|Some(v',w)->t.value<-Somev';resumew()(fun()->kv))letwritetxk=matcht.valuewith|Some_->suspend(funk->Queue.pusht.writers(x,k))k|None->(matchQueue.popt.readerswith|None->t.value<-Somex;k()|Somer->resumerx(fun()->k()))