MSVC support for libcontext
This uses the Windows native Fiber API.
This commit is contained in:
parent
884ae5a7ff
commit
6cab769f41
|
@ -13,6 +13,8 @@
|
||||||
http://www.boost.org/LICENSE_1_0.txt)
|
http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <setjmp.h>
|
||||||
#include <system/libcontext.h>
|
#include <system/libcontext.h>
|
||||||
|
|
||||||
#if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
|
#if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc)
|
||||||
|
@ -1268,3 +1270,67 @@ __asm (
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386)
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace libcontext
|
||||||
|
{
|
||||||
|
|
||||||
|
static int threadHasFibers = 0;
|
||||||
|
|
||||||
|
struct FiberData
|
||||||
|
{
|
||||||
|
intptr_t inValue;
|
||||||
|
intptr_t outValue;
|
||||||
|
void(*entry)(intptr_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<fcontext_t, FiberData> fiberParams;
|
||||||
|
|
||||||
|
static void fiberEntry(LPVOID params)
|
||||||
|
{
|
||||||
|
auto ctx = (fcontext_t) GetCurrentFiber();
|
||||||
|
auto& d = fiberParams[ctx];
|
||||||
|
d.entry(d.inValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
fcontext_t LIBCONTEXT_CALL_CONVENTION make_fcontext(void* sp, size_t size, void(*fn)(intptr_t))
|
||||||
|
{
|
||||||
|
if (!threadHasFibers)
|
||||||
|
{
|
||||||
|
ConvertThreadToFiber(nullptr);
|
||||||
|
threadHasFibers = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcontext_t ctx = CreateFiber(size, (LPFIBER_START_ROUTINE) fiberEntry, nullptr );
|
||||||
|
fiberParams[ctx].entry = fn;
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t LIBCONTEXT_CALL_CONVENTION jump_fcontext(fcontext_t* ofc, fcontext_t nfc,
|
||||||
|
intptr_t vp, bool preserve_fpu)
|
||||||
|
{
|
||||||
|
auto current = (void*)GetCurrentFiber();
|
||||||
|
fiberParams[current].outValue = vp;
|
||||||
|
*ofc = GetCurrentFiber();
|
||||||
|
fiberParams[nfc].inValue = vp;
|
||||||
|
SwitchToFiber(nfc);
|
||||||
|
return fiberParams[*ofc].outValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace libcontext
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__GNUC__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
|
|
||||||
|
#undef LIBCONTEXT_HAS_OWN_STACK
|
||||||
|
|
||||||
#define LIBCONTEXT_COMPILER_gcc
|
#define LIBCONTEXT_COMPILER_gcc
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
@ -46,7 +48,8 @@
|
||||||
#ifdef _ARCH_PPC64
|
#ifdef _ARCH_PPC64
|
||||||
#define LIBCONTEXT_PLATFORM_linux_ppc64
|
#define LIBCONTEXT_PLATFORM_linux_ppc64
|
||||||
#define LIBCONTEXT_CALL_CONVENTION
|
#define LIBCONTEXT_CALL_CONVENTION
|
||||||
#elif defined _ARCH_PPC
|
#endif
|
||||||
|
#ifdef _ARCH_PPC
|
||||||
#define LIBCONTEXT_PLATFORM_linux_ppc32
|
#define LIBCONTEXT_PLATFORM_linux_ppc32
|
||||||
#define LIBCONTEXT_CALL_CONVENTION
|
#define LIBCONTEXT_CALL_CONVENTION
|
||||||
#endif
|
#endif
|
||||||
|
@ -73,6 +76,17 @@
|
||||||
#define LIBCONTEXT_CALL_CONVENTION
|
#define LIBCONTEXT_CALL_CONVENTION
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined (_MSC_VER)
|
||||||
|
|
||||||
|
#define LIBCONTEXT_HAS_OWN_STACK
|
||||||
|
|
||||||
|
#define LIBCONTEXT_CALL_CONVENTION __cdecl
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define LIBCONTEXT_PLATFORM_msvc_x86_64
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define LIBCONTEXT_PLATFORM_msvc_i386
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -294,15 +294,19 @@ private:
|
||||||
|
|
||||||
assert( m_stack == nullptr );
|
assert( m_stack == nullptr );
|
||||||
|
|
||||||
// fixme: Clean up stack stuff. Add a guard
|
|
||||||
size_t stackSize = c_defaultStackSize;
|
size_t stackSize = c_defaultStackSize;
|
||||||
|
void* sp = nullptr;
|
||||||
|
|
||||||
|
#ifndef LIBCONTEXT_HAS_OWN_STACK
|
||||||
|
// fixme: Clean up stack stuff. Add a guard
|
||||||
m_stack.reset( new char[stackSize] );
|
m_stack.reset( new char[stackSize] );
|
||||||
|
|
||||||
// align to 16 bytes
|
// align to 16 bytes
|
||||||
void* sp = (void*)((((ptrdiff_t) m_stack.get()) + stackSize - 0xf) & (~0x0f));
|
sp = (void*)((((ptrdiff_t) m_stack.get()) + stackSize - 0xf) & (~0x0f));
|
||||||
|
|
||||||
// correct the stack size
|
// correct the stack size
|
||||||
stackSize -= size_t( ( (ptrdiff_t) m_stack.get() + stackSize ) - (ptrdiff_t) sp );
|
stackSize -= size_t( ( (ptrdiff_t) m_stack.get() + stackSize ) - (ptrdiff_t) sp );
|
||||||
|
#endif
|
||||||
|
|
||||||
m_callee = libcontext::make_fcontext( sp, stackSize, callerStub );
|
m_callee = libcontext::make_fcontext( sp, stackSize, callerStub );
|
||||||
m_running = true;
|
m_running = true;
|
||||||
|
|
Loading…
Reference in New Issue