1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465moduleP=CatapultmoduleAtomic=P.Atomic_shim_(* emulate thread local storage *)moduleInt_map=Map.Make(structtypet=intletcompare:int->int->int=compareend)type'avalue={value:'a;}[@@unboxed](** A thread-local map. *)type'at={map:'avalueInt_map.tAtomic.t;init:t_id:int->'a;close:'a->unit;}let[@inline]modify_map_~f(self:_t)=whilenot(letcur=Atomic.getself.mapinletnew_=fcurinAtomic.compare_and_setself.mapcurnew_)do()doneletsizeself=Int_map.cardinal(Atomic.getself.map)letremove(self:_t)~t_id=letm=Atomic.getself.mapinmatchInt_map.find_optt_idmwith|None->()|Somevalue->modify_map_self~f:(funm->Int_map.removet_idm);self.closevalue.valueletget_or_createself:'a=lett=Thread.self()inlett_id=Thread.idtinletm=Atomic.getself.mapinmatchInt_map.find_optt_idmwith|Somev->v.value|None->letv={value=self.init~t_id}inmodify_map_self~f:(funm->Int_map.addt_idvm);Gc.finalise(fun_->removeself~t_id)t;v.valueletiter~fself=letm=Atomic.getself.mapinInt_map.iter(fun_v->fv.value)mletclearself=letm=Atomic.exchangeself.mapInt_map.emptyinInt_map.iter(fun_v->self.closev.value)mletcreate~init~close():_t=letm={map=Atomic.makeInt_map.empty;init;close;}inGc.finaliseclearm;m