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