85d9cfbbb8f827bb1586291faaf6df34686bc997
[novacoin.git] / src / allocators.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_ALLOCATORS_H
6 #define BITCOIN_ALLOCATORS_H
7
8 #include <string>
9
10 #ifdef WIN32
11 #define _WIN32_WINNT 0x0501
12 #define WIN32_LEAN_AND_MEAN 1
13 #ifndef NOMINMAX
14 #define NOMINMAX
15 #endif
16 #include <windows.h>
17 // This is used to attempt to keep keying material out of swap
18 // Note that VirtualLock does not provide this as a guarantee on Windows,
19 // but, in practice, memory that has been VirtualLock'd almost never gets written to
20 // the pagefile except in rare circumstances where memory is extremely low.
21 #define mlock(p, n) VirtualLock((p), (n));
22 #define munlock(p, n) VirtualUnlock((p), (n));
23 #else
24 #include <sys/mman.h>
25 #include <limits.h>
26 /* This comes from limits.h if it's not defined there set a sane default */
27 #ifndef PAGESIZE
28 #include <unistd.h>
29 #define PAGESIZE sysconf(_SC_PAGESIZE)
30 #endif
31 #define mlock(a,b) \
32   mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
33   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
34 #define munlock(a,b) \
35   munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
36   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
37 #endif
38
39 //
40 // Allocator that locks its contents from being paged
41 // out of memory and clears its contents before deletion.
42 //
43 template<typename T>
44 struct secure_allocator : public std::allocator<T>
45 {
46     // MSVC8 default copy constructor is broken
47     typedef std::allocator<T> base;
48     typedef typename base::size_type size_type;
49     typedef typename base::difference_type  difference_type;
50     typedef typename base::pointer pointer;
51     typedef typename base::const_pointer const_pointer;
52     typedef typename base::reference reference;
53     typedef typename base::const_reference const_reference;
54     typedef typename base::value_type value_type;
55     secure_allocator() throw() {}
56     secure_allocator(const secure_allocator& a) throw() : base(a) {}
57     template <typename U>
58     secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
59     ~secure_allocator() throw() {}
60     template<typename _Other> struct rebind
61     { typedef secure_allocator<_Other> other; };
62
63     T* allocate(std::size_t n, const void *hint = 0)
64     {
65         T *p;
66         p = std::allocator<T>::allocate(n, hint);
67         if (p != NULL)
68             mlock(p, sizeof(T) * n);
69         return p;
70     }
71
72     void deallocate(T* p, std::size_t n)
73     {
74         if (p != NULL)
75         {
76             memset(p, 0, sizeof(T) * n);
77             munlock(p, sizeof(T) * n);
78         }
79         std::allocator<T>::deallocate(p, n);
80     }
81 };
82
83
84 //
85 // Allocator that clears its contents before deletion.
86 //
87 template<typename T>
88 struct zero_after_free_allocator : public std::allocator<T>
89 {
90     // MSVC8 default copy constructor is broken
91     typedef std::allocator<T> base;
92     typedef typename base::size_type size_type;
93     typedef typename base::difference_type  difference_type;
94     typedef typename base::pointer pointer;
95     typedef typename base::const_pointer const_pointer;
96     typedef typename base::reference reference;
97     typedef typename base::const_reference const_reference;
98     typedef typename base::value_type value_type;
99     zero_after_free_allocator() throw() {}
100     zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
101     template <typename U>
102     zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
103     ~zero_after_free_allocator() throw() {}
104     template<typename _Other> struct rebind
105     { typedef zero_after_free_allocator<_Other> other; };
106
107     void deallocate(T* p, std::size_t n)
108     {
109         if (p != NULL)
110             memset(p, 0, sizeof(T) * n);
111         std::allocator<T>::deallocate(p, n);
112     }
113 };
114
115 // This is exactly like std::string, but with a custom allocator.
116 // (secure_allocator<> is defined in serialize.h)
117 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
118
119 #endif