fix libretrobridge to be 64bit only (and fix it for 64bit)
This commit is contained in:
parent
39433e509e
commit
0246c540bb
|
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
delegate void MessageApi(eMessage msg);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
delegate void BufferApi(BufId id, void* ptr, int size);
|
||||
delegate void BufferApi(BufId id, void* ptr, ulong size); //size_t
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
delegate void SetVariableApi(string key, string value);
|
||||
|
@ -106,7 +106,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
public void CopyAscii(BufId id, string str)
|
||||
{
|
||||
fixed (char* cp = str)
|
||||
_copyBuffer(id, cp, str.Length + 1);
|
||||
_copyBuffer(id, cp, (ulong)str.Length + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -115,7 +115,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
public void CopyBytes(BufId id, byte[] bytes)
|
||||
{
|
||||
fixed (byte* bp = bytes)
|
||||
_copyBuffer(id, bp, bytes.Length);
|
||||
_copyBuffer(id, bp, (ulong)bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -129,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
{
|
||||
fixed (byte* bp = bytes)
|
||||
{
|
||||
_setBuffer(id, bp, bytes.Length);
|
||||
_setBuffer(id, bp, (ulong)bytes.Length);
|
||||
andThen();
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
{
|
||||
fixed (byte* cp = System.Text.Encoding.ASCII.GetBytes(str+"\0"))
|
||||
{
|
||||
_setBuffer(id, cp, str.Length + 1);
|
||||
_setBuffer(id, cp, (ulong)str.Length + 1);
|
||||
andThen();
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
{
|
||||
public retro_system_info retro_system_info;
|
||||
public retro_system_av_info retro_system_av_info;
|
||||
public uint retro_serialize_size; //size_t :(
|
||||
public ulong retro_serialize_size; //size_t actually
|
||||
public uint retro_region;
|
||||
public uint retro_api_version;
|
||||
public retro_pixel_format pixel_format; //default is 0 -- RETRO_PIXEL_FORMAT_0RGB1555
|
||||
|
@ -196,8 +196,8 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
public CommStructEnv env;
|
||||
|
||||
//this should always be used in pairs
|
||||
public fixed uint buf[(int)BufId.BufId_Num]; //ACTUALLY A POINTER but can't marshal it :(
|
||||
public fixed int buf_size[(int)BufId.BufId_Num];
|
||||
public fixed ulong buf[(int)BufId.BufId_Num]; //actually a pointer, but can't marshal IntPtr, so dumb
|
||||
public fixed ulong buf_size[(int)BufId.BufId_Num]; //actually a size_t
|
||||
|
||||
//utilities
|
||||
public bool GetBoolValue() { return value != 0; } //should this be here or by the other helpers? I dont know
|
||||
|
|
|
@ -6,11 +6,11 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
{
|
||||
unsafe partial class LibretroApi
|
||||
{
|
||||
public Tuple<IntPtr, int> QUERY_GetMemory(RETRO_MEMORY mem)
|
||||
public Tuple<IntPtr, ulong> QUERY_GetMemory(RETRO_MEMORY mem)
|
||||
{
|
||||
comm->value = (uint)mem;
|
||||
Message(eMessage.QUERY_GetMemory);
|
||||
return Tuple.Create(new IntPtr(comm->buf[(int)BufId.Param0]), comm->buf_size[(int)BufId.Param0]);
|
||||
return Tuple.Create(new IntPtr((long)comm->buf[(int)BufId.Param0]), comm->buf_size[(int)BufId.Param0]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
case eMessage.SIG_SampleBatch:
|
||||
{
|
||||
void* samples = (void*)comm->buf[(int)BufId.Param0];
|
||||
core.retro_audio_sample_batch(samples, comm->buf_size[(int)BufId.Param0]/4);
|
||||
core.retro_audio_sample_batch(samples, (int)comm->buf_size[(int)BufId.Param0]/4);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
var mem = api.QUERY_GetMemory(LibretroApi.RETRO_MEMORY.SAVE_RAM);
|
||||
var buf = new byte[mem.Item2];
|
||||
|
||||
Marshal.Copy(mem.Item1, buf, 0, mem.Item2);
|
||||
Marshal.Copy(mem.Item1, buf, 0, (int)mem.Item2);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ namespace BizHawk.Emulation.Cores.Libretro
|
|||
if (mem.Item2 == 0)
|
||||
return;
|
||||
|
||||
Marshal.Copy(data, 0, mem.Item1, mem.Item2);
|
||||
Marshal.Copy(data, 0, mem.Item1, (int)mem.Item2);
|
||||
}
|
||||
|
||||
public bool SaveRamModified
|
||||
|
|
|
@ -170,7 +170,7 @@ struct CommStruct
|
|||
|
||||
//always used in pairs
|
||||
void* buf[BufId_Num];
|
||||
s32 buf_size[BufId_Num];
|
||||
size_t buf_size[BufId_Num];
|
||||
|
||||
//===========================================================
|
||||
//private stuff
|
||||
|
@ -185,7 +185,7 @@ struct CommStruct
|
|||
size_t len = strlen(str);
|
||||
CopyBuffer(id, (void*)str, len+1);
|
||||
}
|
||||
void CopyBuffer(int id, void* ptr, s32 size)
|
||||
void CopyBuffer(int id, void* ptr, size_t size)
|
||||
{
|
||||
if (privbuf[id]) free(privbuf[id]);
|
||||
buf[id] = privbuf[id] = malloc(size);
|
||||
|
@ -193,7 +193,7 @@ struct CommStruct
|
|||
buf_size[id] = size;
|
||||
}
|
||||
|
||||
void SetBuffer(int id, void* ptr, s32 size)
|
||||
void SetBuffer(int id, void* ptr, size_t size)
|
||||
{
|
||||
buf[id] = ptr;
|
||||
buf_size[id] = size;
|
||||
|
|
|
@ -7,14 +7,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibretroBridge", "LibretroB
|
|||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x86.Build.0 = Debug|Win32
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x86.ActiveCfg = Release|Win32
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x86.Build.0 = Release|Win32
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Debug|x64.Build.0 = Debug|x64
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x64.ActiveCfg = Release|x64
|
||||
{AEACAA89-FDA2-40C6-910C-85AEB9726452}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
|
@ -19,14 +11,26 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="features_cpu.c" />
|
||||
<ClCompile Include="libco\sjlj-multi.c" />
|
||||
<ClCompile Include="LibretroBridge.cpp" />
|
||||
<ClCompile Include="features_cpu.c">
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libco\amd64.c">
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LibretroBridge.cpp">
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotSet</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="libco\libco.h" />
|
||||
<ClInclude Include="libretro.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="libco\coswap.asm" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AEACAA89-FDA2-40C6-910C-85AEB9726452}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
@ -34,20 +38,6 @@
|
|||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
|
@ -64,15 +54,10 @@
|
|||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
|
@ -80,44 +65,16 @@
|
|||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>..\..\output\dll\</OutDir>
|
||||
<IntDir>.obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>..\..\output\dll\</OutDir>
|
||||
<IntDir>.obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>..\..\output\dll\</OutDir>
|
||||
<IntDir>.obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>..\..\output\dll\</OutDir>
|
||||
<IntDir>.obj\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBRETRO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
|
@ -136,27 +93,6 @@
|
|||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBRETRO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalOptions>/pdbaltpath:%_PDB% %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
|
@ -180,6 +116,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
|
|
@ -1,104 +1,82 @@
|
|||
/*
|
||||
libco.amd64 (2009-10-12)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static thread_local long long co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle = 0;
|
||||
static void (*co_swap)(cothread_t, cothread_t) = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
//ABI: Win64
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x22, 0x48, 0x8B, 0x21, 0x58, 0x48, 0x89, 0x6A, 0x08, 0x48, 0x89, 0x72, 0x10, 0x48,
|
||||
0x89, 0x7A, 0x18, 0x48, 0x89, 0x5A, 0x20, 0x4C, 0x89, 0x62, 0x28, 0x4C, 0x89, 0x6A, 0x30, 0x4C,
|
||||
0x89, 0x72, 0x38, 0x4C, 0x89, 0x7A, 0x40, 0x48, 0x81, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
|
||||
0xE2, 0xF0, 0x0F, 0x29, 0x32, 0x0F, 0x29, 0x7A, 0x10, 0x44, 0x0F, 0x29, 0x42, 0x20, 0x44, 0x0F,
|
||||
0x29, 0x4A, 0x30, 0x44, 0x0F, 0x29, 0x52, 0x40, 0x44, 0x0F, 0x29, 0x5A, 0x50, 0x44, 0x0F, 0x29,
|
||||
0x62, 0x60, 0x44, 0x0F, 0x29, 0x6A, 0x70, 0x44, 0x0F, 0x29, 0xB2, 0x80, 0x00, 0x00, 0x00, 0x44,
|
||||
0x0F, 0x29, 0xBA, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x69, 0x08, 0x48, 0x8B, 0x71, 0x10, 0x48,
|
||||
0x8B, 0x79, 0x18, 0x48, 0x8B, 0x59, 0x20, 0x4C, 0x8B, 0x61, 0x28, 0x4C, 0x8B, 0x69, 0x30, 0x4C,
|
||||
0x8B, 0x71, 0x38, 0x4C, 0x8B, 0x79, 0x40, 0x48, 0x81, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83,
|
||||
0xE1, 0xF0, 0x0F, 0x29, 0x31, 0x0F, 0x29, 0x79, 0x10, 0x44, 0x0F, 0x29, 0x41, 0x20, 0x44, 0x0F,
|
||||
0x29, 0x49, 0x30, 0x44, 0x0F, 0x29, 0x51, 0x40, 0x44, 0x0F, 0x29, 0x59, 0x50, 0x44, 0x0F, 0x29,
|
||||
0x61, 0x60, 0x44, 0x0F, 0x29, 0x69, 0x70, 0x44, 0x0F, 0x29, 0xB1, 0x80, 0x00, 0x00, 0x00, 0x44,
|
||||
0x0F, 0x29, 0xB9, 0x90, 0x00, 0x00, 0x00, 0xFF, 0xE0,
|
||||
};
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void co_init() {
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
#else
|
||||
//ABI: SystemV
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x48, 0x89, 0x26, 0x48, 0x8B, 0x27, 0x58, 0x48, 0x89, 0x6E, 0x08, 0x48, 0x89, 0x5E, 0x10, 0x4C,
|
||||
0x89, 0x66, 0x18, 0x4C, 0x89, 0x6E, 0x20, 0x4C, 0x89, 0x76, 0x28, 0x4C, 0x89, 0x7E, 0x30, 0x48,
|
||||
0x8B, 0x6F, 0x08, 0x48, 0x8B, 0x5F, 0x10, 0x4C, 0x8B, 0x67, 0x18, 0x4C, 0x8B, 0x6F, 0x20, 0x4C,
|
||||
0x8B, 0x77, 0x28, 0x4C, 0x8B, 0x7F, 0x30, 0xFF, 0xE0,
|
||||
};
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void co_init() {
|
||||
unsigned long long addr = (unsigned long long)co_swap_function;
|
||||
unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long long size = (addr - base) + sizeof co_swap_function;
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crash() {
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
|
||||
cothread_t handle;
|
||||
if(!co_swap) {
|
||||
co_init();
|
||||
co_swap = (void (*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
if(!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
size += 512; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
if(handle = (cothread_t)malloc(size)) {
|
||||
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle) {
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle) {
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
libco.amd64 (2016-09-14)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static long long co_active_buffer[64];
|
||||
static cothread_t co_active_handle = 0;
|
||||
|
||||
static void* smalloc(size_t size)
|
||||
{
|
||||
char* ret = malloc(size + 16);
|
||||
if (ret)
|
||||
{
|
||||
*(size_t*)ret = size;
|
||||
return ret + 16;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sfree(void* ptr)
|
||||
{
|
||||
char* original = (char*)ptr - 16;
|
||||
size_t size = *(size_t*)original + 16;
|
||||
memset(original, 0, size);
|
||||
free(original);
|
||||
}
|
||||
|
||||
extern void co_swap(cothread_t, cothread_t);
|
||||
|
||||
static void crash() {
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
void co_clean() {
|
||||
memset(co_active_buffer, 0, sizeof(co_active_buffer));
|
||||
}
|
||||
|
||||
cothread_t co_active() {
|
||||
if (!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void(*entrypoint)(void)) {
|
||||
cothread_t handle;
|
||||
if (!co_active_handle) co_active_handle = &co_active_buffer;
|
||||
size += 512; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
if (handle = (cothread_t)smalloc(size)) {
|
||||
long long *p = (long long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long long)entrypoint; /* start of function */
|
||||
*(long long*)handle = (long long)p; /* stack pointer */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle) {
|
||||
sfree(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle) {
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
_TEXT SEGMENT
|
||||
|
||||
PUBLIC co_swap
|
||||
co_swap PROC
|
||||
|
||||
mov [rdx],rsp
|
||||
mov rsp,[rcx]
|
||||
pop rax
|
||||
mov [rdx+ 8],rbp
|
||||
mov [rdx+16],rsi
|
||||
mov [rdx+24],rdi
|
||||
mov [rdx+32],rbx
|
||||
mov [rdx+40],r12
|
||||
mov [rdx+48],r13
|
||||
mov [rdx+56],r14
|
||||
mov [rdx+64],r15
|
||||
|
||||
movaps [rdx+ 80],xmm6
|
||||
movaps [rdx+ 96],xmm7
|
||||
movaps [rdx+112],xmm8
|
||||
add rdx,112
|
||||
movaps [rdx+ 16],xmm9
|
||||
movaps [rdx+ 32],xmm10
|
||||
movaps [rdx+ 48],xmm11
|
||||
movaps [rdx+ 64],xmm12
|
||||
movaps [rdx+ 80],xmm13
|
||||
movaps [rdx+ 96],xmm14
|
||||
movaps [rdx+112],xmm15
|
||||
|
||||
mov rbp,[rcx+ 8]
|
||||
mov rsi,[rcx+16]
|
||||
mov rdi,[rcx+24]
|
||||
mov rbx,[rcx+32]
|
||||
mov r12,[rcx+40]
|
||||
mov r13,[rcx+48]
|
||||
mov r14,[rcx+56]
|
||||
mov r15,[rcx+64]
|
||||
|
||||
movaps xmm6, [rcx+ 80]
|
||||
movaps xmm7, [rcx+ 96]
|
||||
movaps xmm8, [rcx+112]
|
||||
add rcx,112
|
||||
movaps xmm9, [rcx+ 16]
|
||||
movaps xmm10,[rcx+ 32]
|
||||
movaps xmm11,[rcx+ 48]
|
||||
movaps xmm12,[rcx+ 64]
|
||||
movaps xmm13,[rcx+ 80]
|
||||
movaps xmm14,[rcx+ 96]
|
||||
movaps xmm15,[rcx+112]
|
||||
|
||||
jmp rax
|
||||
|
||||
co_swap ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
|
||||
END
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
original author: Nach
|
||||
license: public domain
|
||||
|
||||
additional work: zeromus
|
||||
note: more ARM compilers are supported here (check the ifdefs in _JUMP_BUFFER)
|
||||
and: work has been done to make this coexist more peaceably with .net
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
jmp_buf context;
|
||||
coentry_t coentry;
|
||||
void *stack;
|
||||
unsigned long seh_frame, stack_top, stack_bottom;
|
||||
cothread_t caller;
|
||||
int ownstack;
|
||||
} cothread_struct;
|
||||
|
||||
static thread_local cothread_struct _co_primary;
|
||||
static thread_local cothread_struct *co_running = 0;
|
||||
|
||||
cothread_t co_primary() { return (cothread_t)&_co_primary; }
|
||||
|
||||
|
||||
//-------------------
|
||||
#ifdef _MSC_VER
|
||||
|
||||
//links of interest
|
||||
//http://connect.microsoft.com/VisualStudio/feedback/details/100319/really-wierd-behaviour-in-crt-io-coupled-with-some-inline-assembly
|
||||
//http://en.wikipedia.org/wiki/Thread_Information_Block
|
||||
//http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/72093e46-4524-4f54-9f36-c7e8a309d1db/ //FS warning
|
||||
|
||||
|
||||
#define WINVER 0x0400
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#pragma warning(disable:4733)
|
||||
#pragma warning(disable:4311)
|
||||
|
||||
static void capture_fs(cothread_struct* rec)
|
||||
{
|
||||
int temp;
|
||||
__asm mov eax, dword ptr fs:[0];
|
||||
__asm mov temp, eax;
|
||||
rec->seh_frame = temp;
|
||||
__asm mov eax, dword ptr fs:[4];
|
||||
__asm mov temp, eax;
|
||||
rec->stack_top = temp;
|
||||
__asm mov eax, dword ptr fs:[8];
|
||||
__asm mov temp, eax;
|
||||
rec->stack_bottom = temp;
|
||||
}
|
||||
|
||||
static void restore_fs(cothread_struct* rec)
|
||||
{
|
||||
int temp;
|
||||
temp = rec->seh_frame;
|
||||
__asm mov eax, temp;
|
||||
__asm mov dword ptr fs:[0], eax
|
||||
temp = rec->stack_top;
|
||||
__asm mov eax, temp;
|
||||
__asm mov dword ptr fs:[4], eax
|
||||
temp = rec->stack_bottom;
|
||||
__asm mov eax, temp;
|
||||
__asm mov dword ptr fs:[8], eax
|
||||
}
|
||||
|
||||
static void os_co_wrapper()
|
||||
{
|
||||
cothread_struct* rec = (cothread_struct*)co_active();
|
||||
__try
|
||||
{
|
||||
rec->coentry();
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//unhandled win32 exception in coroutine.
|
||||
//this coroutine will now be suspended permanently and control will be yielded to caller, for lack of anything better to do.
|
||||
//perhaps the process should just terminate.
|
||||
for(;;)
|
||||
{
|
||||
//dead coroutine
|
||||
co_switch(rec->caller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry)
|
||||
{
|
||||
_JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context;
|
||||
cothread_struct temp;
|
||||
|
||||
jb->Esp = (unsigned long)rec->stack + size - 4;
|
||||
jb->Eip = (unsigned long)os_co_wrapper;
|
||||
|
||||
rec->stack_top = jb->Esp + 4;
|
||||
rec->stack_bottom = (unsigned long)rec->stack;
|
||||
|
||||
//wild assumption about SEH frame.. seems to work
|
||||
capture_fs(&temp);
|
||||
rec->seh_frame = temp.seh_frame;
|
||||
}
|
||||
|
||||
static void os_pre_setjmp(cothread_t target)
|
||||
{
|
||||
cothread_struct* rec = (cothread_struct*)target;
|
||||
capture_fs(co_running);
|
||||
rec->caller = co_running;
|
||||
}
|
||||
|
||||
static void os_pre_longjmp(cothread_struct* rec)
|
||||
{
|
||||
restore_fs(rec);
|
||||
}
|
||||
|
||||
#elif defined(__ARM_EABI__) || defined(__ARMCC_VERSION)
|
||||
|
||||
//http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/machine/arm/setjmp.S?rev=1.5&content-type=text/x-cvsweb-markup&cvsroot=src
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef LIBCO_ARM_JUMBLED
|
||||
int r8,r9,r10,r11,lr,r4,r5,r6,r7,sp;
|
||||
#else
|
||||
int r4,r5,r6,r7,r8,r9,r10,fp;
|
||||
#ifndef LIBCO_ARM_NOIP
|
||||
int ip;
|
||||
#endif
|
||||
int sp,lr;
|
||||
#endif
|
||||
} _JUMP_BUFFER;
|
||||
|
||||
static void os_co_create(cothread_struct* rec, unsigned int size, coentry_t coentry)
|
||||
{
|
||||
_JUMP_BUFFER* jb = (_JUMP_BUFFER*)&rec->context;
|
||||
|
||||
jb->sp = (unsigned long)rec->stack + size - 4;
|
||||
jb->lr = (unsigned long)coentry;
|
||||
}
|
||||
|
||||
static void os_pre_setjmp(cothread_t target)
|
||||
{
|
||||
cothread_struct* rec = (cothread_struct*)target;
|
||||
rec->caller = co_running;
|
||||
}
|
||||
|
||||
static void os_pre_longjmp(cothread_struct* rec)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
#error "sjlj-multi: unsupported processor, compiler or operating system"
|
||||
#endif
|
||||
//-------------------
|
||||
|
||||
cothread_t co_active()
|
||||
{
|
||||
if(!co_running) co_running = &_co_primary;
|
||||
return (cothread_t)co_running;
|
||||
}
|
||||
|
||||
void* co_getstack(cothread_t cothread)
|
||||
{
|
||||
return ((cothread_struct*)cothread)->stack;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int stacksize, coentry_t coentry)
|
||||
{
|
||||
cothread_struct* ret = (cothread_struct*)co_create_withstack(malloc(stacksize), stacksize, coentry);
|
||||
if(ret)
|
||||
ret->ownstack = 1;
|
||||
return (cothread_t)ret;
|
||||
}
|
||||
|
||||
cothread_t co_create_withstack(void* stack, int stacksize, coentry_t coentry)
|
||||
{
|
||||
cothread_struct *thread;
|
||||
|
||||
if(!co_running) co_running = &_co_primary;
|
||||
|
||||
thread = (cothread_struct*)malloc(sizeof(cothread_struct));
|
||||
if(thread)
|
||||
{
|
||||
thread->coentry = coentry;
|
||||
thread->stack = stack;
|
||||
|
||||
{
|
||||
setjmp(thread->context);
|
||||
os_co_create(thread,stacksize,coentry);
|
||||
}
|
||||
thread->ownstack = 0;
|
||||
}
|
||||
|
||||
return (cothread_t)thread;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t cothread)
|
||||
{
|
||||
if(cothread)
|
||||
{
|
||||
cothread_struct* thread = (cothread_struct*)cothread;
|
||||
if (thread->ownstack)
|
||||
free(thread->stack);
|
||||
free(cothread);
|
||||
}
|
||||
}
|
||||
|
||||
void co_switch(cothread_t cothread)
|
||||
{
|
||||
os_pre_setjmp(cothread);
|
||||
if(!setjmp(co_running->context))
|
||||
{
|
||||
co_running = (cothread_struct*)cothread;
|
||||
os_pre_longjmp(co_running);
|
||||
longjmp(co_running->context,0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
libco.x86 (2009-10-12)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define fastcall __fastcall
|
||||
#elif defined(__GNUC__)
|
||||
#define fastcall __attribute__((fastcall))
|
||||
#else
|
||||
#error "libco: please define fastcall macro"
|
||||
#endif
|
||||
|
||||
static thread_local long co_active_buffer[64];
|
||||
static thread_local cothread_t co_active_handle = 0;
|
||||
static void (fastcall *co_swap)(cothread_t, cothread_t) = 0;
|
||||
|
||||
//ABI: fastcall
|
||||
static unsigned char co_swap_function[] = {
|
||||
0x89, 0x22, /* mov [edx],esp */
|
||||
0x8b, 0x21, /* mov esp,[ecx] */
|
||||
0x58, /* pop eax */
|
||||
0x89, 0x6a, 0x04, /* mov [edx+0x04],ebp */
|
||||
0x89, 0x72, 0x08, /* mov [edx+0x08],esi */
|
||||
0x89, 0x7a, 0x0c, /* mov [edx+0x0c],edi */
|
||||
0x89, 0x5a, 0x10, /* mov [edx+0x10],ebx */
|
||||
0x8b, 0x69, 0x04, /* mov ebp,[ecx+0x04] */
|
||||
0x8b, 0x71, 0x08, /* mov esi,[ecx+0x08] */
|
||||
0x8b, 0x79, 0x0c, /* mov edi,[ecx+0x0c] */
|
||||
0x8b, 0x59, 0x10, /* mov ebx,[ecx+0x10] */
|
||||
0xff, 0xe0, /* jmp eax */
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
void co_init(void)
|
||||
{
|
||||
DWORD old_privileges;
|
||||
VirtualProtect(co_swap_function,
|
||||
sizeof co_swap_function, PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||
}
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void co_init(void)
|
||||
{
|
||||
unsigned long addr = (unsigned long)co_swap_function;
|
||||
unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE));
|
||||
unsigned long size = (addr - base) + sizeof co_swap_function;
|
||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crash(void)
|
||||
{
|
||||
assert(0); /* called only if cothread_t entrypoint returns */
|
||||
}
|
||||
|
||||
cothread_t co_active(void)
|
||||
{
|
||||
if(!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
return co_active_handle;
|
||||
}
|
||||
|
||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||
{
|
||||
cothread_t handle;
|
||||
if(!co_swap)
|
||||
{
|
||||
co_init();
|
||||
co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function;
|
||||
}
|
||||
|
||||
if(!co_active_handle)
|
||||
co_active_handle = &co_active_buffer;
|
||||
|
||||
size += 256; /* allocate additional space for storage */
|
||||
size &= ~15; /* align stack to 16-byte boundary */
|
||||
|
||||
if((handle = (cothread_t)malloc(size)))
|
||||
{
|
||||
long *p = (long*)((char*)handle + size); /* seek to top of stack */
|
||||
*--p = (long)crash; /* crash if entrypoint returns */
|
||||
*--p = (long)entrypoint; /* start of function */
|
||||
*(long*)handle = (long)p; /* stack pointer */
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void co_delete(cothread_t handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void co_switch(cothread_t handle)
|
||||
{
|
||||
register cothread_t co_previous_handle = co_active_handle;
|
||||
co_swap(co_active_handle = handle, co_previous_handle);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue