123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110moduleO=Order_indirtypet={a:O.t;b:O.t;(* This strange dance with protect is to prevent the GC from collecting
values in the middle of an operation. *)lock:gc_lock;}andgc_lock={mutablelocks:int;mutableforgotten:O.tlist;}letlocklock=lock.locks<-lock.locks+1letunlocklock=lock.locks<-lock.locks-1;iflock.locks=0thenmatchlock.forgottenwith|[]->()|forgotten->lock.forgotten<-[];List.iterO.forgetforgottenletforget{lock;a;b}=iflock.locks>0thenlock.forgotten<-a::b::lock.forgottenelse(O.forgeta;O.forgetb)letis_validt=lockt.lock;letresult=O.is_validt.ainunlockt.lock;resultletroot()=leta=O.root()inletb=O.afterainlett={a;b;lock={locks=0;forgotten=[]}}inGc.finaliseforgett;tletaftert=lockt.lock;letb=O.aftert.binleta=O.beforebinlett'={a;b;lock=t.lock}inGc.finaliseforgett';unlockt.lock;t'letbeforet=lockt.lock;leta=O.beforet.ainletb=O.afterainlett'={a;b;lock=t.lock}inGc.finaliseforgett';unlockt.lock;t'letinsidet=lockt.lock;leta=O.aftert.ainletb=O.beforet.binlett'={a;b;lock=t.lock}inGc.finaliseforgett';unlockt.lock;t'letoutsidet=lockt.lock;leta=O.beforet.ainletb=O.aftert.binlett'={a;b;lock=t.lock}inGc.finaliseforgett';unlockt.lock;t'letsame_ordert1t2=O.same_ordert1.at2.atyperel=|Before|Inside|Equal|Outside|Afterletcomparet1t2=ift1==t2thenEqualelseletca=O.comparet1.at2.a<=0inletcb=O.comparet1.bt2.b<=0inmatchca,cbwith|true,true->Before|true,false->Outside|false,true->Inside|false,false->Afterletcardinalt=O.cardinalt.a/2letunsafe_checktmsg=lockt.lock;O.unsafe_checkt.a("(Order_managed_interval a) "^msg);O.unsafe_checkt.b("(Order_managed_interval b) "^msg);unlockt.lock