123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2025 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)let()=Plugin.is_share_visible()moduleMThread=Plugin.Register(structletname="mthread"letshortname="mt"lethelp="Experimental tools for multi-threaded programs"end);;(* Including this module directly is a bad idea, as this hides the
"String" module of the standard library... *)(* Reexport useful values *)include(MThread:Log.Messages)letdebug_level()=MThread.Debug.get()openMThreadletgrp_models=add_group"Extraction of models"letgrp_debug=add_group"Debug"letgrp_cfg=add_group"Multithreaded control-flow-graph"(*let grp_misc = add_group "Misc"*)letgrp_analysis=add_group"Analysis"moduleEnabled=False(structletoption_name="-mthread"lethelp="enable analysis of multi-threaded programs through the Mthread plugin"end);;let()=Parameter_customize.set_groupgrp_debugmoduleKeepProjects=String(structletoption_name="-mt-keep-analyses"lethelp="keep a copy of the analyses done for each thread"letdefault="last"letarg_name="all|last|none"end);;let()=KeepProjects.set_possible_values["all";"last";"none"]let()=Parameter_customize.set_groupgrp_debuglet()=Parameter_customize.set_negative_option_name"-mt-projects-together"moduleToDisk=False(structletoption_name="-mt-projects-on-disk"lethelp="Save the copies of the analyses in a separate file, instead of all together"end);;let()=Parameter_customize.set_groupgrp_debuglet()=Parameter_customize.set_negative_option_name"-mt-consider-null"moduleIgnoreNull=False(structletoption_name="-mt-ignore-null"lethelp="Ignore shared accesses to numeric memory (NULL base)"end);;let()=Parameter_customize.set_groupgrp_debugmoduleToDiskPrefix=String(structletoption_name="-mt-projects-on-disk-prefix"letarg_name="prefix"letdefault="th"lethelp="Prepend <prefix> to the project's filename saved by -mt-projects-on-disk (defaults to th)"end)let()=Parameter_customize.set_groupgrp_analysismoduleWriteWriteRaces=False(structletoption_name="-mt-write-races"lethelp="Display memory on which there is a write-only race condition"end)let()=Parameter_customize.set_groupgrp_analysismoduleDumpSharedVarsValues=Int(structletdefault=0letoption_name="-mt-shared-values"lethelp="Show what threads read and write in shared memory at the end of each iteration\n\
0: values not shown\n\
1: values shown\n\
2: values shown with the stack at which the operation occurs"letarg_name="level"end)let()=DumpSharedVarsValues.set_range~min:0~max:2let()=Parameter_customize.set_groupgrp_analysismoduleCheckProtections=False(structlethelp="more precise inference of which mutexes protect shared memory"letoption_name="-mt-shared-accesses-synchronization"end)let()=Parameter_customize.set_groupgrp_analysismoduleInterruptHandlers=Kernel_function_set(structletoption_name="-mt-interrupt-handlers"letarg_name="functions"lethelp="Specify functions that will be treated as handlers for \
interrupts."end)let()=Parameter_customize.set_groupmessagesmoduleModerateWarnings=True(structletoption_name="-mt-moderate-warnings"lethelp="Show semi-important warnings during analysis."end)let()=Parameter_customize.set_groupmessagesmodulePrintCallstacks=False(structletoption_name="-mt-print-callstacks"lethelp="Print the callstacks at which concurrent events occur"end)let()=Parameter_customize.set_groupgrp_debugmoduleShowTime=False(structletoption_name="-mt-time"lethelp="Show time taken by thread computation"end);;let()=Parameter_customize.set_groupgrp_debugmoduleSkipThreads=String_set(structletoption_name="-mt-skip-threads"letarg_name="th1,...,thn"lethelp="do not execute the specified threads"end);;let()=Parameter_customize.set_groupgrp_debugmoduleOnlyThreads=String_set(structletoption_name="-mt-only-threads"letarg_name="th1,...,thn"lethelp="only execute the specified threads"end);;let()=Parameter_customize.set_groupgrp_debugmoduleStopAfter=Int(structletdefault=max_intletoption_name="-mt-stop-after"lethelp="Only perform at most i iterations"letarg_name="i"end);;let()=Parameter_customize.set_groupgrp_debugmoduleConcatDotFilesTo=Filepath(structletoption_name="-mt-concat-dot-files-to"letarg_name="filename"letexistence=Fc_Filepath.Indifferentletfile_kind="dot"lethelp="Concatenate dot files generated by the html output into a \
single file."end)let()=Parameter_customize.set_groupgrp_modelsmoduleExtractModels=String_set(structletoption_name="-mt-extract"letarg_name="[html]"lethelp="extraction of models"end);;let()=Parameter_customize.set_groupgrp_cfgmoduleFullCfg=False(structletoption_name="-mt-full-cfg"lethelp="Do not simplify cfg and show all statements (can be costly)"end);;let()=Parameter_customize.set_groupgrp_cfgmoduleKeepWhiteNodes=False(structletoption_name="-mt-non-shared-accesses"lethelp="Keep accesses to false shared variables in the cfg"end);;let()=Parameter_customize.set_groupgrp_cfgmoduleKeepGreenNodes=True(structletoption_name="-mt-non-concurrent-accesses"lethelp="Keep non-concurrent accesses to shared variables in the cfg"end);;let()=Parameter_customize.set_groupgrp_cfgmoduleShowReturnEdges=True(structletoption_name="-mt-return-edges"lethelp="Show link between a call an a return instruction as a dotted line"end);;let()=Parameter_customize.set_groupgrp_cfgmodulePopTopFunctionForCallbacks=False(structletoption_name="-mt-inline-callbacks"lethelp="Do not show the names of concurrent primitives, only their effect"end);;