missing project/build files
[client-tools.git] / src / external / 3rd / library / videocapture / SoeUtil / Memory.h
bloba2a1727df7b24a0cc5d902f7f6d258e461559c5a
1 // Copyright 2009 Sony Online Entertainment, all rights reserved.
2 // Original author: Jeff Petersen
3 #ifndef SOEUTIL_MEMORY_H
4 #define SOEUTIL_MEMORY_H
6 #include "ThreadLocal.h"
7 #include <new>
10 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 // The basic idea is to allow hooking of the SoeUtil memory allocations that occur. The application call
12 // SoeUtil::SetMemoryHandler to point SoeUtil to use the specified MemoryHandler derived class. All allocations
13 // by SoeUtil that occur then get routed to the handler.
15 // Normally SetMemoryHandler only changes the handler for the current thread-context. Applications can use
16 // SetGlobalMemoryHandler to change the MemoryHandler used for all thread contexts. Thread-specific handlers take
17 // precedence over the global handler, which takes precedence over going directly to the built-in heap. By default
18 // there are no handlers installed and everything goes directly to the built-in heap.
20 // Not all memory activity inside of SoeUtil routes through the MemoryHandler. In particular, the DeleteAll
21 // convenience function on embedded containers, the algorithm ListDeleteAll, and the RefCounted::RefDestroySelf
22 // function do not go through the handler to free things, but instead always simply call 'delete' since most of the
23 // time these are allocations that were done by the application directly. Serialization and Unserialization of
24 // embedded containers also do not go through the memory handler, for similar reasons.
26 // The application is free to also hook through the SoeUtil memory handler by doing allocations via the
27 // SoeUtil::Alloc and SoeUtil::Free functions.
29 // Warning: It is not safe to delete an object via its base-class pointer by explicitly calling the destructor and
30 // then calling SoeUtil::Free on the pointer to free the memory. The base-class pointer is not guaranteed to point
31 // to the beginning of the originally allocated memory-block in situations where multiple-inheritance has been used.
32 // This is partly the reason why SoeUtil makes no attempt to have DeleteAll and Release functionality go through its
33 // custom allocator. The only safe way to destruct an object via a pointer to it base class is via the 'delete'
34 // operator. If these things must be routed to a custom allocator, then overloading the new/delete operator on a
35 // per class basis (or the global new/delete operator) would be required.
36 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
39 namespace SoeUtil
43 class MemoryHandler
45 public:
46 // if this handler is set as the global handler for all thread contexts, then these functions need to be thread-safe.
47 virtual void *OnAlloc(int bytes) = 0;
48 virtual void OnFree(void *p) = 0;
51 // These two calls set/get the memory handler for the global-context
52 // It is not safe to change the global handler if other threads are currently using the heap/SoeUtil, since they may get mismatched alloc/free calls
53 void SetGlobalMemoryHandler(MemoryHandler *handler);
54 MemoryHandler *GetGlobalMemoryHandler();
56 // These two calls set/get the memory handler for this thread-context
57 void SetMemoryHandler(MemoryHandler *handler);
58 MemoryHandler *GetMemoryHandler();
60 void *Alloc(int bytes); // returns NULL on failure
61 void Free(void *p);
64 class MemoryHandlerGuard
66 public:
67 MemoryHandlerGuard(MemoryHandler *handler)
69 m_oldHandler = GetMemoryHandler();
70 SetMemoryHandler(handler);
73 ~MemoryHandlerGuard()
75 SetMemoryHandler(m_oldHandler);
78 protected:
79 MemoryHandler *m_oldHandler;
82 // deriving from this base class will cause derived classes to route through the SoeUtil::Alloc and SoeUtil::Free functions
83 class MemoryBase
85 public:
86 static void *operator new(size_t size) { void *p = Alloc((int)size); if (p == NULL) { throw std::bad_alloc(); } return p; }
87 static void *operator new[](size_t size) { void *p = Alloc((int)size); if (p == NULL) { throw std::bad_alloc(); } return p; }
88 static void *operator new(size_t size, const std::nothrow_t &) throw() { return Alloc((int)size); }
89 static void *operator new(size_t /*size*/, void *p) throw() { return p; }
90 static void *operator new[](size_t size, const std::nothrow_t &) throw() { return Alloc((int)size); }
91 static void *operator new[](size_t /*size*/, void *p) throw() { return p; }
93 static void operator delete(void *p) throw() { Free(p); }
94 static void operator delete[](void *p) throw() { Free(p); }
95 static void operator delete(void *p, const std::nothrow_t &) throw() { Free(p); }
96 static void operator delete(void * /*p*/, void *) throw() {}
97 static void operator delete[] (void *p, const std::nothrow_t &) throw() { Free(p); }
98 static void operator delete[] (void * /*p*/, void *) throw() {}
102 ////////////////////////////////////////////////////////////////////////////////////////////////////////
103 // inline implementation
104 ////////////////////////////////////////////////////////////////////////////////////////////////////////
106 namespace SystemInternal
108 inline MemoryHandler *&GlobalMemoryHandler()
110 static MemoryHandler *s_memoryHandler = NULL;
111 return s_memoryHandler;
114 inline SoeUtil::ThreadLocalPointer<MemoryHandler> &GlobalTlsMemoryHandler()
116 static SoeUtil::ThreadLocalPointer<MemoryHandler> s_tls_memoryHandler;
117 return s_tls_memoryHandler;
121 inline void *Alloc(int bytes)
123 if (SystemInternal::GlobalTlsMemoryHandler().Get() != NULL)
125 return SystemInternal::GlobalTlsMemoryHandler().Get()->OnAlloc(bytes);
127 else if (SystemInternal::GlobalMemoryHandler() != NULL)
129 return SystemInternal::GlobalMemoryHandler()->OnAlloc(bytes);
131 else
133 return new(std::nothrow) byte[bytes];
137 inline void Free(void *p)
139 if (p != NULL)
141 if (SystemInternal::GlobalTlsMemoryHandler().Get() != NULL)
143 SystemInternal::GlobalTlsMemoryHandler().Get()->OnFree(p);
145 else if (SystemInternal::GlobalMemoryHandler() != NULL)
147 SystemInternal::GlobalMemoryHandler()->OnFree(p);
149 else
151 delete[] (byte *)p;
156 inline void SetGlobalMemoryHandler(MemoryHandler *handler)
158 SystemInternal::GlobalMemoryHandler() = handler;
161 inline MemoryHandler *GetGlobalMemoryHandler()
163 return SystemInternal::GlobalMemoryHandler();
166 inline void SetMemoryHandler(MemoryHandler *handler)
168 SystemInternal::GlobalTlsMemoryHandler().Set(handler);
171 inline MemoryHandler *GetMemoryHandler()
173 return SystemInternal::GlobalTlsMemoryHandler().Get();
177 } // namespace
180 #endif