1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586typet={mutablelocked:bool;mutablefailed:bool;mutablestopped:bool;report_exn:exn->unit;trace:Trace.Writer.t}let[@inlinenever]lock_tracers=(* This is a maximally unfair spinlock. *)(* if s.locked then Printf.fprintf stderr "contention\n%!"; *)whiles.lockeddoThread.yield()done;ifs.failedthenfalseelse(s.locked<-true;true)let[@inlinenever]unlock_tracers=assert(s.locked&¬s.failed);s.locked<-falselet[@inlinenever]mark_failedse=assert(s.locked&¬s.failed);s.failed<-true;s.locked<-false;s.report_exneletdefault_report_exne=letmsg=Printf.sprintf"Memtrace failure: %s\n"(Printexc.to_stringe)inoutput_stringstderrmsg;Printexc.print_backtracestderr;flushstderrletstart?(report_exn=default_report_exn)~sampling_ratetrace=lets={trace;locked=false;stopped=false;failed=false;report_exn}inlettracker:(_,_)Gc.Memprof.tracker={alloc_minor=(funinfo->iflock_tracersthenbeginmatchTrace.Writer.put_alloc_with_raw_backtracetrace(Trace.Timestamp.now())~length:info.size~nsamples:info.n_samples~is_major:false~callstack:info.callstackwith|r->unlock_tracers;Somer|exceptione->mark_failedse;NoneendelseNone);alloc_major=(funinfo->iflock_tracersthenbeginmatchTrace.Writer.put_alloc_with_raw_backtracetrace(Trace.Timestamp.now())~length:info.size~nsamples:info.n_samples~is_major:true~callstack:info.callstackwith|r->unlock_tracers;Somer|exceptione->mark_failedse;NoneendelseNone);promote=(funid->iflock_tracersthenmatchTrace.Writer.put_promotetrace(Trace.Timestamp.now())idwith|()->unlock_tracers;Someid|exceptione->mark_failedse;NoneelseNone);dealloc_minor=(funid->iflock_tracersthenmatchTrace.Writer.put_collecttrace(Trace.Timestamp.now())idwith|()->unlock_tracers|exceptione->mark_failedse);dealloc_major=(funid->iflock_tracersthenmatchTrace.Writer.put_collecttrace(Trace.Timestamp.now())idwith|()->unlock_tracers|exceptione->mark_failedse)}inGc.Memprof.start~sampling_rate~callstack_size:max_inttracker;sletstops=ifnots.stoppedthenbegins.stopped<-true;Gc.Memprof.stop();iflock_tracersthenTrace.Writer.closes.traceend