Blender V4.3
BLI_implicit_sharing_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "MEM_guardedalloc.h"
6
8
9#include "testing/testing.h"
10
11namespace blender::tests {
12
14 public:
16 {
17 return ImplicitSharingPtr<ImplicitlySharedData>(MEM_new<ImplicitlySharedData>(__func__));
18 }
19
20 void delete_self() override
21 {
22 MEM_delete(this);
23 }
24};
25
27 private:
29
30 public:
31 SharedDataContainer() : data_(MEM_new<ImplicitlySharedData>(__func__)) {}
32
34 {
35 return data_.get();
36 }
37
39 {
40 return data_.get();
41 }
42
44 {
45 if (!data_) {
46 return nullptr;
47 }
48 if (data_->is_mutable()) {
49 data_->tag_ensured_mutable();
50 }
51 else {
52 data_ = data_->copy();
53 }
54 return const_cast<ImplicitlySharedData *>(data_.get());
55 }
56};
57
58TEST(implicit_sharing, CopyOnWriteAccess)
59{
60 /* Create the initial data. */
62 EXPECT_NE(a.get_for_read(), nullptr);
63
64 /* a and b share the same underlying data now. */
66 EXPECT_EQ(a.get_for_read(), b.get_for_read());
67
68 /* c now shares the data with a and b. */
70 EXPECT_EQ(b.get_for_read(), c.get_for_read());
71
72 /* Retrieving write access on b should make a copy because the data is shared. */
73 ImplicitlySharedData *data_b1 = b.get_for_write();
74 EXPECT_NE(data_b1, nullptr);
75 EXPECT_EQ(data_b1, b.get_for_read());
76 EXPECT_NE(data_b1, a.get_for_read());
77 EXPECT_NE(data_b1, c.get_for_read());
78
79 /* Retrieving the same write access again should *not* make another copy. */
80 ImplicitlySharedData *data_b2 = b.get_for_write();
81 EXPECT_EQ(data_b1, data_b2);
82
83 /* Moving b should also move the data. b then does not have ownership anymore. Since the data in
84 * b only had one owner, the data is still mutable now that d is the owner. */
85 SharedDataContainer d = std::move(b);
86 EXPECT_EQ(b.get_for_read(), nullptr);
87 EXPECT_EQ(b.get_for_write(), nullptr);
88 EXPECT_EQ(d.get_for_read(), data_b1);
89 EXPECT_EQ(d.get_for_write(), data_b1);
90}
91
92TEST(implicit_sharing, WeakUser)
93{
95 const ImplicitSharingInfo *sharing_info = a.sharing_info();
96 EXPECT_FALSE(sharing_info->is_expired());
97 EXPECT_TRUE(sharing_info->is_mutable());
98 sharing_info->add_weak_user();
99 EXPECT_FALSE(sharing_info->is_expired());
100 EXPECT_TRUE(sharing_info->is_mutable());
101 a = {};
102 EXPECT_TRUE(sharing_info->is_expired());
104}
105
106TEST(implicit_sharing, Version)
107{
109 const ImplicitSharingInfo *sharing_info = a.sharing_info();
110 const int old_version = sharing_info->version();
111 a.get_for_read();
112 EXPECT_EQ(old_version, sharing_info->version());
113 a.get_for_write();
114 EXPECT_LT(old_version, sharing_info->version());
115}
116
117} // namespace blender::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
Read Guarded memory(de)allocation.
ImplicitSharingPtr< ImplicitlySharedData > copy() const
const ImplicitlySharedData * get_for_read() const
const ImplicitSharingInfo * sharing_info() const
local_group_size(16, 16) .push_constant(Type b
TEST(any, DefaultConstructor)