diff options
Diffstat (limited to 'src/fluent-bit/lib/monkey/deps/flb_libco/ucontext.c')
-rw-r--r-- | src/fluent-bit/lib/monkey/deps/flb_libco/ucontext.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/fluent-bit/lib/monkey/deps/flb_libco/ucontext.c b/src/fluent-bit/lib/monkey/deps/flb_libco/ucontext.c new file mode 100644 index 000000000..b252cb2d8 --- /dev/null +++ b/src/fluent-bit/lib/monkey/deps/flb_libco/ucontext.c @@ -0,0 +1,72 @@ +/* + libco.ucontext (2008-01-28) + author: Nach + license: public domain +*/ + +/* + WARNING: the overhead of POSIX ucontext is very high, + assembly versions of libco or libco_sjlj should be much faster + + this library only exists for two reasons: + 1: as an initial test for the viability of a ucontext implementation + 2: to demonstrate the power and speed of libco over existing implementations, + such as pth (which defaults to wrapping ucontext on unix targets) + + use this library only as a *last resort* +*/ + +#define LIBCO_C +#include "libco.h" +#include "settings.h" + +#define _BSD_SOURCE +#include <stdlib.h> +#include <ucontext.h> + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local ucontext_t co_primary; +static thread_local ucontext_t* co_running = 0; + +cothread_t co_active() { + if(!co_running) co_running = &co_primary; + return (cothread_t)co_running; +} + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void), + size_t *out_size) { + if(!co_running) co_running = &co_primary; + ucontext_t* thread = (ucontext_t*)malloc(sizeof(ucontext_t)); + if(thread) { + if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { + thread->uc_link = co_running; + thread->uc_stack.ss_size = heapsize; + *out_size = heapsize; + makecontext(thread, coentry, 0); + } else { + co_delete((cothread_t)thread); + thread = 0; + } + } + return (cothread_t)thread; +} + +void co_delete(cothread_t cothread) { + if(cothread) { + if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); } + free(cothread); + } +} + +void co_switch(cothread_t cothread) { + ucontext_t* old_thread = co_running; + co_running = (ucontext_t*)cothread; + swapcontext(old_thread, co_running); +} + +#ifdef __cplusplus +} +#endif |