diff --git a/aarch64.c b/aarch64.c index e153cd46..59162f20 100644 --- a/aarch64.c +++ b/aarch64.c @@ -59,6 +59,10 @@ static void co_init() { #endif } +const char* co_method() { + return "aarch64"; +} + cothread_t co_active() { if(!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; @@ -73,7 +77,8 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) if(!co_active_handle) co_active_handle = &co_active_buffer; if(handle = (unsigned long*)memory) { - unsigned long* p = (unsigned long*)((unsigned char*)handle + size); + unsigned int offset = (size & ~15); + unsigned long* p = (unsigned long*)((unsigned char*)handle + offset); handle[19] = (unsigned long)p; /* x29 (frame pointer) */ handle[20] = (unsigned long)p; /* x30 (stack pointer) */ handle[21] = (unsigned long)entrypoint; /* x31 (link register) */ @@ -83,23 +88,9 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) } cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { - unsigned long* 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 += 256; - size &= ~15; - - if(handle = (unsigned long*)malloc(size)) { - unsigned long* p = (unsigned long*)((unsigned char*)handle + size); - handle[19] = (unsigned long)p; /* x29 (frame pointer) */ - handle[20] = (unsigned long)p; /* x30 (stack pointer) */ - handle[21] = (unsigned long)entrypoint; /* x31 (link register) */ - } - - return handle; + void* memory = malloc(size); + if(!memory) return (cothread_t)0; + return co_derive(memory, size, entrypoint); } void co_delete(cothread_t handle) { diff --git a/amd64.c b/amd64.c index 664730a1..e9aef889 100644 --- a/amd64.c +++ b/amd64.c @@ -115,6 +115,10 @@ static void crash() { assert(0); /* called only if cothread_t entrypoint returns */ } +const char* co_method() { + return "amd64"; +} + cothread_t co_active() { if(!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; @@ -140,22 +144,9 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) } 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; - - if(handle = (cothread_t)malloc(size)) { - unsigned int offset = (size & ~15) - 32; - long long *p = (long long*)((char*)handle + offset); /* 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* memory = malloc(size); + if(!memory) return (cothread_t)0; + return co_derive(memory, size, entrypoint); } void co_delete(cothread_t handle) { diff --git a/arm.c b/arm.c index 20c95310..8d872bf5 100644 --- a/arm.c +++ b/arm.c @@ -35,6 +35,10 @@ static void co_init() { #endif } +const char* co_method() { + return "arm"; +} + cothread_t co_active() { if(!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; @@ -49,7 +53,8 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) if(!co_active_handle) co_active_handle = &co_active_buffer; if(handle = (unsigned long*)memory) { - unsigned long* p = (unsigned long*)((unsigned char*)handle + size); + unsigned int offset = (size & ~15); + unsigned long* p = (unsigned long*)((unsigned char*)handle + offset); handle[8] = (unsigned long)p; handle[9] = (unsigned long)entrypoint; } @@ -58,22 +63,9 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) } cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { - unsigned long* 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 += 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* memory = malloc(size); + if(!memory) return (cothread_t)0; + return co_derive(memory, size, entrypoint); } void co_delete(cothread_t handle) { diff --git a/fiber.c b/fiber.c index bdf4dd4e..f508b0f8 100644 --- a/fiber.c +++ b/fiber.c @@ -16,6 +16,10 @@ static void __stdcall co_thunk(void* coentry) { ((void (*)(void))coentry)(); } +const char* co_method() { + return "fiber"; +} + cothread_t co_active() { if(!co_active_) { ConvertThreadToFiber(0); diff --git a/libco.c b/libco.c index f9c79bf4..21fe4cab 100644 --- a/libco.c +++ b/libco.c @@ -1,7 +1,7 @@ #if defined(__clang__) #pragma clang diagnostic ignored "-Wparentheses" - //placing code in section(text) does not mark it executable with Clang. + /* placing code in section(text) does not mark it executable with Clang. */ #undef LIBCO_MPROTECT #define LIBCO_MPROTECT #endif diff --git a/libco.h b/libco.h index a436957c..0b94c2e9 100644 --- a/libco.h +++ b/libco.h @@ -1,5 +1,5 @@ /* - libco v20 (2019-10-14) + libco v20 (2019-10-16) author: byuu license: ISC */ @@ -13,6 +13,7 @@ extern "C" { typedef void* cothread_t; +const char* co_method(); cothread_t co_active(); cothread_t co_derive(void*, unsigned int, void (*)(void)); cothread_t co_create(unsigned int, void (*)(void)); diff --git a/ppc.c b/ppc.c index 969fcec2..314997c8 100644 --- a/ppc.c +++ b/ppc.c @@ -413,6 +413,10 @@ static void co_init_(void) { co_active_handle = co_create_(state_size, (uintptr_t)&co_switch); } +const char* co_method() { + return "ppc"; +} + cothread_t co_active() { if(!co_active_handle) co_init_(); diff --git a/ppc64v2.c b/ppc64v2.c index b1f153d4..fac464a6 100644 --- a/ppc64v2.c +++ b/ppc64v2.c @@ -221,6 +221,10 @@ __asm__( ".size swap_context, .-swap_context\n" ); +const char* co_method() { + return "ppc64v2"; +} + cothread_t co_active() { if(!co_active_handle) { co_active_handle = (struct ppc64_context*)malloc(MIN_STACK + sizeof(struct ppc64_context)); @@ -255,11 +259,9 @@ cothread_t co_derive(void* memory, unsigned int size, void (*coentry)(void)) { } cothread_t co_create(unsigned int size, void (*coentry)(void)) { - size_t total = MAX(size, MIN_STACK) + sizeof(struct ppc64_context); - void* memory = malloc(total); - + void* memory = malloc(size); if(!memory) return (cothread_t)0; - return co_derive(memory, total, coentry); + return co_derive(memory, size, coentry); } void co_delete(cothread_t handle) { diff --git a/sjlj.c b/sjlj.c index d99572a3..b4faf17b 100644 --- a/sjlj.c +++ b/sjlj.c @@ -33,6 +33,10 @@ static void springboard(int ignored) { } } +const char* co_method() { + return "sjlj"; +} + cothread_t co_active() { if(!co_running) co_running = &co_primary; return (cothread_t)co_running; diff --git a/ucontext.c b/ucontext.c index edf513d4..49fa976c 100644 --- a/ucontext.c +++ b/ucontext.c @@ -26,6 +26,10 @@ extern "C" { static thread_local ucontext_t co_primary; static thread_local ucontext_t* co_running = 0; +const char* co_module() { + return "ucontext"; +} + cothread_t co_active() { if(!co_running) co_running = &co_primary; return (cothread_t)co_running; diff --git a/x86.c b/x86.c index 3eb2e21e..8effa0d4 100644 --- a/x86.c +++ b/x86.c @@ -69,6 +69,10 @@ static void crash() { assert(0); /* called only if cothread_t entrypoint returns */ } +const char* co_method() { + return "x86"; +} + cothread_t co_active() { if(!co_active_handle) co_active_handle = &co_active_buffer; return co_active_handle; @@ -94,22 +98,9 @@ cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) } 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; - - if(handle = (cothread_t)malloc(size)) { - unsigned int offset = (size & ~15) - 32; - long *p = (long*)((char*)handle + offset); /* 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* memory = malloc(size); + if(!memory) return (cothread_t)0; + return co_derive(memory, size, entrypoint); } void co_delete(cothread_t handle) {