Blender  V3.3
BLI_index_range.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <mutex>
4 
5 #include "BLI_array.hh"
6 #include "BLI_index_range.hh"
7 #include "BLI_span.hh"
8 #include "BLI_task.hh"
9 #include "BLI_vector.hh"
10 
11 namespace blender {
12 
15 std::atomic<int64_t> IndexRange::s_current_array_size = 0;
16 std::atomic<int64_t *> IndexRange::s_current_array = nullptr;
17 
18 Span<int64_t> IndexRange::as_span_internal() const
19 {
20  int64_t min_required_size = start_ + size_;
21 
22  std::lock_guard<std::mutex> lock(current_array_mutex);
23 
24  /* Double checked lock. */
25  if (min_required_size <= s_current_array_size) {
26  return Span<int64_t>(s_current_array + start_, size_);
27  }
28 
29  /* Isolate, because a mutex is locked. */
31  int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size));
32  RawArray<int64_t, 0> new_array(new_size);
33  threading::parallel_for(IndexRange(new_size), 4096, [&](const IndexRange range) {
34  for (const int64_t i : range) {
35  new_array[i] = i;
36  }
37  });
38  arrays.append(std::move(new_array));
39 
40  s_current_array.store(arrays.last().data(), std::memory_order_release);
41  s_current_array_size.store(new_size, std::memory_order_release);
42  });
43 
44  return Span<int64_t>(s_current_array + start_, size_);
45 }
46 
47 } // namespace blender
MINLINE unsigned int power_of_2_max_u(unsigned int x)
ThreadMutex mutex
volatile int lock
constexpr IndexRange()=default
void isolate_task(const Function &function)
Definition: BLI_task.hh:125
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
static RawVector< RawArray< int64_t, 0 > > arrays
static std::mutex current_array_mutex
__int64 int64_t
Definition: stdint.h:89