raze-gles/libraries/asmjit/asmjit/base/osutils.h
2020-05-23 22:43:03 +02:00

178 lines
5.9 KiB
C++

// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.
// [Guard]
#ifndef _ASMJIT_BASE_OSUTILS_H
#define _ASMJIT_BASE_OSUTILS_H
// [Dependencies]
#include "../base/globals.h"
// [Api-Begin]
#include "../asmjit_apibegin.h"
namespace asmjit {
//! \addtogroup asmjit_base
//! \{
// ============================================================================
// [asmjit::VMemInfo]
// ============================================================================
//! Information about OS virtual memory.
struct VMemInfo {
#if ASMJIT_OS_WINDOWS
HANDLE hCurrentProcess; //!< Handle of the current process (Windows).
#endif // ASMJIT_OS_WINDOWS
size_t pageSize; //!< Virtual memory page size.
size_t pageGranularity; //!< Virtual memory page granularity.
};
// ============================================================================
// [asmjit::OSUtils]
// ============================================================================
//! OS utilities.
//!
//! Virtual Memory
//! --------------
//!
//! Provides functions to allocate and release virtual memory that is required
//! to execute dynamically generated code. If both processor and host OS support
//! data-execution-prevention (DEP) then the only way to run machine code is to
//! allocate virtual memory that has `OSUtils::kVMExecutable` flag enabled. All
//! functions provides by OSUtils use internally platform specific API.
//!
//! Benchmarking
//! ------------
//!
//! OSUtils also provide a function `getTickCount()` that can be used for
//! benchmarking purposes. It's similar to Windows-only `GetTickCount()`, but
//! it's cross-platform and tries to be the most reliable platform specific
//! calls to make the result usable.
struct OSUtils {
// --------------------------------------------------------------------------
// [Virtual Memory]
// --------------------------------------------------------------------------
//! Virtual memory flags.
ASMJIT_ENUM(VMFlags) {
kVMWritable = 0x00000001U, //!< Virtual memory is writable.
kVMExecutable = 0x00000002U //!< Virtual memory is executable.
};
ASMJIT_API static VMemInfo getVirtualMemoryInfo() noexcept;
//! Allocate virtual memory.
ASMJIT_API static void* allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept;
//! Release virtual memory previously allocated by \ref allocVirtualMemory().
ASMJIT_API static Error releaseVirtualMemory(void* p, size_t size) noexcept;
#if ASMJIT_OS_WINDOWS
//! Allocate virtual memory of `hProcess` (Windows).
ASMJIT_API static void* allocProcessMemory(HANDLE hProcess, size_t size, size_t* allocated, uint32_t flags) noexcept;
//! Release virtual memory of `hProcess` (Windows).
ASMJIT_API static Error releaseProcessMemory(HANDLE hProcess, void* p, size_t size) noexcept;
#endif // ASMJIT_OS_WINDOWS
// --------------------------------------------------------------------------
// [GetTickCount]
// --------------------------------------------------------------------------
//! Get the current CPU tick count, used for benchmarking (1ms resolution).
ASMJIT_API static uint32_t getTickCount() noexcept;
};
// ============================================================================
// [asmjit::Lock]
// ============================================================================
//! \internal
//!
//! Lock.
struct Lock {
ASMJIT_NONCOPYABLE(Lock)
// --------------------------------------------------------------------------
// [Windows]
// --------------------------------------------------------------------------
#if ASMJIT_OS_WINDOWS
typedef CRITICAL_SECTION Handle;
//! Create a new `Lock` instance.
ASMJIT_INLINE Lock() noexcept { InitializeCriticalSection(&_handle); }
//! Destroy the `Lock` instance.
ASMJIT_INLINE ~Lock() noexcept { DeleteCriticalSection(&_handle); }
//! Lock.
ASMJIT_INLINE void lock() noexcept { EnterCriticalSection(&_handle); }
//! Unlock.
ASMJIT_INLINE void unlock() noexcept { LeaveCriticalSection(&_handle); }
#endif // ASMJIT_OS_WINDOWS
// --------------------------------------------------------------------------
// [Posix]
// --------------------------------------------------------------------------
#if ASMJIT_OS_POSIX
typedef pthread_mutex_t Handle;
//! Create a new `Lock` instance.
ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
//! Destroy the `Lock` instance.
ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
//! Lock.
ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
//! Unlock.
ASMJIT_INLINE void unlock() noexcept { pthread_mutex_unlock(&_handle); }
#endif // ASMJIT_OS_POSIX
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Native handle.
Handle _handle;
};
// ============================================================================
// [asmjit::AutoLock]
// ============================================================================
//! \internal
//!
//! Scoped lock.
struct AutoLock {
ASMJIT_NONCOPYABLE(AutoLock)
// --------------------------------------------------------------------------
// [Construction / Destruction]
// --------------------------------------------------------------------------
ASMJIT_INLINE AutoLock(Lock& target) noexcept : _target(target) { _target.lock(); }
ASMJIT_INLINE ~AutoLock() noexcept { _target.unlock(); }
// --------------------------------------------------------------------------
// [Members]
// --------------------------------------------------------------------------
//! Reference to the `Lock`.
Lock& _target;
};
//! \}
} // asmjit namespace
// [Api-End]
#include "../asmjit_apiend.h"
// [Guard]
#endif // _ASMJIT_BASE_OSUTILS_H