Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ConcurrencyApplication.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ConcurrencyApplication.h (C) 2000-2026 */
9/* */
10/* Management of multi-threading services for an Arccore application. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/concurrency/internal/ConcurrencyApplication.h"
15
16#include "arccore/base/CheckedConvert.h"
17#include "arccore/base/PlatformUtils.h"
18#include "arccore/base/FatalErrorException.h"
19#include "arccore/base/internal/DependencyInjection.h"
20
21#include "arccore/trace/ITraceMng.h"
22
23#include "arccore/concurrency/ITaskImplementation.h"
24#include "arccore/concurrency/IThreadImplementation.h"
25#include "arccore/concurrency/IThreadImplementationService.h"
26#include "arccore/concurrency/TaskFactory.h"
27#include "arccore/concurrency/internal/TaskFactoryInternal.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
45template <typename InterfaceType> Ref<InterfaceType> ConcurrencyApplication::
46tryCreateServiceUsingInjector(ConstArrayView<String> names, String* found_name, bool has_trace)
47{
48 DependencyInjection::Injector injector;
49 injector.fillWithGlobalFactories();
50 // Adds an instance of ITraceMng* for services that need it
51 if (has_trace)
52 injector.bind(m_trace.get());
53
54 if (found_name)
55 (*found_name) = String();
56 for (String s : names) {
57 auto t = injector.createInstance<InterfaceType>(s, true);
58 if (t.get()) {
59 if (found_name)
60 (*found_name) = s;
61 return t;
62 }
63 }
64 return {};
65}
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
70void ConcurrencyApplication::
71setCoreServices(const ConcurrencyApplicationBuildInfo& build_info)
72{
73 // Searches for the service used to know the call stack
74 bool has_dbghelp = false;
75 {
76 String dbghelp_service_name = "DbgHelpStackTraceService";
78 String found_name;
80 const auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_USE_BACKWARDCPP", true);
81 if (v && v.value() != 0) {
82 names.add("BackwardCppStackTraceService");
83 }
84 names.add("LibUnwind");
85 names.add("DbgHelpStackTraceService");
86 sv = tryCreateServiceUsingInjector<IStackTraceService>(names.constView(), &found_name, true);
87 if (found_name == dbghelp_service_name)
88 has_dbghelp = true;
89 if (sv.get()) {
90 m_stack_trace_service = sv;
92 }
93 }
94
95 // Searches for the service used to know the symbol information
96 // of the source code. For now, only LLVM is supported and this service
97 // is activated
98 // if the environment variable ARCANE_LLVMSYMBOLIZER_PATH is defined.
99 {
100 Impl::CoreArray<String> names;
101 String found_name;
102 Ref<ISymbolizerService> sv;
103
104 if (!platform::getEnvironmentVariable("ARCANE_LLVMSYMBOLIZER_PATH").null())
105 names.add("LLVMSymbolizer");
106 if (has_dbghelp)
107 names.add("DbgHelpSymbolizerService");
108 sv = tryCreateServiceUsingInjector<ISymbolizerService>(names.constView(), &found_name, true);
109 if (sv.get()) {
110 m_symbolizer_service = sv;
112 }
113 }
114
115 // Searches for the service implementing multi-threading support.
116 {
117 ConstArrayView<String> names = build_info.threadImplementationServices();
118 String found_name;
119 auto sv = tryCreateServiceUsingInjector<IThreadImplementationService>(names, &found_name, false);
120 if (!sv.get())
121 ARCCORE_FATAL("Can not find implementation for 'IThreadImplementation' (names='{0}').", names);
122 m_thread_implementation_service = sv;
123 m_thread_implementation = sv->createImplementation();
124 Arccore::Concurrency::setThreadImplementation(m_thread_implementation.get());
125 m_thread_implementation->initialize();
126 m_used_thread_service_name = found_name;
127 }
128
129 // The thread manager may have changed and therefore
130 // the trace manager must be reinitialized.
131 m_trace->resetThreadStatus();
132
133 // Searches for the service used to manage tasks
134 {
135 Integer nb_task_thread = build_info.nbTaskThread();
136 if (nb_task_thread >= 0) {
137
138 ConstArrayView<String> names = build_info.taskImplementationServices();
139 String found_name;
140 auto sv = tryCreateServiceUsingInjector<ITaskImplementation>(names, &found_name, false);
141 if (sv.get()) {
142 TaskFactoryInternal::setImplementation(sv.get());
143 sv->initialize(nb_task_thread);
144 m_used_task_service_name = found_name;
145 m_task_implementation = sv;
146 }
147 else
148 ARCCORE_FATAL("Can not find task implementation service (names='{0}')."
149 " Please check if Arcane is configured with Intel TBB library",
150 names);
151 }
152
153 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_TASK_VERBOSE_LEVEL", true))
155 }
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
160
161} // namespace Arcane
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
Ref< InterfaceType > tryCreateServiceUsingInjector(ConstArrayView< String > names, String *found_name, bool has_trace)
String m_used_task_service_name
Name of the service used to manage tasks.
ReferenceCounter< ITraceMng > m_trace
Trace manager.
String m_used_thread_service_name
Name of the service used to manage threads.
Constant view of an array of type T.
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Template class for converting a type.
ConstArrayView< DataType > constView() const
Constant view.
InstanceType * get() const
Associated instance or nullptr if none.
Reference to an instance.
static void setVerboseLevel(Integer v)
Sets the verbosity level (0 for no output, which is the default).
IStackTraceService * setStackTraceService(IStackTraceService *service)
Sets the service used to obtain the call stack.
ISymbolizerService * setSymbolizerService(ISymbolizerService *service)
Sets the service to obtain information about source code symbols.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.