summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/monkey/deps/flb_libco/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/monkey/deps/flb_libco/arm.c')
-rw-r--r--fluent-bit/lib/monkey/deps/flb_libco/arm.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/fluent-bit/lib/monkey/deps/flb_libco/arm.c b/fluent-bit/lib/monkey/deps/flb_libco/arm.c
new file mode 100644
index 000000000..1bd8c043d
--- /dev/null
+++ b/fluent-bit/lib/monkey/deps/flb_libco/arm.c
@@ -0,0 +1,81 @@
+/*
+ libco.arm (2016-09-14)
+ author: byuu
+ license: public domain
+*/
+
+#define LIBCO_C
+#include "libco.h"
+#include "settings.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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;
+
+#ifdef LIBCO_MPROTECT
+ alignas(4096)
+#else
+ text_section
+#endif
+static const unsigned long co_swap_function[1024] = {
+ 0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */
+ 0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */
+ 0xe12fff1e, /* bx lr */
+};
+
+static void co_init() {
+ #ifdef LIBCO_MPROTECT
+ 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_EXEC);
+ #endif
+}
+
+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),
+ size_t *out_size) {
+ unsigned long* handle = 0;
+ 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;
+ *out_size = size;
+
+ 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);
+}
+
+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