1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// ------------------------------------------------------------------------
//
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (C) 2000 - 2025 by the deal.II authors
//
// This file is part of the deal.II library.
//
// Part of the source code is dual licensed under Apache-2.0 WITH
// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
// governing the source code and code contributions can be found in
// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
//
// ------------------------------------------------------------------------
#include <deal.II/base/mutex.h>
#include <deal.II/base/thread_management.h>
#include <atomic>
#include <cstdlib>
#include <iostream>
#ifdef DEAL_II_HAVE_UNISTD_H
# include <unistd.h>
#endif
DEAL_II_NAMESPACE_OPEN
namespace Threads
{
namespace internal
{
[[noreturn]] void
handle_std_exception(const std::exception &exc)
{
// lock the following context
// to ensure that we don't
// print things over each other
// if we have trouble from
// multiple threads. release
// the lock before calling
// std::abort, though
static Mutex mutex;
{
std::lock_guard<std::mutex> lock(mutex);
std::cerr
<< std::endl
<< std::endl
<< "---------------------------------------------------------"
<< std::endl
<< "In one of the sub-threads of this program, an exception\n"
<< "was thrown and not caught. Since exceptions do not\n"
<< "propagate to the main thread, the library has caught it.\n"
<< "The information carried by this exception is given below.\n"
<< std::endl
<< "---------------------------------------------------------"
<< std::endl;
std::cerr << "Exception message: " << std::endl
<< " " << exc.what() << std::endl
<< "Exception type: " << std::endl
<< " " << typeid(exc).name() << std::endl;
std::cerr << "Aborting!" << std::endl
<< "---------------------------------------------------------"
<< std::endl;
}
std::abort();
}
[[noreturn]] void
handle_unknown_exception()
{
// lock the following context
// to ensure that we don't
// print things over each other
// if we have trouble from
// multiple threads. release
// the lock before calling
// std::abort, though
static Mutex mutex;
{
std::lock_guard<std::mutex> lock(mutex);
std::cerr
<< std::endl
<< std::endl
<< "---------------------------------------------------------"
<< std::endl
<< "In one of the sub-threads of this program, an exception\n"
<< "was thrown and not caught. Since exceptions do not\n"
<< "propagate to the main thread, the library has caught it.\n"
<< std::endl
<< "---------------------------------------------------------"
<< std::endl;
std::cerr << "Type of exception is unknown, but not std::exception.\n"
<< "No additional information is available.\n"
<< "---------------------------------------------------------"
<< std::endl;
}
std::abort();
}
} // namespace internal
std::vector<std::pair<unsigned int, unsigned int>>
split_interval(const unsigned int begin,
const unsigned int end,
const unsigned int n_intervals)
{
Assert(end >= begin, ExcInternalError());
const unsigned int n_elements = end - begin;
const unsigned int n_elements_per_interval = n_elements / n_intervals;
const unsigned int residual = n_elements % n_intervals;
std::vector<std::pair<unsigned int, unsigned int>> return_values(
n_intervals);
return_values[0].first = begin;
for (unsigned int i = 0; i < n_intervals; ++i)
{
if (i != n_intervals - 1)
{
return_values[i].second =
(return_values[i].first + n_elements_per_interval);
// distribute residual in
// division equally among
// the first few
// subintervals
if (i < residual)
++return_values[i].second;
return_values[i + 1].first = return_values[i].second;
}
else
return_values[i].second = end;
}
return return_values;
}
} // namespace Threads
DEAL_II_NAMESPACE_CLOSE
|