]> git.sesse.net Git - casparcg/blob - common/page_locked_allocator.cpp
set svn:eol-style native on .h and .cpp files
[casparcg] / common / page_locked_allocator.cpp
1 #include "stdafx.h"
2
3 #include "os/windows/windows.h"
4
5 #include <unordered_map>
6 #include <tbb/mutex.h>
7 #include <tbb/atomic.h>
8
9 namespace caspar { namespace detail {
10         
11 tbb::mutex                                                      g_mutex;
12 std::unordered_map<void*, size_t>       g_map;
13 size_t                                                          g_free;
14
15 void allocate_store(size_t size)
16 {               
17         SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0;
18         if(::GetProcessWorkingSetSize(::GetCurrentProcess(), &workingSetMinSize, &workingSetMaxSize))
19         {                       
20                 workingSetMinSize += size;
21                 workingSetMaxSize += size;
22
23                 if(!::SetProcessWorkingSetSize(::GetCurrentProcess(), workingSetMinSize, workingSetMaxSize))            
24                         throw std::bad_alloc();         
25
26                 g_free += size;
27         }
28 }
29
30 void* alloc_page_locked(size_t size)
31 {
32         tbb::mutex::scoped_lock lock(g_mutex);
33
34         if(g_free < size)
35                 allocate_store(size);
36
37         auto p = ::VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
38         if(!p)
39                 throw std::bad_alloc();
40
41         if(::VirtualLock(p, size) == 0) 
42         {
43                 ::VirtualFree(p, 0, MEM_RELEASE);
44                 throw std::bad_alloc();
45         }
46                 
47         g_free   -= size;
48         g_map[p]        = size;
49         return p;
50
51 }
52
53 void free_page_locked(void* p)
54 {               
55         tbb::mutex::scoped_lock lock(g_mutex);
56
57         if(g_map.find(p) == g_map.end())
58                 return;
59
60         ::VirtualFree(p, 0, MEM_RELEASE);
61
62         g_free += g_map[p];
63         g_map.erase(p);
64 }
65
66 }}