mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-20 22:33:22 +02:00
update libco
This commit is contained in:
+35
-28
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBCO_C
|
#define LIBCO_C
|
||||||
#include "libco.h"
|
#include <libco.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -21,12 +21,10 @@ static thread_local long long co_active_buffer[64];
|
|||||||
static thread_local cothread_t co_active_handle = 0;
|
static thread_local cothread_t co_active_handle = 0;
|
||||||
#ifndef CO_USE_INLINE_ASM
|
#ifndef CO_USE_INLINE_ASM
|
||||||
static void (*co_swap)(cothread_t, cothread_t) = 0;
|
static void (*co_swap)(cothread_t, cothread_t) = 0;
|
||||||
#else
|
|
||||||
void co_swap(cothread_t, cothread_t);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
//ABI: Win64
|
/* ABI: Win64 */
|
||||||
static unsigned char co_swap_function[] = {
|
static unsigned char co_swap_function[] = {
|
||||||
0x48, 0x89, 0x22, /* mov [rdx],rsp */
|
0x48, 0x89, 0x22, /* mov [rdx],rsp */
|
||||||
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
|
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
|
||||||
@@ -83,7 +81,7 @@ void co_init(void)
|
|||||||
sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges);
|
sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
//ABI: SystemV
|
/* ABI: SystemV */
|
||||||
#ifndef CO_USE_INLINE_ASM
|
#ifndef CO_USE_INLINE_ASM
|
||||||
static unsigned char co_swap_function[] = {
|
static unsigned char co_swap_function[] = {
|
||||||
0x48, 0x89, 0x26, /* mov [rsi],rsp */
|
0x48, 0x89, 0x26, /* mov [rsi],rsp */
|
||||||
@@ -115,29 +113,7 @@ void co_init(void)
|
|||||||
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
mprotect((void*)base, size, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
__asm__(
|
void co_init(void) {}
|
||||||
".intel_syntax noprefix\n"
|
|
||||||
".globl co_swap \n"
|
|
||||||
"co_swap: \n"
|
|
||||||
".globl _co_swap \n" /* OSX ABI is different from Linux. */
|
|
||||||
"_co_swap: \n"
|
|
||||||
"mov [rsi],rsp \n"
|
|
||||||
"mov [rsi+0x08],rbp \n"
|
|
||||||
"mov [rsi+0x10],rbx \n"
|
|
||||||
"mov [rsi+0x18],r12 \n"
|
|
||||||
"mov [rsi+0x20],r13 \n"
|
|
||||||
"mov [rsi+0x28],r14 \n"
|
|
||||||
"mov [rsi+0x30],r15 \n"
|
|
||||||
"mov rsp,[rdi] \n"
|
|
||||||
"mov rbp,[rdi+0x08] \n"
|
|
||||||
"mov rbx,[rdi+0x10] \n"
|
|
||||||
"mov r12,[rdi+0x18] \n"
|
|
||||||
"mov r13,[rdi+0x20] \n"
|
|
||||||
"mov r14,[rdi+0x28] \n"
|
|
||||||
"mov r15,[rdi+0x30] \n"
|
|
||||||
"ret \n"
|
|
||||||
".att_syntax \n"
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -186,11 +162,42 @@ void co_delete(cothread_t handle)
|
|||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CO_USE_INLINE_ASM
|
||||||
void co_switch(cothread_t handle)
|
void co_switch(cothread_t handle)
|
||||||
{
|
{
|
||||||
register cothread_t co_previous_handle = co_active_handle;
|
register cothread_t co_previous_handle = co_active_handle;
|
||||||
co_swap(co_active_handle = handle, co_previous_handle);
|
co_swap(co_active_handle = handle, co_previous_handle);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define ASM_PREFIX "_"
|
||||||
|
#else
|
||||||
|
#define ASM_PREFIX ""
|
||||||
|
#endif
|
||||||
|
__asm__(
|
||||||
|
".intel_syntax noprefix \n"
|
||||||
|
".globl " ASM_PREFIX "co_switch \n"
|
||||||
|
ASM_PREFIX "co_switch: \n"
|
||||||
|
"mov rsi, [rip+" ASM_PREFIX "co_active_handle]\n"
|
||||||
|
"mov [rsi],rsp \n"
|
||||||
|
"mov [rsi+0x08],rbp \n"
|
||||||
|
"mov [rsi+0x10],rbx \n"
|
||||||
|
"mov [rsi+0x18],r12 \n"
|
||||||
|
"mov [rsi+0x20],r13 \n"
|
||||||
|
"mov [rsi+0x28],r14 \n"
|
||||||
|
"mov [rsi+0x30],r15 \n"
|
||||||
|
"mov [rip+" ASM_PREFIX "co_active_handle], rdi\n"
|
||||||
|
"mov rsp,[rdi] \n"
|
||||||
|
"mov rbp,[rdi+0x08] \n"
|
||||||
|
"mov rbx,[rdi+0x10] \n"
|
||||||
|
"mov r12,[rdi+0x18] \n"
|
||||||
|
"mov r13,[rdi+0x20] \n"
|
||||||
|
"mov r14,[rdi+0x28] \n"
|
||||||
|
"mov r15,[rdi+0x30] \n"
|
||||||
|
"ret \n"
|
||||||
|
".att_syntax \n"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef IOS
|
#ifndef __APPLE__
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -23,6 +23,22 @@ static thread_local uint32_t co_active_buffer[64];
|
|||||||
static thread_local cothread_t co_active_handle;
|
static thread_local cothread_t co_active_handle;
|
||||||
|
|
||||||
asm (
|
asm (
|
||||||
|
#if defined(__thumb2__)
|
||||||
|
".thumb\n"
|
||||||
|
".align 2\n"
|
||||||
|
".globl co_switch_arm\n"
|
||||||
|
".globl _co_switch_arm\n"
|
||||||
|
"co_switch_arm:\n"
|
||||||
|
"_co_switch_arm:\n"
|
||||||
|
" mov r3, sp\n"
|
||||||
|
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11}\n"
|
||||||
|
" stmia r1!, {r3, lr}\n"
|
||||||
|
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11}\n"
|
||||||
|
" ldmfd r0!, { r3 }\n"
|
||||||
|
" mov sp, r3\n"
|
||||||
|
" ldmfd r0!, { r3 }\n"
|
||||||
|
" mov pc, r3\n"
|
||||||
|
#else
|
||||||
".arm\n"
|
".arm\n"
|
||||||
".align 4\n"
|
".align 4\n"
|
||||||
".globl co_switch_arm\n"
|
".globl co_switch_arm\n"
|
||||||
@@ -31,22 +47,17 @@ asm (
|
|||||||
"_co_switch_arm:\n"
|
"_co_switch_arm:\n"
|
||||||
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n"
|
" stmia r1!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, lr}\n"
|
||||||
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n"
|
" ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, sp, pc}\n"
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
/* ASM */
|
/* ASM */
|
||||||
void co_switch_arm(cothread_t handle, cothread_t current);
|
void co_switch_arm(cothread_t handle, cothread_t current);
|
||||||
|
|
||||||
static void crash(void)
|
|
||||||
{
|
|
||||||
/* Called only if cothread_t entrypoint returns. */
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
||||||
{
|
{
|
||||||
size = (size + 1023) & ~1023;
|
size = (size + 1023) & ~1023;
|
||||||
cothread_t handle = 0;
|
cothread_t handle = 0;
|
||||||
#if HAVE_POSIX_MEMALIGN >= 1
|
#if defined(__APPLE__) || HAVE_POSIX_MEMALIGN >= 1
|
||||||
if (posix_memalign(&handle, 1024, size + 256) < 0)
|
if (posix_memalign(&handle, 1024, size + 256) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
@@ -66,6 +77,7 @@ cothread_t co_create(unsigned int size, void (*entrypoint)(void))
|
|||||||
ptr[5] = 0; /* r9 */
|
ptr[5] = 0; /* r9 */
|
||||||
ptr[6] = 0; /* r10 */
|
ptr[6] = 0; /* r10 */
|
||||||
ptr[7] = 0; /* r11 */
|
ptr[7] = 0; /* r11 */
|
||||||
|
/* Align stack to 64-bit */
|
||||||
ptr[8] = (uintptr_t)ptr + size + 256 - 8; /* r13, stack pointer */
|
ptr[8] = (uintptr_t)ptr + size + 256 - 8; /* r13, stack pointer */
|
||||||
ptr[9] = (uintptr_t)entrypoint; /* r15, PC (link register r14 gets saved here). */
|
ptr[9] = (uintptr_t)entrypoint; /* r15, PC (link register r14 gets saved here). */
|
||||||
return handle;
|
return handle;
|
||||||
|
|||||||
@@ -26,7 +26,11 @@ cothread_t co_active(void)
|
|||||||
{
|
{
|
||||||
if(!co_active_)
|
if(!co_active_)
|
||||||
{
|
{
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
ConvertThreadToFiberEx(0, FIBER_FLAG_FLOAT_SWITCH);
|
||||||
|
#else
|
||||||
ConvertThreadToFiber(0);
|
ConvertThreadToFiber(0);
|
||||||
|
#endif
|
||||||
co_active_ = GetCurrentFiber();
|
co_active_ = GetCurrentFiber();
|
||||||
}
|
}
|
||||||
return co_active_;
|
return co_active_;
|
||||||
@@ -36,10 +40,19 @@ cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
|||||||
{
|
{
|
||||||
if(!co_active_)
|
if(!co_active_)
|
||||||
{
|
{
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
ConvertThreadToFiberEx(0, FIBER_FLAG_FLOAT_SWITCH);
|
||||||
|
#else
|
||||||
ConvertThreadToFiber(0);
|
ConvertThreadToFiber(0);
|
||||||
|
#endif
|
||||||
co_active_ = GetCurrentFiber();
|
co_active_ = GetCurrentFiber();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
|
return (cothread_t)CreateFiberEx(heapsize, heapsize, FIBER_FLAG_FLOAT_SWITCH, co_thunk, (void*)coentry);
|
||||||
|
#else
|
||||||
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void co_delete(cothread_t cothread)
|
void co_delete(cothread_t cothread)
|
||||||
|
|||||||
+25
-12
@@ -4,18 +4,31 @@
|
|||||||
license: public domain
|
license: public domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__i386__) || (defined(_MSC_VER) && defined(_M_IX86))
|
#if defined _MSC_VER
|
||||||
#include "x86.c"
|
#include <Windows.h>
|
||||||
#elif defined(__GNUC__) && defined(__amd64__) || (defined(_MSC_VER) && defined(_M_AMD64))
|
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||||
#include "amd64.c"
|
#include "fiber.c"
|
||||||
#elif defined(__GNUC__) && defined(_ARCH_PPC)
|
#elif defined _M_IX86
|
||||||
#include "ppc.c"
|
#include "x86.c"
|
||||||
#elif defined(__GNUC__) && (defined(__ARM_EABI__) || defined(__arm__))
|
#elif defined _M_AMD64
|
||||||
#include "armeabi.c"
|
#include "amd64.c"
|
||||||
#elif defined(__GNUC__)
|
#else
|
||||||
#include "sjlj.c"
|
#include "fiber.c"
|
||||||
#elif defined(_MSC_VER)
|
#endif
|
||||||
#include "fiber.c"
|
#elif defined __GNUC__
|
||||||
|
#if defined __i386__
|
||||||
|
#include "x86.c"
|
||||||
|
#elif defined __amd64__
|
||||||
|
#include "amd64.c"
|
||||||
|
#elif defined _ARCH_PPC
|
||||||
|
#include "ppc.c"
|
||||||
|
#elif defined VITA
|
||||||
|
#include "scefiber.c"
|
||||||
|
#elif defined(__ARM_EABI__) || defined(__arm__)
|
||||||
|
#include "armeabi.c"
|
||||||
|
#else
|
||||||
|
#include "sjlj.c"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error "libco: unsupported processor, compiler or operating system"
|
#error "libco: unsupported processor, compiler or operating system"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+60
-15
@@ -1,12 +1,30 @@
|
|||||||
/*
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
libco
|
*
|
||||||
version: 0.16 (2010-12-24)
|
* ---------------------------------------------------------------------------------------
|
||||||
license: public domain
|
* The following license statement only applies to this file (libco.h).
|
||||||
*/
|
* ---------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge,
|
||||||
|
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef LIBCO_H
|
#ifndef LIBCO_H
|
||||||
#define LIBCO_H
|
#define LIBCO_H
|
||||||
|
|
||||||
|
#include <retro_common_api.h>
|
||||||
|
|
||||||
#ifdef LIBCO_C
|
#ifdef LIBCO_C
|
||||||
#ifdef LIBCO_MP
|
#ifdef LIBCO_MP
|
||||||
#define thread_local __thread
|
#define thread_local __thread
|
||||||
@@ -15,20 +33,47 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
RETRO_BEGIN_DECLS
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void* cothread_t;
|
typedef void* cothread_t;
|
||||||
|
|
||||||
cothread_t co_active();
|
/**
|
||||||
cothread_t co_create(unsigned int, void (*)(void));
|
* co_active:
|
||||||
void co_delete(cothread_t);
|
*
|
||||||
void co_switch(cothread_t);
|
* Gets the currently active context.
|
||||||
|
*
|
||||||
|
* Returns: active context.
|
||||||
|
**/
|
||||||
|
cothread_t co_active(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/**
|
||||||
}
|
* co_create:
|
||||||
#endif
|
* @int : stack size
|
||||||
|
* @funcptr : thread entry function callback
|
||||||
|
*
|
||||||
|
* Create a co_thread.
|
||||||
|
*
|
||||||
|
* Returns: cothread if successful, otherwise NULL.
|
||||||
|
*/
|
||||||
|
cothread_t co_create(unsigned int, void (*)(void));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* co_delete:
|
||||||
|
* @cothread : cothread object
|
||||||
|
*
|
||||||
|
* Frees a co_thread.
|
||||||
|
*/
|
||||||
|
void co_delete(cothread_t cothread);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* co_switch:
|
||||||
|
* @cothread : cothread object to switch to
|
||||||
|
*
|
||||||
|
* Do a context switch to @cothread.
|
||||||
|
*/
|
||||||
|
void co_switch(cothread_t cothread);
|
||||||
|
|
||||||
|
RETRO_END_DECLS
|
||||||
|
|
||||||
/* ifndef LIBCO_H */
|
/* ifndef LIBCO_H */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
libco.arm (2015-06-18)
|
||||||
|
license: public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIBCO_C
|
||||||
|
#include "libco.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <psp2/kernel/sysmem.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define FOUR_KB_ALIGN(x) align(x, 12)
|
||||||
|
#define MB_ALIGN(x) align(x, 20)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int align(int x, int n)
|
||||||
|
{
|
||||||
|
return (((x >> n) + 1) << n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static thread_local unsigned long co_active_buffer[64];
|
||||||
|
static thread_local cothread_t co_active_handle = 0;
|
||||||
|
static void(*co_swap)(cothread_t, cothread_t) = 0;
|
||||||
|
static int block;
|
||||||
|
static uint32_t co_swap_function[] = {
|
||||||
|
0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */
|
||||||
|
0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */
|
||||||
|
0xe12fff1e, /* bx lr */
|
||||||
|
};
|
||||||
|
|
||||||
|
void co_init()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
block = sceKernelAllocMemBlockForVM("libco",
|
||||||
|
MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
|
||||||
|
if (block < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* get base address */
|
||||||
|
ret = sceKernelGetMemBlockBase(block, &base);
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set domain to be writable by user */
|
||||||
|
ret = sceKernelOpenVMDomain();
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(base, co_swap_function, sizeof co_swap_function);
|
||||||
|
|
||||||
|
/* set domain back to read-only */
|
||||||
|
ret = sceKernelCloseVMDomain();
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* flush icache */
|
||||||
|
ret = sceKernelSyncVMDomain(block, base,
|
||||||
|
MB_ALIGN(FOUR_KB_ALIGN(sizeof co_swap_function)));
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
co_swap = (void(*)(cothread_t, cothread_t))base;
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
unsigned long* handle = 0;
|
||||||
|
if (!co_swap)
|
||||||
|
co_init();
|
||||||
|
if (!co_active_handle) co_active_handle = &co_active_buffer;
|
||||||
|
size += 256;
|
||||||
|
size &= ~15;
|
||||||
|
|
||||||
|
if ((handle = (unsigned long*)malloc(size)))
|
||||||
|
{
|
||||||
|
unsigned long* p = (unsigned long*)((unsigned char*)handle + size);
|
||||||
|
handle[8] = (unsigned long)p;
|
||||||
|
handle[9] = (unsigned long)entrypoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_delete(cothread_t handle)
|
||||||
|
{
|
||||||
|
free(handle);
|
||||||
|
sceKernelFreeMemBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_switch(cothread_t handle)
|
||||||
|
{
|
||||||
|
cothread_t co_previous_handle = co_active_handle;
|
||||||
|
co_swap(co_active_handle = handle, co_previous_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/* Copyright (C) 2010-2017 The RetroArch team
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
* The following license statement only applies to this file (retro_common_api.h).
|
||||||
|
* ---------------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge,
|
||||||
|
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBRETRO_COMMON_RETRO_COMMON_API_H
|
||||||
|
#define _LIBRETRO_COMMON_RETRO_COMMON_API_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is designed to normalize the libretro-common compiling environment
|
||||||
|
for public API headers. This should be leaner than a normal compiling environment,
|
||||||
|
since it gets #included into other project's sources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ordinarily we want to put #ifdef __cplusplus extern "C" in C library
|
||||||
|
headers to enable them to get used by c++ sources.
|
||||||
|
However, we want to support building this library as C++ as well, so a
|
||||||
|
special technique is called for.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RETRO_BEGIN_DECLS
|
||||||
|
#define RETRO_END_DECLS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#ifdef CXX_BUILD
|
||||||
|
/* build wants everything to be built as c++, so no extern "C" */
|
||||||
|
#else
|
||||||
|
#undef RETRO_BEGIN_DECLS
|
||||||
|
#undef RETRO_END_DECLS
|
||||||
|
#define RETRO_BEGIN_DECLS extern "C" {
|
||||||
|
#define RETRO_END_DECLS }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* header is included by a C source file, so no extern "C" */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
IMO, this non-standard ssize_t should not be used.
|
||||||
|
However, it's a good example of how to handle something like this.
|
||||||
|
*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifndef HAVE_SSIZE_T
|
||||||
|
#define HAVE_SSIZE_T
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef __int64 ssize_t;
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
typedef int ssize_t;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#elif defined(__MACH__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define STRING_REP_INT64 "%I64d"
|
||||||
|
#define STRING_REP_UINT64 "%I64u"
|
||||||
|
#define STRING_REP_USIZE "%Iu"
|
||||||
|
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L && !defined(VITA) && !defined(WIIU)
|
||||||
|
#define STRING_REP_INT64 "%lld"
|
||||||
|
#define STRING_REP_UINT64 "%llu"
|
||||||
|
#define STRING_REP_USIZE "%zu"
|
||||||
|
#else
|
||||||
|
#define STRING_REP_INT64 "%lld"
|
||||||
|
#define STRING_REP_UINT64 "%llu"
|
||||||
|
#define STRING_REP_USIZE "%lu"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
I would like to see retro_inline.h moved in here; possibly boolean too.
|
||||||
|
|
||||||
|
rationale: these are used in public APIs, and it is easier to find problems
|
||||||
|
and write code that works the first time portably when theyre included uniformly
|
||||||
|
than to do the analysis from scratch each time you think you need it, for each feature.
|
||||||
|
|
||||||
|
Moreover it helps force you to make hard decisions: if you EVER bring in boolean.h,
|
||||||
|
then you should pay the price everywhere, so you can see how much grief it will cause.
|
||||||
|
|
||||||
|
Of course, another school of thought is that you should do as little damage as possible
|
||||||
|
in as few places as possible...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
libco.win (2016-09-06)
|
||||||
|
authors: frangarcj
|
||||||
|
license: public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIBCO_C
|
||||||
|
#include <libco.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <psp2/sysmodule.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static thread_local cothread_t co_active_ = 0;
|
||||||
|
|
||||||
|
typedef struct SceFiber {
|
||||||
|
char reserved[128];
|
||||||
|
} SceFiber __attribute__( ( aligned ( 8 ) ) ) ;
|
||||||
|
|
||||||
|
int32_t _sceFiberInitializeImpl(SceFiber* fiber, char* name, void* entry, uint32_t argOnInitialize, void* addrContext, int32_t sizeContext, void* params);
|
||||||
|
|
||||||
|
int32_t sceFiberFinalize(SceFiber* fiber);
|
||||||
|
|
||||||
|
int32_t sceFiberRun(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun);
|
||||||
|
|
||||||
|
int32_t sceFiberSwitch(SceFiber* fiber, uint32_t argOnRunTo, uint32_t* argOnRun);
|
||||||
|
|
||||||
|
int32_t sceFiberReturnToThread(uint32_t argOnReturn, uint32_t* argOnRun);
|
||||||
|
|
||||||
|
void co_thunk(uint32_t argOnInitialize, uint32_t argOnRun)
|
||||||
|
{
|
||||||
|
((void (*)(void))argOnInitialize)();
|
||||||
|
}
|
||||||
|
|
||||||
|
cothread_t co_active(void)
|
||||||
|
{
|
||||||
|
if(!co_active_)
|
||||||
|
{
|
||||||
|
sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER);
|
||||||
|
co_active_ = (cothread_t)1;
|
||||||
|
}
|
||||||
|
return co_active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
cothread_t co_create(unsigned int heapsize, void (*coentry)(void))
|
||||||
|
{
|
||||||
|
SceFiber* tailFiber = malloc(sizeof(SceFiber));
|
||||||
|
char * m_contextBuffer = malloc(sizeof(char)*heapsize);
|
||||||
|
if(!co_active_)
|
||||||
|
{
|
||||||
|
sceSysmoduleLoadModule(SCE_SYSMODULE_FIBER);
|
||||||
|
co_active_ = (cothread_t)1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//_sceFiberInitializeImpl
|
||||||
|
int ret = _sceFiberInitializeImpl(tailFiber, "tailFiber", co_thunk, (uint32_t)coentry, (void*) m_contextBuffer, heapsize, NULL);
|
||||||
|
if(ret==0){
|
||||||
|
return (cothread_t)tailFiber;
|
||||||
|
}else{
|
||||||
|
return (cothread_t)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_delete(cothread_t cothread)
|
||||||
|
{
|
||||||
|
if(cothread == (cothread_t)1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sceFiberFinalize((SceFiber*)cothread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void co_switch(cothread_t cothread)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t argOnReturn = 0;
|
||||||
|
if(cothread == (cothread_t)1){
|
||||||
|
co_active_ = cothread;
|
||||||
|
sceFiberReturnToThread(0, NULL);
|
||||||
|
}else{
|
||||||
|
SceFiber* theFiber = (SceFiber*)cothread;
|
||||||
|
if(co_active_ == (cothread_t)1){
|
||||||
|
co_active_ = cothread;
|
||||||
|
sceFiberRun(theFiber, 0, &argOnReturn);
|
||||||
|
}else{
|
||||||
|
co_active_ = cothread;
|
||||||
|
sceFiberSwitch(theFiber, 0, &argOnReturn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -53,12 +53,12 @@ cothread_t co_create(unsigned int size, void (*coentry)(void))
|
|||||||
|
|
||||||
if(thread)
|
if(thread)
|
||||||
{
|
{
|
||||||
struct sigaction handler;
|
|
||||||
struct sigaction old_handler;
|
|
||||||
|
|
||||||
stack_t stack;
|
stack_t stack;
|
||||||
stack_t old_stack;
|
stack_t old_stack;
|
||||||
|
|
||||||
|
struct sigaction handler = {{0}};
|
||||||
|
struct sigaction old_handler = {{0}};
|
||||||
|
|
||||||
thread->coentry = thread->stack = 0;
|
thread->coentry = thread->stack = 0;
|
||||||
|
|
||||||
stack.ss_flags = 0;
|
stack.ss_flags = 0;
|
||||||
@@ -68,7 +68,7 @@ cothread_t co_create(unsigned int size, void (*coentry)(void))
|
|||||||
if(stack.ss_sp && !sigaltstack(&stack, &old_stack))
|
if(stack.ss_sp && !sigaltstack(&stack, &old_stack))
|
||||||
{
|
{
|
||||||
handler.sa_handler = springboard;
|
handler.sa_handler = springboard;
|
||||||
handler.sa_flags = SA_ONSTACK;
|
handler.sa_flags = SA_ONSTACK;
|
||||||
sigemptyset(&handler.sa_mask);
|
sigemptyset(&handler.sa_mask);
|
||||||
creating = thread;
|
creating = thread;
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ cothread_t co_create(unsigned int size, void (*coentry)(void))
|
|||||||
|
|
||||||
void co_delete(cothread_t cothread)
|
void co_delete(cothread_t cothread)
|
||||||
{
|
{
|
||||||
if(cothread)
|
if (cothread)
|
||||||
{
|
{
|
||||||
if(((cothread_struct*)cothread)->stack)
|
if(((cothread_struct*)cothread)->stack)
|
||||||
free(((cothread_struct*)cothread)->stack);
|
free(((cothread_struct*)cothread)->stack);
|
||||||
@@ -103,7 +103,7 @@ void co_delete(cothread_t cothread)
|
|||||||
|
|
||||||
void co_switch(cothread_t cothread)
|
void co_switch(cothread_t cothread)
|
||||||
{
|
{
|
||||||
if(!sigsetjmp(co_running->context, 0))
|
if (!sigsetjmp(co_running->context, 0))
|
||||||
{
|
{
|
||||||
co_running = (cothread_struct*)cothread;
|
co_running = (cothread_struct*)cothread;
|
||||||
siglongjmp(co_running->context, 1);
|
siglongjmp(co_running->context, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user