Blender V5.0
implicit_sharing.cc
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#include <algorithm>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
15
17
19 public:
20 void *data;
21
23 {
24 BLI_assert(data != nullptr);
25 }
26
27 private:
28 void delete_self_with_data() override
29 {
31 MEM_delete(this);
32 }
33};
34
36{
37 return MEM_new<MEMFreeImplicitSharing>(__func__, data);
38}
39
40namespace detail {
41
42void *make_trivial_data_mutable_impl(void *old_data,
43 const int64_t size,
44 const int64_t alignment,
45 const ImplicitSharingInfo **sharing_info)
46{
47 if (!old_data) {
48 BLI_assert(size == 0);
49 return nullptr;
50 }
51
52 BLI_assert(*sharing_info != nullptr);
53 if ((*sharing_info)->is_mutable()) {
54 (*sharing_info)->tag_ensured_mutable();
55 }
56 else {
57 void *new_data = MEM_mallocN_aligned(size, alignment, __func__);
58 memcpy(new_data, old_data, size);
59 (*sharing_info)->remove_user_and_delete_if_last();
60 *sharing_info = info_for_mem_free(new_data);
61 return new_data;
62 }
63
64 return old_data;
65}
66
67void *resize_trivial_array_impl(void *old_data,
68 const int64_t old_size,
69 const int64_t new_size,
70 const int64_t alignment,
71 const ImplicitSharingInfo **sharing_info)
72{
73 if (new_size == 0) {
74 if (*sharing_info) {
75 (*sharing_info)->remove_user_and_delete_if_last();
76 *sharing_info = nullptr;
77 }
78 return nullptr;
79 }
80
81 if (!old_data) {
82 BLI_assert(old_size == 0);
83 BLI_assert(*sharing_info == nullptr);
84 void *new_data = MEM_mallocN_aligned(new_size, alignment, __func__);
85 *sharing_info = info_for_mem_free(new_data);
86 return new_data;
87 }
88
89 BLI_assert(old_size != 0);
90 if ((*sharing_info)->is_mutable()) {
91 if (auto *info = const_cast<MEMFreeImplicitSharing *>(
92 dynamic_cast<const MEMFreeImplicitSharing *>(*sharing_info)))
93 {
94 /* If the array was allocated with the MEM allocator, we can use realloc directly, which
95 * could theoretically give better performance if the data can be reused in place. */
96 void *new_data = static_cast<int *>(MEM_reallocN(old_data, new_size));
97 info->data = new_data;
98 (*sharing_info)->tag_ensured_mutable();
99 return new_data;
100 }
101 }
102
103 void *new_data = MEM_mallocN_aligned(new_size, alignment, __func__);
104 memcpy(new_data, old_data, std::min(old_size, new_size));
105 (*sharing_info)->remove_user_and_delete_if_last();
106 *sharing_info = info_for_mem_free(new_data);
107 return new_data;
108}
109
110} // namespace detail
111
112} // namespace blender::implicit_sharing
#define BLI_assert(a)
Definition BLI_assert.h:46
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
BMesh const char void * data
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:138
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void * resize_trivial_array_impl(void *old_data, int64_t old_size, int64_t new_size, int64_t alignment, const ImplicitSharingInfo **sharing_info)
void * make_trivial_data_mutable_impl(void *old_data, int64_t size, int64_t alignment, const ImplicitSharingInfo **sharing_info)
const ImplicitSharingInfo * info_for_mem_free(void *data)