Reference documentation for deal.II version 9.2.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
thread_management.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
17 
18 #include <atomic>
19 #include <cstdlib>
20 #include <iostream>
21 
22 #ifdef DEAL_II_HAVE_UNISTD_H
23 # include <unistd.h>
24 #endif
25 
26 
28 
29 
30 namespace Threads
31 {
32  namespace internal
33  {
34  static std::atomic<unsigned int> n_existing_threads_counter(1);
35 
36 
37  void
39  {
41  }
42 
43 
44 
45  void
47  {
50  }
51 
52 
53 
54  [[noreturn]] void
55  handle_std_exception(const std::exception &exc) {
56  // lock the following context
57  // to ensure that we don't
58  // print things over each other
59  // if we have trouble from
60  // multiple threads. release
61  // the lock before calling
62  // std::abort, though
63  static Mutex mutex;
64  {
65  Mutex::ScopedLock lock(mutex);
66 
67  std::cerr
68  << std::endl
69  << std::endl
70  << "---------------------------------------------------------"
71  << std::endl
72  << "In one of the sub-threads of this program, an exception\n"
73  << "was thrown and not caught. Since exceptions do not\n"
74  << "propagate to the main thread, the library has caught it.\n"
75  << "The information carried by this exception is given below.\n"
76  << std::endl
77  << "---------------------------------------------------------"
78  << std::endl;
79  std::cerr << "Exception message: " << std::endl
80  << " " << exc.what() << std::endl
81  << "Exception type: " << std::endl
82  << " " << typeid(exc).name() << std::endl;
83  std::cerr << "Aborting!" << std::endl
84  << "---------------------------------------------------------"
85  << std::endl;
86  }
87 
88  std::abort();
89  }
90 
91 
92 
93  [[noreturn]] void handle_unknown_exception()
94  {
95  // lock the following context
96  // to ensure that we don't
97  // print things over each other
98  // if we have trouble from
99  // multiple threads. release
100  // the lock before calling
101  // std::abort, though
102  static Mutex mutex;
103  {
104  Mutex::ScopedLock lock(mutex);
105 
106  std::cerr
107  << std::endl
108  << std::endl
109  << "---------------------------------------------------------"
110  << std::endl
111  << "In one of the sub-threads of this program, an exception\n"
112  << "was thrown and not caught. Since exceptions do not\n"
113  << "propagate to the main thread, the library has caught it.\n"
114  << std::endl
115  << "---------------------------------------------------------"
116  << std::endl;
117  std::cerr << "Type of exception is unknown, but not std::exception.\n"
118  << "No additional information is available.\n"
119  << "---------------------------------------------------------"
120  << std::endl;
121  }
122  std::abort();
123  }
124  } // namespace internal
125 
126 
127 
128  unsigned int
130  {
132  }
133 
134 
135  unsigned int
137  {
138 #ifdef SYS_gettid
139  const pid_t this_id = syscall(SYS_gettid);
140 #elif defined(DEAL_II_HAVE_UNISTD_H) && defined(DEAL_II_HAVE_GETPID)
141  const pid_t this_id = getpid();
142 #else
143  const unsigned int this_id = 0;
144 #endif
145 
146  return static_cast<unsigned int>(this_id);
147  }
148 
149 
150 
151 #ifdef DEAL_II_USE_MT_POSIX
152 
153 
154 # ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
155  PosixThreadBarrier::PosixThreadBarrier(const unsigned int count,
156  const char *,
157  void *)
158  {
159  pthread_barrier_init(&barrier, nullptr, count);
160  }
161 
162 # else
163 
164  PosixThreadBarrier::PosixThreadBarrier(const unsigned int count,
165  const char *,
166  void *)
167  : count(count)
168  {
169  // throw an exception unless we
170  // have the special case that a
171  // count of 1 is given, since
172  // then waiting for a barrier is
173  // a no-op, and we don't need the
174  // POSIX functionality
175  AssertThrow(count == 1,
176  ExcMessage("Your local POSIX installation does not support\n"
177  "POSIX barriers. You will not be able to use\n"
178  "this class, but the rest of the threading\n"
179  "functionality is available."));
180  }
181 # endif
182 
183 
184 
186  {
187 # ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
188  pthread_barrier_destroy(&barrier);
189 # else
190  // unless the barrier is a no-op,
191  // complain again (how did we get
192  // here then?)
193  if (count != 1)
194  std::abort();
195 # endif
196  }
197 
198 
199 
200  int
202  {
203 # ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
204  return pthread_barrier_wait(&barrier);
205 # else
206  // in the special case, this
207  // function is a no-op. otherwise
208  // complain about the missing
209  // POSIX functions
210  if (count == 1)
211  return 0;
212  else
213  {
214  std::abort();
215  return 1;
216  }
217 # endif
218  }
219 
220 
221 
222 #endif
223 
224 
225 
226  std::vector<std::pair<unsigned int, unsigned int>>
227  split_interval(const unsigned int begin,
228  const unsigned int end,
229  const unsigned int n_intervals)
230  {
232 
233  const unsigned int n_elements = end - begin;
234  const unsigned int n_elements_per_interval = n_elements / n_intervals;
235  const unsigned int residual = n_elements % n_intervals;
236 
237  std::vector<std::pair<unsigned int, unsigned int>> return_values(
238  n_intervals);
239 
240  return_values[0].first = begin;
241  for (unsigned int i = 0; i < n_intervals; ++i)
242  {
243  if (i != n_intervals - 1)
244  {
245  return_values[i].second =
246  (return_values[i].first + n_elements_per_interval);
247  // distribute residual in
248  // division equally among
249  // the first few
250  // subintervals
251  if (i < residual)
252  ++return_values[i].second;
253  return_values[i + 1].first = return_values[i].second;
254  }
255  else
256  return_values[i].second = end;
257  }
258  return return_values;
259  }
260 } // namespace Threads
261 
262 
Threads::this_thread_id
unsigned int this_thread_id()
Definition: thread_management.cc:136
Threads::internal::register_thread
void register_thread()
Definition: thread_management.cc:38
Threads::Mutex
Definition: thread_management.h:91
Threads::internal::handle_unknown_exception
void handle_unknown_exception()
Definition: thread_management.cc:93
Threads::PosixThreadBarrier::wait
int wait()
Definition: thread_management.cc:201
thread_management.h
Threads::split_interval
std::vector< std::pair< unsigned int, unsigned int > > split_interval(const unsigned int begin, const unsigned int end, const unsigned int n_intervals)
Definition: thread_management.cc:227
deal_II_exceptions::internals::abort
void abort(const ExceptionBase &exc) noexcept
Definition: exceptions.cc:408
Threads::Mutex::ScopedLock
std::lock_guard< std::mutex > ScopedLock
Definition: thread_management.h:114
StandardExceptions::ExcMessage
static ::ExceptionBase & ExcMessage(std::string arg1)
TrilinosWrappers::internal::begin
VectorType::value_type * begin(VectorType &V)
Definition: trilinos_sparse_matrix.cc:51
DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
TrilinosWrappers::internal::end
VectorType::value_type * end(VectorType &V)
Definition: trilinos_sparse_matrix.cc:65
Threads::internal::n_existing_threads_counter
static std::atomic< unsigned int > n_existing_threads_counter(1)
Threads::n_existing_threads
unsigned int n_existing_threads()
Definition: thread_management.cc:129
Threads::internal::handle_std_exception
void handle_std_exception(const std::exception &exc)
Definition: thread_management.cc:55
Threads::PosixThreadBarrier::~PosixThreadBarrier
~PosixThreadBarrier()
Definition: thread_management.cc:185
StandardExceptions::ExcInternalError
static ::ExceptionBase & ExcInternalError()
Assert
#define Assert(cond, exc)
Definition: exceptions.h:1419
Threads::PosixThreadBarrier::barrier
pthread_barrier_t barrier
Definition: thread_management.h:272
Threads::PosixThreadBarrier::PosixThreadBarrier
PosixThreadBarrier(const unsigned int count, const char *name=nullptr, void *arg=nullptr)
Definition: thread_management.cc:155
internal
Definition: aligned_vector.h:369
DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
Threads::internal::deregister_thread
void deregister_thread()
Definition: thread_management.cc:46
Threads
Definition: thread_local_storage.h:36
AssertThrow
#define AssertThrow(cond, exc)
Definition: exceptions.h:1531