1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465# 1 "clib/memprof_coq.memprof.ml"(* From memprof_limits, see also https://gitlab.com/gadmm/memprof-limits/-/issues/7 *)letis_interrupted()=Memprof_limits.is_interrupted()[@@inline]moduleResource_bind=Memprof_limits.Resource_bind(* Not exported by memprof limits :( *)(* module Thread_map = Memprof_limits.Thread_map *)(* module Mutex_aux = Memprof_limits.Mutex_aux *)(* We do our own Mutex_aux for OCaml 5.x *)moduleMutex_aux=Mutex_auxmoduleThread_map_core=structopenResource_bindmoduleIMap=Map.Make(structtypet=intletcompare=Stdlib.compareend)type'at={mutex:Mutex.t;mutablemap:'aIMap.t}letcreate()={mutex=Mutex.create();map=IMap.empty}letcurrent_thread()=Thread.id(Thread.self())letgets=(* Concurrent threads do not alter the value for the current
thread, so we do not need a lock. *)IMap.find_opt(current_thread())s.map(* For set and clear we need a lock *)letsetsv=let&()=Mutex_aux.with_locks.mutexinletnew_map=matchvwith|None->IMap.remove(current_thread())s.map|Somev->IMap.add(current_thread())vs.mapins.map<-new_maplet_clears=let&()=Mutex_aux.with_locks.mutexins.map<-IMap.emptyendmoduleMasking=Memprof_limits.MaskingmoduleThread_map=structincludeThread_map_coreletwith_valuetls~value~scope=letold_value=gettlsin(* FIXME: needs proper masking here as there is a race between
resources and asynchronous exceptions. For now, it is
exception-safe only for exceptions arising from Memprof_callbacks. *)Masking.with_resource~acquire:(fun()->settls(Somevalue))()~scope~release:(fun()->settlsold_value)end