1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "default.h"
namespace embree
{
/*! invokes the memory monitor callback */
struct MemoryMonitorInterface {
virtual void memoryMonitor(ssize_t bytes, bool post) = 0;
};
/*! allocator that performs aligned monitored allocations */
template<typename T, size_t alignment = 64>
struct aligned_monitored_allocator
{
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
__forceinline aligned_monitored_allocator(MemoryMonitorInterface* device)
: device(device), hugepages(false) {}
__forceinline pointer allocate( size_type n )
{
if (n) {
assert(device);
device->memoryMonitor(n*sizeof(T),false);
}
if (n*sizeof(value_type) >= 14 * PAGE_SIZE_2M)
{
pointer p = (pointer) os_malloc(n*sizeof(value_type),hugepages);
assert(p);
return p;
}
return (pointer) alignedMalloc(n*sizeof(value_type),alignment);
}
__forceinline void deallocate( pointer p, size_type n )
{
if (p)
{
if (n*sizeof(value_type) >= 14 * PAGE_SIZE_2M)
os_free(p,n*sizeof(value_type),hugepages);
else
alignedFree(p);
}
else assert(n == 0);
if (n) {
assert(device);
device->memoryMonitor(-ssize_t(n)*sizeof(T),true);
}
}
__forceinline void construct( pointer p, const_reference val ) {
new (p) T(val);
}
__forceinline void destroy( pointer p ) {
p->~T();
}
private:
MemoryMonitorInterface* device;
bool hugepages;
};
/*! monitored vector */
template<typename T>
using mvector = vector_t<T,aligned_monitored_allocator<T,std::alignment_of<T>::value> >;
}
|