1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465(* SPDX-License-Identifier: MIT *)(* Copyright (C) 2023-2024 formalsec *)(* Written by the Smtml programmers *)letrun_and_time_call~usef=letstart=Unix.gettimeofday()inletresult=f()inletstop=Unix.gettimeofday()inuse(stop-.start);resultletquery_log_path:Fpath.toption=letenv_var="QUERY_LOG_PATH"inmatchBos.OS.Env.varenv_varwithSomep->Some(Fpath.vp)|None->Nonelet[@inlinenever]protectmf=Mutex.lockm;matchf()with|x->Mutex.unlockm;x|exceptione->Mutex.unlockm;letbt=Printexc.get_raw_backtrace()inPrintexc.raise_with_backtraceebt(* If the environment variable [QUERY_LOG_PATH] is set, stores and writes
all queries sent to the solver (with their timestamps) to the given file *)letwrite=matchquery_log_pathwith|None->fun~model:____->()|Somepath->letlog_entries:(string*Expr.tlist*bool*int64)listref=ref[]inletclose()=ifList.compare_length_with!log_entries0<>0thentryletoc=(* open with wr/r/r rights, create if it does not exit and append to
it if it exists. *)Out_channel.open_gen[Open_creat;Open_binary;Open_append]0o644(Fpath.to_stringpath)inMarshal.to_channeloc!log_entries[];Out_channel.closeocwithe->Fmt.failwith"Failed to write log: %s@."(Printexc.to_stringe)inat_exitclose;Sys.set_signalSys.sigterm(Sys.Signal_handle(fun_->close()));(* write *)letmutex=Mutex.create()infun~modelsolver_nameassumptionstime->letentry=(solver_name,assumptions,model,time)inprotectmutex(fun()->log_entries:=entry::!log_entries)letrun_and_log_query~modelfnameassumptions=matchquery_log_pathwith|Some_->letcounter=Mtime_clock.counter()inletres=f()inwrite~modelnameassumptions(Mtime.Span.to_uint64_ns(Mtime_clock.countcounter));res|None->f()