1 #ifndef _VKALLOCATIONCALLBACKUTIL_HPP
2 #define _VKALLOCATIONCALLBACKUTIL_HPP
3 /*-------------------------------------------------------------------------
7 * Copyright (c) 2015 Google Inc.
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Memory allocation callback utilities.
24 *//*--------------------------------------------------------------------*/
27 #include "deAppendList.hpp"
40 class AllocationCallbacks
43 AllocationCallbacks (void);
44 virtual ~AllocationCallbacks (void);
46 virtual void* allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
47 virtual void* reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
48 virtual void free (void* mem) = 0;
50 virtual void notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;
51 virtual void notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;
53 const VkAllocationCallbacks* getCallbacks (void) const { return &m_callbacks; }
56 const VkAllocationCallbacks m_callbacks;
59 struct AllocationCallbackRecord
63 TYPE_ALLOCATION = 0, //! Call to pfnAllocation
64 TYPE_REALLOCATION, //! Call to pfnReallocation
65 TYPE_FREE, //! Call to pfnFree
66 TYPE_INTERNAL_ALLOCATION, //! Call to pfnInternalAllocation
67 TYPE_INTERNAL_FREE, //! Call to pfnInternalFree
80 VkSystemAllocationScope scope;
89 VkSystemAllocationScope scope;
98 // \note Used for both INTERNAL_ALLOCATION and INTERNAL_FREE
102 VkInternalAllocationType type;
103 VkSystemAllocationScope scope;
104 } internalAllocation;
107 AllocationCallbackRecord (void) : type(TYPE_LAST) {}
109 static AllocationCallbackRecord allocation (size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
110 static AllocationCallbackRecord reallocation (void* original, size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
111 static AllocationCallbackRecord free (void* mem);
112 static AllocationCallbackRecord internalAllocation (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
113 static AllocationCallbackRecord internalFree (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
116 class ChainedAllocator : public AllocationCallbacks
119 ChainedAllocator (const VkAllocationCallbacks* nextAllocator);
120 ~ChainedAllocator (void);
122 void* allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
123 void* reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
124 void free (void* mem);
126 void notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
127 void notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
130 const VkAllocationCallbacks* m_nextAllocator;
133 class AllocationCallbackRecorder : public ChainedAllocator
136 AllocationCallbackRecorder (const VkAllocationCallbacks* allocator, deUint32 callCountHint = 1024);
137 ~AllocationCallbackRecorder (void);
139 void* allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
140 void* reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
141 void free (void* mem);
143 void notifyInternalAllocation (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
144 void notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
146 typedef de::AppendList<AllocationCallbackRecord>::const_iterator RecordIterator;
148 RecordIterator getRecordsBegin (void) const { return m_records.begin(); }
149 RecordIterator getRecordsEnd (void) const { return m_records.end(); }
152 typedef de::AppendList<AllocationCallbackRecord> Records;
157 //! Allocator that starts returning null after N allocs
158 class DeterministicFailAllocator : public ChainedAllocator
161 DeterministicFailAllocator (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs);
162 ~DeterministicFailAllocator (void);
164 void* allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
165 void* reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
168 const deUint32 m_numPassingAllocs;
169 volatile deUint32 m_allocationNdx;
172 struct AllocationCallbackViolation
176 REASON_DOUBLE_FREE = 0,
177 REASON_FREE_NOT_ALLOCATED_PTR,
178 REASON_REALLOC_NOT_ALLOCATED_PTR,
179 REASON_REALLOC_FREED_PTR,
180 REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL,
181 REASON_INVALID_ALLOCATION_SCOPE,
182 REASON_INVALID_INTERNAL_ALLOCATION_TYPE,
183 REASON_INVALID_ALIGNMENT,
184 REASON_REALLOC_DIFFERENT_ALIGNMENT,
189 AllocationCallbackRecord record;
192 AllocationCallbackViolation (void)
193 : reason(REASON_LAST)
196 AllocationCallbackViolation (const AllocationCallbackRecord& record_, Reason reason_)
202 struct AllocationCallbackValidationResults
204 std::vector<AllocationCallbackRecord> liveAllocations;
205 size_t internalAllocationTotal[VK_INTERNAL_ALLOCATION_TYPE_LAST][VK_SYSTEM_ALLOCATION_SCOPE_LAST];
206 std::vector<AllocationCallbackViolation> violations;
208 AllocationCallbackValidationResults (void);
213 void validateAllocationCallbacks (const AllocationCallbackRecorder& recorder, AllocationCallbackValidationResults* results);
214 bool checkAndLog (tcu::TestLog& log, const AllocationCallbackValidationResults& results, deUint32 allowedLiveAllocScopeBits);
215 bool validateAndLog (tcu::TestLog& log, const AllocationCallbackRecorder& recorder, deUint32 allowedLiveAllocScopeBits);
217 size_t getLiveSystemAllocationTotal (const AllocationCallbackValidationResults& validationResults);
219 std::ostream& operator<< (std::ostream& str, const AllocationCallbackRecord& record);
220 std::ostream& operator<< (std::ostream& str, const AllocationCallbackViolation& violation);
222 const VkAllocationCallbacks* getSystemAllocator (void);
226 #endif // _VKALLOCATIONCALLBACKUTIL_HPP