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