Blender
V4.3
source
blender
blenlib
BLI_enumerable_thread_specific.hh
Go to the documentation of this file.
1
/* SPDX-FileCopyrightText: 2023 Blender Authors
2
*
3
* SPDX-License-Identifier: GPL-2.0-or-later */
4
5
#pragma once
6
7
#ifdef WITH_TBB
8
/* Quiet top level deprecation message, unrelated to API usage here. */
9
# if defined(WIN32) && !defined(NOMINMAX)
10
/* TBB includes Windows.h which will define min/max macros causing issues
11
* when we try to use std::min and std::max later on. */
12
# define NOMINMAX
13
# define TBB_MIN_MAX_CLEANUP
14
# endif
15
# include <tbb/enumerable_thread_specific.h>
16
# ifdef WIN32
17
/* We cannot keep this defined, since other parts of the code deal with this on their own, leading
18
* to multiple define warnings unless we un-define this, however we can only undefine this if we
19
* were the ones that made the definition earlier. */
20
# ifdef TBB_MIN_MAX_CLEANUP
21
# undef NOMINMAX
22
# endif
23
# endif
24
#else
25
# include <atomic>
26
# include <functional>
27
# include <mutex>
28
29
# include "
BLI_map.hh
"
30
#endif
31
32
#include "
BLI_utility_mixins.hh
"
33
34
namespace
blender::threading
{
35
36
#ifndef WITH_TBB
37
namespace
enumerable_thread_specific_utils {
38
inline
std::atomic<int>
next_id
= 0;
39
inline
thread_local
int
thread_id
=
next_id
.fetch_add(1, std::memory_order_relaxed);
40
}
// namespace enumerable_thread_specific_utils
41
#endif
/* !WITH_TBB */
42
49
template
<
typename
T>
class
EnumerableThreadSpecific
:
NonCopyable
,
NonMovable
{
50
#ifdef WITH_TBB
51
52
private
:
53
tbb::enumerable_thread_specific<T> values_;
54
55
public
:
56
using
iterator
=
typename
tbb::enumerable_thread_specific<T>::iterator;
57
58
EnumerableThreadSpecific
() =
default
;
59
60
template
<
typename
F>
EnumerableThreadSpecific
(F initializer) : values_(std::move(initializer)) {}
61
62
T &
local
()
63
{
64
return
values_.local();
65
}
66
67
iterator
begin
()
68
{
69
return
values_.begin();
70
}
71
72
iterator
end
()
73
{
74
return
values_.end();
75
}
76
77
#else
/* WITH_TBB */
78
79
private
:
80
std::mutex mutex_;
81
/* Maps thread ids to their corresponding values. The values are not embedded in the map, so that
82
* their addresses do not change when the map grows. */
83
Map<int, std::reference_wrapper<T>
> values_;
84
Vector<std::unique_ptr<T>
> owned_values_;
85
std::function<void(
void
*)> initializer_;
86
87
public
:
88
using
iterator
=
typename
Map<int, std::reference_wrapper<T>
>::MutableValueIterator;
89
90
EnumerableThreadSpecific
() : initializer_([](void *buffer) {
new
(buffer)
T
(); }) {}
91
92
template
<
typename
F>
93
EnumerableThreadSpecific
(F initializer)
94
: initializer_([=](void *buffer) {
new
(buffer)
T
(initializer()); })
95
{
96
}
97
98
T &
local
()
99
{
100
const
int
thread_id =
enumerable_thread_specific_utils::thread_id
;
101
std::lock_guard
lock
{mutex_};
102
return
values_.lookup_or_add_cb(thread_id, [&]() {
103
T *value = (T *)::operator
new
(
sizeof
(T));
104
initializer_(value);
105
owned_values_.
append
(std::unique_ptr<T>{value});
106
return
std::reference_wrapper<T>{*value};
107
});
108
}
109
110
iterator
begin
()
111
{
112
return
values_.values().begin();
113
}
114
115
iterator
end
()
116
{
117
return
values_.values().end();
118
}
119
120
#endif
/* WITH_TBB */
121
};
122
123
}
// namespace blender::threading
BLI_map.hh
BLI_utility_mixins.hh
lock
volatile int lock
Definition
atomic_ops_unix.h:0
blender::Map
Definition
BLI_map.hh:129
blender::NonCopyable
Definition
BLI_utility_mixins.hh:16
blender::NonMovable
Definition
BLI_utility_mixins.hh:31
blender::Vector
Definition
BLI_vector.hh:65
blender::Vector::append
void append(const T &value)
Definition
BLI_vector.hh:430
blender::threading::EnumerableThreadSpecific
Definition
BLI_enumerable_thread_specific.hh:49
blender::threading::EnumerableThreadSpecific::iterator
typename Map< int, std::reference_wrapper< T > >::MutableValueIterator iterator
Definition
BLI_enumerable_thread_specific.hh:88
blender::threading::EnumerableThreadSpecific::EnumerableThreadSpecific
EnumerableThreadSpecific()
Definition
BLI_enumerable_thread_specific.hh:90
blender::threading::EnumerableThreadSpecific::end
iterator end()
Definition
BLI_enumerable_thread_specific.hh:115
blender::threading::EnumerableThreadSpecific::begin
iterator begin()
Definition
BLI_enumerable_thread_specific.hh:110
blender::threading::EnumerableThreadSpecific::local
T & local()
Definition
BLI_enumerable_thread_specific.hh:98
blender::threading::EnumerableThreadSpecific::EnumerableThreadSpecific
EnumerableThreadSpecific(F initializer)
Definition
BLI_enumerable_thread_specific.hh:93
T
#define T
Definition
mball_tessellate.cc:273
blender::threading::enumerable_thread_specific_utils::thread_id
thread_local int thread_id
Definition
BLI_enumerable_thread_specific.hh:39
blender::threading::enumerable_thread_specific_utils::next_id
std::atomic< int > next_id
Definition
BLI_enumerable_thread_specific.hh:38
blender::threading
Definition
BLI_enumerable_thread_specific.hh:34
Generated on Thu Feb 6 2025 07:36:39 for Blender by
doxygen
1.11.0