update libco

This commit is contained in:
Not6
2017-10-15 20:21:24 +02:00
parent e11b43cbed
commit fc862fbfcc
9 changed files with 476 additions and 69 deletions
+35 -28
View File
@@ -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
} }
+20 -8
View File
@@ -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;
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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
+113
View File
@@ -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
+108
View File
@@ -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
+96
View File
@@ -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
+6 -6
View File
@@ -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);