12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667openRresulttyperequest=Requestof{np:int;mem:int;}typeresource=Resourceof{np:int;mem:int;}typet={np:int;mem:int;mutablecurrent_np:int;mutablecurrent_mem:int;mutablewaiters:((int*int)*resourceLwt.u)list;}letcreate~np~mem={np;mem;current_np=np;current_mem=mem;waiters=[];}letdecrp~np~mem=p.current_np<-p.current_np-np;p.current_mem<-p.current_mem-memletincrp~np~mem=p.current_np<-p.current_np+np;p.current_mem<-p.current_mem+memletrequestp(Request{np;mem})=letnp=minnpp.npinifmem>p.memthenR.error_msgf"Bistro_engine.Allocator: asked more memory than available (%d against %d)"memp.mem|>Lwt.returnelseifnp<=p.current_np&&mem<=p.current_memthen(decrp~np~mem;Lwt.return(Ok(Resource{np;mem})))else(lett,u=Lwt.wait()inp.waiters<-((np,mem),u)::p.waiters;Lwt.(t>|=R.ok))letreleasep(Resource{np;mem})=letrecwake_guys_upp=function|[]->[]|(((np,mem),u)ash)::t->ifnp<=p.current_np&&mem<=p.current_memthen(decrp~np~mem;Lwt.wakeupu(Resource{np;mem});ifnp=0||mem=0thentelsewake_guys_uppt)elseh::(wake_guys_uppt)inincrp~np~mem;p.waiters<-wake_guys_upp(List.sort(fun(x,_)(y,_)->compareyx)p.waiters)