1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 Copyright (c) 2008-2017, Petr Kobalicek
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not
13    claim that you wrote the original software. If you use this software
14    in a product, an acknowledgment in the product documentation would be
15    appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17    misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
20 #ifndef __PLUMED_asmjit_osutils_h
21 #define __PLUMED_asmjit_osutils_h
22 #ifdef __PLUMED_HAS_ASMJIT
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wpedantic"
25 // [AsmJit]
26 // Complete x86/x64 JIT and Remote Assembler for C++.
27 //
28 // [License]
29 // Zlib - See LICENSE.md file in the package.
30 
31 // [Guard]
32 #ifndef _ASMJIT_BASE_OSUTILS_H
33 #define _ASMJIT_BASE_OSUTILS_H
34 
35 // [Dependencies]
36 #include "./globals.h"
37 
38 // [Api-Begin]
39 #include "./asmjit_apibegin.h"
40 
41 namespace PLMD {
42 namespace asmjit {
43 
44 //! \addtogroup asmjit_base
45 //! \{
46 
47 // ============================================================================
48 // [asmjit::VMemInfo]
49 // ============================================================================
50 
51 //! Information about OS virtual memory.
52 struct VMemInfo {
53 #if ASMJIT_OS_WINDOWS
54   HANDLE hCurrentProcess;                //!< Handle of the current process (Windows).
55 #endif // ASMJIT_OS_WINDOWS
56   size_t pageSize;                       //!< Virtual memory page size.
57   size_t pageGranularity;                //!< Virtual memory page granularity.
58 };
59 
60 // ============================================================================
61 // [asmjit::OSUtils]
62 // ============================================================================
63 
64 //! OS utilities.
65 //!
66 //! Virtual Memory
67 //! --------------
68 //!
69 //! Provides functions to allocate and release virtual memory that is required
70 //! to execute dynamically generated code. If both processor and host OS support
71 //! data-execution-prevention (DEP) then the only way to run machine code is to
72 //! allocate virtual memory that has `OSUtils::kVMExecutable` flag enabled. All
73 //! functions provides by OSUtils use internally platform specific API.
74 //!
75 //! Benchmarking
76 //! ------------
77 //!
78 //! OSUtils also provide a function `getTickCount()` that can be used for
79 //! benchmarking purposes. It's similar to Windows-only `GetTickCount()`, but
80 //! it's cross-platform and tries to be the most reliable platform specific
81 //! calls to make the result usable.
82 struct OSUtils {
83   // --------------------------------------------------------------------------
84   // [Virtual Memory]
85   // --------------------------------------------------------------------------
86 
87   //! Virtual memory flags.
ASMJIT_ENUMOSUtils88   ASMJIT_ENUM(VMFlags) {
89     kVMWritable   = 0x00000001U,         //!< Virtual memory is writable.
90     kVMExecutable = 0x00000002U          //!< Virtual memory is executable.
91   };
92 
93   ASMJIT_API static VMemInfo getVirtualMemoryInfo() noexcept;
94 
95   //! Allocate virtual memory.
96   ASMJIT_API static void* allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept;
97   //! Release virtual memory previously allocated by \ref allocVirtualMemory().
98   ASMJIT_API static Error releaseVirtualMemory(void* p, size_t size) noexcept;
99 
100 #if ASMJIT_OS_WINDOWS
101   //! Allocate virtual memory of `hProcess` (Windows).
102   ASMJIT_API static void* allocProcessMemory(HANDLE hProcess, size_t size, size_t* allocated, uint32_t flags) noexcept;
103 
104   //! Release virtual memory of `hProcess` (Windows).
105   ASMJIT_API static Error releaseProcessMemory(HANDLE hProcess, void* p, size_t size) noexcept;
106 #endif // ASMJIT_OS_WINDOWS
107 
108   // --------------------------------------------------------------------------
109   // [GetTickCount]
110   // --------------------------------------------------------------------------
111 
112   //! Get the current CPU tick count, used for benchmarking (1ms resolution).
113   ASMJIT_API static uint32_t getTickCount() noexcept;
114 };
115 
116 // ============================================================================
117 // [asmjit::Lock]
118 // ============================================================================
119 
120 //! \internal
121 //!
122 //! Lock.
123 struct Lock {
124   ASMJIT_NONCOPYABLE(Lock)
125 
126   // --------------------------------------------------------------------------
127   // [Windows]
128   // --------------------------------------------------------------------------
129 
130 #if ASMJIT_OS_WINDOWS
131   typedef CRITICAL_SECTION Handle;
132 
133   //! Create a new `Lock` instance.
LockLock134   ASMJIT_INLINE Lock() noexcept { InitializeCriticalSection(&_handle); }
135   //! Destroy the `Lock` instance.
~LockLock136   ASMJIT_INLINE ~Lock() noexcept { DeleteCriticalSection(&_handle); }
137 
138   //! Lock.
lockLock139   ASMJIT_INLINE void lock() noexcept { EnterCriticalSection(&_handle); }
140   //! Unlock.
unlockLock141   ASMJIT_INLINE void unlock() noexcept { LeaveCriticalSection(&_handle); }
142 #endif // ASMJIT_OS_WINDOWS
143 
144   // --------------------------------------------------------------------------
145   // [Posix]
146   // --------------------------------------------------------------------------
147 
148 #if ASMJIT_OS_POSIX
149   typedef pthread_mutex_t Handle;
150 
151   //! Create a new `Lock` instance.
LockLock152   ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
153   //! Destroy the `Lock` instance.
~LockLock154   ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
155 
156   //! Lock.
lockLock157   ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
158   //! Unlock.
unlockLock159   ASMJIT_INLINE void unlock() noexcept { pthread_mutex_unlock(&_handle); }
160 #endif // ASMJIT_OS_POSIX
161 
162   // --------------------------------------------------------------------------
163   // [Members]
164   // --------------------------------------------------------------------------
165 
166   //! Native handle.
167   Handle _handle;
168 };
169 
170 // ============================================================================
171 // [asmjit::AutoLock]
172 // ============================================================================
173 
174 //! \internal
175 //!
176 //! Scoped lock.
177 struct AutoLock {
ASMJIT_NONCOPYABLEAutoLock178   ASMJIT_NONCOPYABLE(AutoLock)
179 
180   // --------------------------------------------------------------------------
181   // [Construction / Destruction]
182   // --------------------------------------------------------------------------
183 
184   ASMJIT_INLINE AutoLock(Lock& target) noexcept : _target(target) { _target.lock(); }
~AutoLockAutoLock185   ASMJIT_INLINE ~AutoLock() noexcept { _target.unlock(); }
186 
187   // --------------------------------------------------------------------------
188   // [Members]
189   // --------------------------------------------------------------------------
190 
191   //! Reference to the `Lock`.
192   Lock& _target;
193 };
194 
195 //! \}
196 
197 } // asmjit namespace
198 } // namespace PLMD
199 
200 // [Api-End]
201 #include "./asmjit_apiend.h"
202 
203 // [Guard]
204 #endif // _ASMJIT_BASE_OSUTILS_H
205 #pragma GCC diagnostic pop
206 #endif // __PLUMED_HAS_ASMJIT
207 #endif
208