From d8c19f378757d7b13f04611ebd0902a7e1c72587 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Fri, 9 Jun 2017 19:54:20 -0400 Subject: [PATCH] waterbox libco (not yet tested) --- waterbox/libco/Makefile | 46 ++++++++++++++ waterbox/libco/amd64.c | 58 +++++++++++++++++ waterbox/libco/coswap.s | 53 ++++++++++++++++ waterbox/libco/doc/style.css | 8 +++ waterbox/libco/doc/targets.html | 89 ++++++++++++++++++++++++++ waterbox/libco/doc/usage.html | 107 ++++++++++++++++++++++++++++++++ waterbox/libco/libco.h | 26 ++++++++ waterbox/libco/libco.so | Bin 0 -> 6158 bytes 8 files changed, 387 insertions(+) create mode 100644 waterbox/libco/Makefile create mode 100644 waterbox/libco/amd64.c create mode 100644 waterbox/libco/coswap.s create mode 100644 waterbox/libco/doc/style.css create mode 100644 waterbox/libco/doc/targets.html create mode 100644 waterbox/libco/doc/usage.html create mode 100644 waterbox/libco/libco.h create mode 100644 waterbox/libco/libco.so diff --git a/waterbox/libco/Makefile b/waterbox/libco/Makefile new file mode 100644 index 0000000000..82e3f337b8 --- /dev/null +++ b/waterbox/libco/Makefile @@ -0,0 +1,46 @@ +CC = x86_64-nt64-midipix-gcc +AS = nasm + +CCFLAGS:= -Wall -O3 +ASFLAGS:= -f elf64 + +TARGET = libco.so + +LDFLAGS = -shared + +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c') +ASRCS:=$(shell find $(ROOT_DIR) -type f -name '*.s') + +OBJ_DIR:=$(ROOT_DIR)/obj + +_OBJS:=$(SRCS:.c=.c.o) +OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS)) +_AOBJS:=$(ASRCS:.s=.s.o) +AOBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_AOBJS)) + +$(OBJ_DIR)/%.c.o: %.c + @mkdir -p $(@D) + $(CC) -c -o $@ $< $(CCFLAGS) + +$(OBJ_DIR)/%.s.o: %.s + @mkdir -p $(@D) + $(AS) $(ASFLAGS) -o $@ $< + +all: $(TARGET) + +.PHONY: clean all + +$(TARGET).in : $(OBJS) $(AOBJS) + $(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) $(AOBJS) + +$(TARGET): $(TARGET).in + strip $< -o $@ -R /4 -R /14 -R /29 -R /41 -R /55 -R /67 -R /78 -R /89 -R /104 + +clean: + rm -rf $(OBJ_DIR) + rm -f $(TARGET).in + rm -f $(TARGET) + +#install: +# $(CP) $(TARGET) $(DEST_$(ARCH)) diff --git a/waterbox/libco/amd64.c b/waterbox/libco/amd64.c new file mode 100644 index 0000000000..5af2246e03 --- /dev/null +++ b/waterbox/libco/amd64.c @@ -0,0 +1,58 @@ +/* + libco.amd64 (2016-09-14) + author: byuu + license: public domain +*/ + +#define LIBCO_C +#include "libco.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static long long co_active_buffer[64]; +static cothread_t co_active_handle = 0; + +extern void co_swap(cothread_t, cothread_t); + +static void crash() { + assert(0); /* called only if cothread_t entrypoint returns */ +} + +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)) { + cothread_t handle; + if(!co_active_handle) co_active_handle = &co_active_buffer; + size += 512; /* allocate additional space for storage */ + size &= ~15; /* align stack to 16-byte boundary */ + + if(handle = (cothread_t)malloc(size)) { + long long *p = (long long*)((char*)handle + size); /* 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 co_delete(cothread_t handle) { + free(handle); +} + +void co_switch(cothread_t handle) { + register cothread_t co_previous_handle = co_active_handle; + co_swap(co_active_handle = handle, co_previous_handle); +} + +#ifdef __cplusplus +} +#endif diff --git a/waterbox/libco/coswap.s b/waterbox/libco/coswap.s new file mode 100644 index 0000000000..6f48858b0c --- /dev/null +++ b/waterbox/libco/coswap.s @@ -0,0 +1,53 @@ +section .text + global co_swap + global __imp_co_swap + +align 16 +co_swap: +__imp_co_swap: + mov [rdx],rsp + mov rsp,[rcx] + pop rax + mov [rdx+ 8],rbp + mov [rdx+16],rsi + mov [rdx+24],rdi + mov [rdx+32],rbx + mov [rdx+40],r12 + mov [rdx+48],r13 + mov [rdx+56],r14 + mov [rdx+64],r15 +;#if !defined(LIBCO_NO_SSE) + movaps [rdx+ 80],xmm6 + movaps [rdx+ 96],xmm7 + movaps [rdx+112],xmm8 + add rdx,112 + movaps [rdx+ 16],xmm9 + movaps [rdx+ 32],xmm10 + movaps [rdx+ 48],xmm11 + movaps [rdx+ 64],xmm12 + movaps [rdx+ 80],xmm13 + movaps [rdx+ 96],xmm14 + movaps [rdx+112],xmm15 +;#endif + mov rbp,[rcx+ 8] + mov rsi,[rcx+16] + mov rdi,[rcx+24] + mov rbx,[rcx+32] + mov r12,[rcx+40] + mov r13,[rcx+48] + mov r14,[rcx+56] + mov r15,[rcx+64] +;#if !defined(LIBCO_NO_SSE) + movaps xmm6, [rcx+ 80] + movaps xmm7, [rcx+ 96] + movaps xmm8, [rcx+112] + add rcx,112 + movaps xmm9, [rcx+ 16] + movaps xmm10,[rcx+ 32] + movaps xmm11,[rcx+ 48] + movaps xmm12,[rcx+ 64] + movaps xmm13,[rcx+ 80] + movaps xmm14,[rcx+ 96] + movaps xmm15,[rcx+112] +;#endif + jmp rax diff --git a/waterbox/libco/doc/style.css b/waterbox/libco/doc/style.css new file mode 100644 index 0000000000..5181afde6c --- /dev/null +++ b/waterbox/libco/doc/style.css @@ -0,0 +1,8 @@ +body { + background: #333; + color: #fff; +} + +code { + background: #444; +} diff --git a/waterbox/libco/doc/targets.html b/waterbox/libco/doc/targets.html new file mode 100644 index 0000000000..d6211a15d7 --- /dev/null +++ b/waterbox/libco/doc/targets.html @@ -0,0 +1,89 @@ + + + + + + + +Supported targets:

+ +Note that supported targets are only those that have been tested and confirmed +working. It is quite possible that libco will work on more processors, compilers +and operating systems than those listed below. +
+ +libco.x86
+Overhead: ~5x
+Supported processor(s): 32-bit x86
+Supported compiler(s): any
+Supported operating system(s):
    +
  • Windows
  • +
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
+
+ +libco.amd64
+Overhead: ~10x (Windows), ~6x (all other platforms)
+Supported processor(s): 64-bit amd64
+Supported compiler(s): any
+Supported operating system(s):
    +
  • Windows
  • +
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
+
+ +libco.ppc
+Overhead: ~20x
+Supported processor(s): 32-bit PowerPC, 64-bit PowerPC
+Supported compiler(s): GNU GCC
+Supported operating system(s):
    +
+
  • Mac OS X
  • +
  • Linux
  • +
  • BSD
  • +
  • Playstation 3
  • + +
    + +Note: this module contains compiler flags to enable/disable FPU and Altivec +support. + +
    + +libco.fiber
    +Overhead: ~15x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Windows
    • +
    +
    + +libco.sjlj
    +Overhead: ~30x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Mac OS X
    • +
    • Linux
    • +
    • BSD
    • +
    • Solaris
    • +
    +
    + +libco.ucontext
    +Overhead: ~300x
    +Supported processor(s): Processor independent
    +Supported compiler(s): any
    +Supported operating system(s):
      +
    • Linux
    • +
    • BSD
    • +
    +
    + + + diff --git a/waterbox/libco/doc/usage.html b/waterbox/libco/doc/usage.html new file mode 100644 index 0000000000..3f0d81ccd8 --- /dev/null +++ b/waterbox/libco/doc/usage.html @@ -0,0 +1,107 @@ + + + + + + + +License:

    +libco is released to the public domain. +
    + +Contact:

    +At present, you may contact me at setsunakun0 at hotmail dot com.
    +I am interested in knowing of any projects that make use of this library, +though this is only a courtesy. +
    + +Foreword:

    +libco is a cross-platform, public domain implementation of +cooperative-multithreading; a feature that is sorely lacking +from the ISO C/C++ standard.
    +The library is designed for maximum speed and portability, and +not for safety or features. If safety or extra functionality is desired, +a wrapper API can easily be written to encapsulate all library functions.
    +Behavior of executing operations that are listed as not permitted +below result in undefined behavior. They may work anyway, they +may cause undesired / unknown behavior, or they may crash the +program entirely.
    +The goal of this library was to simplify the base API as much as possible, +implementing only that which cannot be implemented using pure C. Additional +functionality after this would only complicate ports of this library to new +platforms. +
    + +Porting:

    +This document is included as a reference for porting libco. Please submit any +ports you create to me, so that libco can become more useful. Please note that +since libco is public domain, you must submit your code as a work of the +public domain in order for it to be included in the official distribution. +Full credit will be given in the source code of the official release. Please +do not bother submitting code to me under any other license -- including GPL, +LGPL, BSD or CC -- I am not interested in creating a library with multiple +different licenses depending on which targets are used. +
    + +Synopsis:

    + +typedef void* cothread_t;
    +
    +cothread_t co_active();
    +cothread_t co_create(unsigned int heapsize, void (*coentry)(void));
    +void       co_delete(cothread_t cothread);
    +void       co_switch(cothread_t cothread);
    +
    +
    + +Usage: +
    + +typedef void* cothread_t;

    +Handle to cothread.
    +Handle must be of type void*.
    +A value of null (0) indicates an uninitialized or invalid +handle, whereas a non-zero value indicates a valid handle. +
    + +cothread_t co_active();

    +Return handle to current cothread. Always returns a valid handle, even when +called from the main program thread. +
    + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void));

    +Create new cothread.
    +Heapsize is the amount of memory allocated for the cothread stack, specified +in bytes. This is unfortunately impossible to make fully portable. It is +recommended to specify sizes using `n * sizeof(void*)'. It is better to err +on the side of caution and allocate more memory than will be needed to ensure +compatibility with other platforms, within reason. A typical heapsize for a +32-bit architecture is ~1MB.
    +When the new cothread is first called, program execution jumps to coentry. +This function does not take any arguments, due to portability issues with +passing function arguments. However, arguments can be simulated by the use +of global variables, which can be set before the first call to each cothread.
    +coentry() must not return, and should end with an appropriate co_switch() +statement. Behavior is undefined if entry point returns normally.
    +Library is responsible for allocating cothread stack memory, to free +the user from needing to allocate special memory capable of being used +as program stack memory on platforms where this is required.
    +User is always responsible for deleting cothreads with co_delete().
    +Return value of null (0) indicates cothread creation failed. +
    + +void co_delete(cothread_t cothread);

    +Delete specified cothread.
    +Null (0) or invalid cothread handle is not allowed.
    +Passing handle of active cothread to this function is not allowed.
    +Passing handle of primary cothread is not allowed. +
    + +void co_switch(cothread_t cothread);

    +Switch to specified cothread.
    +Null (0) or invalid cothread handle is not allowed.
    +Passing handle of active cothread to this function is not allowed. +
    + + + diff --git a/waterbox/libco/libco.h b/waterbox/libco/libco.h new file mode 100644 index 0000000000..792df0bd24 --- /dev/null +++ b/waterbox/libco/libco.h @@ -0,0 +1,26 @@ +/* + libco v18 (2016-09-14) + author: byuu + license: public domain +*/ + +#ifndef LIBCO_H +#define LIBCO_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* cothread_t; + +cothread_t co_active(); +cothread_t co_create(unsigned int, void (*)(void)); +void co_delete(cothread_t); +void co_switch(cothread_t); + +#ifdef __cplusplus +} +#endif + +/* ifndef LIBCO_H */ +#endif diff --git a/waterbox/libco/libco.so b/waterbox/libco/libco.so new file mode 100644 index 0000000000000000000000000000000000000000..f88632c0199dec8614b9311e91792fa38a0ad936 GIT binary patch literal 6158 zcmeHL-D@0G6hFI3+HITtP+HxhkV&yH1sS(7iCeTVDG_gF#kCQ!Rm{%r&Nfq$>}Ge> zBrgWG6^A9d4?ffvnLj|Vs1L;#x7|L7PzVS@-vYiU=|jL55n=qDnLEu|r7EQ+fj#8h z^Yz#ef=4M_x*P=cm>Ib_n(N#z$-5c*ctRNg4`Z`8m?YlXAHI%tI{OXKVQ!3T+ z`KmFe6pZ=#a$U)rO7-n|#hO-~jROJ(9{DTZURh7dh^De;(2sazxK< zSwvTe)NcD<>cSyX?t#_n=3*W3%@77&8}B{X98@NSvN>(eDq0n5F~>Ls%(y+^F48I0 z)~ZFLZpb-P2r@3x1%j$mR@cs#d0I;Ipo1B=AKXRAr$067J1(=xf*Ci+#un+M>srO1 z*Q;3$F~-HVFsyMtZPCX)&W;M0alG#?@^JZDja@p&S6KTitx&G5nSMU+8n%F8Jl{KA zRzUMgwvA+OQ|{4G3?;!?Zb|4XOT5~~A0vuzJt zhv>9kn-Y!Ns%V`2f*)I9|4=`<`Uw}a@#ChjZ@GuQ|H%LKVa)ZO>$)P;5q1r+sb587 zBO&ahXxvcWc&k&24^0BPI$->l>lG+3CNP{) zFq}(a$mz2)6^1yb@nwc^Wb^10UK^OTdaE#;b&_dRbf!H%dvaP$c+ zpP|sA5_)WKZ^S{fOkj0U za6j}MWE&iT&hk6(LFj9cKY^3bd$jv2z~>^5_w-TtR47F`Y4856^>*+dE0AsZ*PhSp z%qr|OSb+7!R!`s_@FsjEa0R>!=3jYugpg|b#FYt}p!%F{-nZoOl&R;Zdr-P4NZ ztm$jDcddG%cgE!EZ5OG|*36fo^LMJhqZ#R6lyXJN0Q*nzC{0frwVGM2PnQg9mJall zs-{Vl@1HYfy)P}u#5pDNeT3TxjvhVG3Ml@WEajw~w)3rnk6PrN!JLSbaFUMVs7}gx XpeyJl-^L2?_Y}>XnJ(dry-9xnS~q+3 literal 0 HcmV?d00001