Arcane  4.2.3.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/IStackTraceService.h"
20#include "arccore/base/internal/DependencyInjection.h"
21
22#include "arccore/trace/ITraceMng.h"
23
24#include "arccore/concurrency/ITaskImplementation.h"
25#include "arccore/concurrency/IThreadImplementation.h"
26#include "arccore/concurrency/IThreadImplementationService.h"
27#include "arccore/concurrency/TaskFactory.h"
28#include "arccore/concurrency/internal/TaskFactoryInternal.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
46template <typename InterfaceType> Ref<InterfaceType> ConcurrencyApplication::
47tryCreateServiceUsingInjector(ConstArrayView<String> names, String* found_name, bool has_trace)
48{
49 DependencyInjection::Injector injector;
50 injector.fillWithGlobalFactories();
51 // Adds an instance of ITraceMng* for services that need it
52 if (has_trace)
53 injector.bind(m_trace.get());
54
55 if (found_name)
56 (*found_name) = String();
57 for (String s : names) {
58 auto t = injector.createInstance<InterfaceType>(s, true);
59 if (t.get()) {
60 if (found_name)
61 (*found_name) = s;
62 return t;
63 }
64 }
65 return {};
66}
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70
71void ConcurrencyApplication::
72setCoreServices(const ConcurrencyApplicationBuildInfo& build_info)
73{
74 // Searches for the service used to know the call stack
75 bool has_dbghelp = false;
76 {
77 String dbghelp_service_name = "DbgHelpStackTraceService";
79 String found_name;
81 const auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_USE_BACKWARDCPP", true);
82 if (v && v.value() != 0) {
83 names.add("BackwardCppStackTraceService");
84 }
85 names.add("LibUnwind");
86 names.add("DbgHelpStackTraceService");
87 sv = tryCreateServiceUsingInjector<IStackTraceService>(names.constView(), &found_name, true);
88 if (found_name == dbghelp_service_name)
89 has_dbghelp = true;
90 if (sv.get()) {
91 sv->build();
92 m_stack_trace_service = sv;
94 }
95 }
96
97 // Searches for the service used to know the symbol information
98 // of the source code. For now, only LLVM is supported and this service
99 // is activated
100 // if the environment variable ARCANE_LLVMSYMBOLIZER_PATH is defined.
101 {
102 Impl::CoreArray<String> names;
103 String found_name;
104 Ref<ISymbolizerService> sv;
105
106 if (!platform::getEnvironmentVariable("ARCANE_LLVMSYMBOLIZER_PATH").null())
107 names.add("LLVMSymbolizer");
108 if (has_dbghelp)
109 names.add("DbgHelpSymbolizerService");
110 sv = tryCreateServiceUsingInjector<ISymbolizerService>(names.constView(), &found_name, true);
111 if (sv.get()) {
112 m_symbolizer_service = sv;
114 }
115 }
116
117 // Searches for the service implementing multi-threading support.
118 {
119 ConstArrayView<String> names = build_info.threadImplementationServices();
120 String found_name;
121 auto sv = tryCreateServiceUsingInjector<IThreadImplementationService>(names, &found_name, false);
122 if (!sv.get())
123 ARCCORE_FATAL("Can not find implementation for 'IThreadImplementation' (names='{0}').", names);
124 m_thread_implementation_service = sv;
125 m_thread_implementation = sv->createImplementation();
126 Arccore::Concurrency::setThreadImplementation(m_thread_implementation.get());
127 m_thread_implementation->initialize();
128 m_used_thread_service_name = found_name;
129 }
130
131 // The thread manager may have changed and therefore
132 // the trace manager must be reinitialized.
133 m_trace->resetThreadStatus();
134
135 // Searches for the service used to manage tasks
136 {
137 Integer nb_task_thread = build_info.nbTaskThread();
138 if (nb_task_thread >= 0) {
139
140 ConstArrayView<String> names = build_info.taskImplementationServices();
141 String found_name;
142 auto sv = tryCreateServiceUsingInjector<ITaskImplementation>(names, &found_name, false);
143 if (sv.get()) {
144 TaskFactoryInternal::setImplementation(sv.get());
145 sv->initialize(nb_task_thread);
146 m_used_task_service_name = found_name;
147 m_task_implementation = sv;
148 }
149 else
150 ARCCORE_FATAL("Can not find task implementation service (names='{0}')."
151 " Please check if Arcane is configured with Intel TBB library",
152 names);
153 }
154
155 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_TASK_VERBOSE_LEVEL", true))
157 }
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
163} // namespace Arcane
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
#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.