@@ -31,69 +31,68 @@ using provider_unique_handle_t =
31
31
std::unique_ptr<uma_memory_provider_t ,
32
32
std::function<void (uma_memory_provider_handle_t )>>;
33
33
34
+ #define UMA_ASSIGN_OP (ops, type, func, default_return ) \
35
+ ops.func = [](void *obj, auto ... args) { \
36
+ try { \
37
+ return reinterpret_cast <type *>(obj)->func (args...); \
38
+ } catch (...) { \
39
+ return default_return; \
40
+ } \
41
+ }
42
+
43
+ #define UMA_ASSIGN_OP_NORETURN (ops, type, func ) \
44
+ ops.func = [](void *obj, auto ... args) { \
45
+ try { \
46
+ return reinterpret_cast <type *>(obj)->func (args...); \
47
+ } catch (...) { \
48
+ } \
49
+ }
50
+
34
51
// / @brief creates UMA memory provider based on given T type.
35
52
// / T should implement all functions defined by
36
53
// / uma_memory_provider_ops_t, except for finalize (it is
37
54
// / replaced by dtor). All arguments passed to this function are
38
- // / forwarded to T::initialize(). All functions of T
39
- // / should be noexcept.
55
+ // / forwarded to T::initialize().
40
56
template <typename T, typename ... Args>
41
57
auto memoryProviderMakeUnique (Args &&...args) {
42
58
uma_memory_provider_ops_t ops;
43
59
auto argsTuple = std::make_tuple (std::forward<Args>(args)...);
44
- static_assert (
45
- noexcept (std::declval<T>().initialize (std::forward<Args>(args)...)));
46
60
47
61
ops.version = UMA_VERSION_CURRENT;
48
62
ops.initialize = [](void *params, void **obj) {
49
63
auto *tuple = reinterpret_cast <decltype (argsTuple) *>(params);
50
- auto provider = new T;
64
+ T *provider;
65
+ try {
66
+ provider = new T;
67
+ } catch (...) {
68
+ return UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
69
+ }
70
+
51
71
*obj = provider;
52
- auto ret = std::apply (
53
- &T::initialize, std::tuple_cat (std::make_tuple (provider), *tuple));
54
- if (ret != UMA_RESULT_SUCCESS) {
72
+
73
+ try {
74
+ auto ret =
75
+ std::apply (&T::initialize,
76
+ std::tuple_cat (std::make_tuple (provider), *tuple));
77
+ if (ret != UMA_RESULT_SUCCESS) {
78
+ delete provider;
79
+ }
80
+ return ret;
81
+ } catch (...) {
55
82
delete provider;
83
+ return UMA_RESULT_ERROR_UNKNOWN;
56
84
}
57
- return ret;
58
85
};
59
86
ops.finalize = [](void *obj) { delete reinterpret_cast <T *>(obj); };
60
- ops.alloc = [](void *obj, auto ... args) {
61
- static_assert (noexcept (reinterpret_cast <T *>(obj)->alloc (args...)));
62
- return reinterpret_cast <T *>(obj)->alloc (args...);
63
- };
64
- ops.free = [](void *obj, auto ... args) {
65
- static_assert (noexcept (reinterpret_cast <T *>(obj)->free (args...)));
66
- return reinterpret_cast <T *>(obj)->free (args...);
67
- };
68
- ops.get_last_result = [](void *obj, auto ... args) {
69
- static_assert (
70
- noexcept (reinterpret_cast <T *>(obj)->get_last_result (args...)));
71
- return reinterpret_cast <T *>(obj)->get_last_result (args...);
72
- };
73
- ops.get_recommended_page_size = [](void *obj, auto ... args) {
74
- static_assert (noexcept (
75
- reinterpret_cast <T *>(obj)->get_recommended_page_size (args...)));
76
- return reinterpret_cast <T *>(obj)->get_recommended_page_size (args...);
77
- };
78
- ops.get_min_page_size = [](void *obj, auto ... args) {
79
- static_assert (
80
- noexcept (reinterpret_cast <T *>(obj)->get_min_page_size (args...)));
81
- return reinterpret_cast <T *>(obj)->get_min_page_size (args...);
82
- };
83
- ops.purge_lazy = [](void *obj, auto ... args) {
84
- static_assert (
85
- noexcept (reinterpret_cast <T *>(obj)->purge_lazy (args...)));
86
- return reinterpret_cast <T *>(obj)->purge_lazy (args...);
87
- };
88
- ops.purge_force = [](void *obj, auto ... args) {
89
- static_assert (
90
- noexcept (reinterpret_cast <T *>(obj)->purge_force (args...)));
91
- return reinterpret_cast <T *>(obj)->purge_force (args...);
92
- };
93
- ops.get_name = [](void *obj, auto ... args) {
94
- static_assert (noexcept (reinterpret_cast <T *>(obj)->get_name (args...)));
95
- return reinterpret_cast <T *>(obj)->get_name (args...);
96
- };
87
+
88
+ UMA_ASSIGN_OP (ops, T, alloc, UMA_RESULT_ERROR_UNKNOWN);
89
+ UMA_ASSIGN_OP (ops, T, free, UMA_RESULT_ERROR_UNKNOWN);
90
+ UMA_ASSIGN_OP (ops, T, get_last_result, UMA_RESULT_ERROR_UNKNOWN);
91
+ UMA_ASSIGN_OP (ops, T, get_recommended_page_size, UMA_RESULT_ERROR_UNKNOWN);
92
+ UMA_ASSIGN_OP (ops, T, get_min_page_size, UMA_RESULT_ERROR_UNKNOWN);
93
+ UMA_ASSIGN_OP (ops, T, purge_lazy, UMA_RESULT_ERROR_UNKNOWN);
94
+ UMA_ASSIGN_OP (ops, T, purge_force, UMA_RESULT_ERROR_UNKNOWN);
95
+ UMA_ASSIGN_OP_NORETURN (ops, T, get_name);
97
96
98
97
uma_memory_provider_handle_t hProvider = nullptr ;
99
98
auto ret = umaMemoryProviderCreate (&ops, &argsTuple, &hProvider);
@@ -105,63 +104,50 @@ auto memoryProviderMakeUnique(Args &&...args) {
105
104
// / T should implement all functions defined by
106
105
// / uma_memory_provider_ops_t, except for finalize (it is
107
106
// / replaced by dtor). All arguments passed to this function are
108
- // / forwarded to T::initialize(). All functions of T
109
- // / should be noexcept.
107
+ // / forwarded to T::initialize().
110
108
template <typename T, typename ... Args>
111
109
auto poolMakeUnique (uma_memory_provider_handle_t *providers,
112
110
size_t numProviders, Args &&...args) {
113
111
uma_memory_pool_ops_t ops;
114
112
auto argsTuple = std::make_tuple (std::forward<Args>(args)...);
115
- static_assert (noexcept (std::declval<T>().initialize (
116
- providers, numProviders, std::forward<Args>(args)...)));
117
113
118
114
ops.version = UMA_VERSION_CURRENT;
119
115
ops.initialize = [](uma_memory_provider_handle_t *providers,
120
116
size_t numProviders, void *params, void **obj) {
121
117
auto *tuple = reinterpret_cast <decltype (argsTuple) *>(params);
122
- auto pool = new T;
118
+ T *pool;
119
+
120
+ try {
121
+ pool = new T;
122
+ } catch (...) {
123
+ return UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
124
+ }
125
+
123
126
*obj = pool;
124
- auto ret = std::apply (
125
- &T::initialize,
126
- std::tuple_cat (std::make_tuple (pool, providers, numProviders),
127
- *tuple));
128
- if (ret != UMA_RESULT_SUCCESS) {
127
+
128
+ try {
129
+ auto ret = std::apply (
130
+ &T::initialize,
131
+ std::tuple_cat (std::make_tuple (pool, providers, numProviders),
132
+ *tuple));
133
+ if (ret != UMA_RESULT_SUCCESS) {
134
+ delete pool;
135
+ }
136
+ return ret;
137
+ } catch (...) {
129
138
delete pool;
139
+ return UMA_RESULT_ERROR_UNKNOWN;
130
140
}
131
- return ret;
132
141
};
133
142
ops.finalize = [](void *obj) { delete reinterpret_cast <T *>(obj); };
134
- ops.malloc = [](void *obj, auto ... args) {
135
- static_assert (noexcept (reinterpret_cast <T *>(obj)->malloc (args...)));
136
- return reinterpret_cast <T *>(obj)->malloc (args...);
137
- };
138
- ops.calloc = [](void *obj, auto ... args) {
139
- static_assert (noexcept (reinterpret_cast <T *>(obj)->calloc (args...)));
140
- return reinterpret_cast <T *>(obj)->calloc (args...);
141
- };
142
- ops.aligned_malloc = [](void *obj, auto ... args) {
143
- static_assert (
144
- noexcept (reinterpret_cast <T *>(obj)->aligned_malloc (args...)));
145
- return reinterpret_cast <T *>(obj)->aligned_malloc (args...);
146
- };
147
- ops.realloc = [](void *obj, auto ... args) {
148
- static_assert (noexcept (reinterpret_cast <T *>(obj)->realloc (args...)));
149
- return reinterpret_cast <T *>(obj)->realloc (args...);
150
- };
151
- ops.malloc_usable_size = [](void *obj, auto ... args) {
152
- static_assert (
153
- noexcept (reinterpret_cast <T *>(obj)->malloc_usable_size (args...)));
154
- return reinterpret_cast <T *>(obj)->malloc_usable_size (args...);
155
- };
156
- ops.free = [](void *obj, auto ... args) {
157
- static_assert (noexcept (reinterpret_cast <T *>(obj)->free (args...)));
158
- reinterpret_cast <T *>(obj)->free (args...);
159
- };
160
- ops.get_last_result = [](void *obj, auto ... args) {
161
- static_assert (
162
- noexcept (reinterpret_cast <T *>(obj)->get_last_result (args...)));
163
- return reinterpret_cast <T *>(obj)->get_last_result (args...);
164
- };
143
+
144
+ UMA_ASSIGN_OP (ops, T, malloc, ((void *)nullptr ));
145
+ UMA_ASSIGN_OP (ops, T, calloc, ((void *)nullptr ));
146
+ UMA_ASSIGN_OP (ops, T, aligned_malloc, ((void *)nullptr ));
147
+ UMA_ASSIGN_OP (ops, T, realloc, ((void *)nullptr ));
148
+ UMA_ASSIGN_OP (ops, T, malloc_usable_size, ((size_t )0 ));
149
+ UMA_ASSIGN_OP_NORETURN (ops, T, free);
150
+ UMA_ASSIGN_OP (ops, T, get_last_result, UMA_RESULT_ERROR_UNKNOWN);
165
151
166
152
uma_memory_pool_handle_t hPool = nullptr ;
167
153
auto ret = umaPoolCreate (&ops, providers, numProviders, &argsTuple, &hPool);
0 commit comments