waterbox libco (not yet tested)
This commit is contained in:
parent
59a2b58275
commit
d8c19f3787
|
@ -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))
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
libco.amd64 (2016-09-14)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#define LIBCO_C
|
||||
#include "libco.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
body {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
code {
|
||||
background: #444;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<link href="style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<b>Supported targets:</b><br/><br/>
|
||||
|
||||
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.
|
||||
<hr/>
|
||||
|
||||
<b>libco.x86</b><br/>
|
||||
Overhead: ~5x<br/>
|
||||
Supported processor(s): 32-bit x86<br/>
|
||||
Supported compiler(s): any<br/>
|
||||
Supported operating system(s):<ul>
|
||||
<li>Windows</li>
|
||||
<li>Mac OS X</li>
|
||||
<li>Linux</li>
|
||||
<li>BSD</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
<b>libco.amd64</b><br/>
|
||||
Overhead: ~10x (Windows), ~6x (all other platforms)<br/>
|
||||
Supported processor(s): 64-bit amd64<br/>
|
||||
Supported compiler(s): any<br/>
|
||||
Supported operating system(s):<ul>
|
||||
<li>Windows</li>
|
||||
<li>Mac OS X</li>
|
||||
<li>Linux</li>
|
||||
<li>BSD</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
<b>libco.ppc</b><br/>
|
||||
Overhead: ~20x<br/>
|
||||
Supported processor(s): 32-bit PowerPC, 64-bit PowerPC<br/>
|
||||
Supported compiler(s): GNU GCC<br/>
|
||||
Supported operating system(s):<ul>
|
||||
</ul>
|
||||
<li>Mac OS X</li>
|
||||
<li>Linux</li>
|
||||
<li>BSD</li>
|
||||
<li>Playstation 3</li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
Note: this module contains compiler flags to enable/disable FPU and Altivec
|
||||
support.
|
||||
|
||||
<hr/>
|
||||
|
||||
<b>libco.fiber</b><br/>
|
||||
Overhead: ~15x<br/>
|
||||
Supported processor(s): Processor independent<br/>
|
||||
Supported compiler(s): any<br/>
|
||||
Supported operating system(s):<ul>
|
||||
<li>Windows</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
<b>libco.sjlj</b><br/>
|
||||
Overhead: ~30x<br/>
|
||||
Supported processor(s): Processor independent<br/>
|
||||
Supported compiler(s): any<br/>
|
||||
Supported operating system(s):<ul>
|
||||
<li>Mac OS X</li>
|
||||
<li>Linux</li>
|
||||
<li>BSD</li>
|
||||
<li>Solaris</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
<b>libco.ucontext</b><br/>
|
||||
Overhead: <b><font color="#ff0000">~300x</font></b><br/>
|
||||
Supported processor(s): Processor independent<br/>
|
||||
Supported compiler(s): any<br/>
|
||||
Supported operating system(s):<ul>
|
||||
<li>Linux</li>
|
||||
<li>BSD</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,107 @@
|
|||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<link href="style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<b>License:</b><br/><br/>
|
||||
libco is released to the public domain.
|
||||
<hr/>
|
||||
|
||||
<b>Contact:</b><br/><br/>
|
||||
At present, you may contact me at setsunakun0 at hotmail dot com.<br/>
|
||||
I am interested in knowing of any projects that make use of this library,
|
||||
though this is only a courtesy.
|
||||
<hr/>
|
||||
|
||||
<b>Foreword:</b><br/><br/>
|
||||
libco is a cross-platform, public domain implementation of
|
||||
cooperative-multithreading; a feature that is sorely lacking
|
||||
from the ISO C/C++ standard.<br/>
|
||||
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.<br/>
|
||||
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.<br/>
|
||||
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.
|
||||
<hr/>
|
||||
|
||||
<b>Porting:</b><br/><br/>
|
||||
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.
|
||||
<hr/>
|
||||
|
||||
<b>Synopsis:</b><br/><br/>
|
||||
<code>
|
||||
typedef void* cothread_t;<br/>
|
||||
<br/>
|
||||
cothread_t co_active();<br/>
|
||||
cothread_t co_create(unsigned int heapsize, void (*coentry)(void));<br/>
|
||||
void co_delete(cothread_t cothread);<br/>
|
||||
void co_switch(cothread_t cothread);<br/>
|
||||
</code>
|
||||
<hr/>
|
||||
|
||||
<b>Usage:</b>
|
||||
<hr/>
|
||||
|
||||
<code>typedef void* cothread_t;</code><br/><br/>
|
||||
Handle to cothread.<br/>
|
||||
Handle must be of type void*.<br/>
|
||||
A value of null (0) indicates an uninitialized or invalid
|
||||
handle, whereas a non-zero value indicates a valid handle.
|
||||
<hr/>
|
||||
|
||||
<code>cothread_t co_active();</code><br/><br/>
|
||||
Return handle to current cothread. Always returns a valid handle, even when
|
||||
called from the main program thread.
|
||||
<hr/>
|
||||
|
||||
<code>cothread_t co_create(unsigned int heapsize, void (*coentry)(void));</code><br/><br/>
|
||||
Create new cothread.<br/>
|
||||
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.<br/>
|
||||
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.<br/>
|
||||
coentry() must not return, and should end with an appropriate co_switch()
|
||||
statement. Behavior is undefined if entry point returns normally.<br/>
|
||||
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.<br/>
|
||||
User is always responsible for deleting cothreads with co_delete().<br/>
|
||||
Return value of null (0) indicates cothread creation failed.
|
||||
<hr/>
|
||||
|
||||
<code>void co_delete(cothread_t cothread);</code><br/><br/>
|
||||
Delete specified cothread.<br/>
|
||||
Null (0) or invalid cothread handle is not allowed.<br/>
|
||||
Passing handle of active cothread to this function is not allowed.<br/>
|
||||
Passing handle of primary cothread is not allowed.
|
||||
<hr/>
|
||||
|
||||
<code>void co_switch(cothread_t cothread);</code><br/><br/>
|
||||
Switch to specified cothread.<br/>
|
||||
Null (0) or invalid cothread handle is not allowed.<br/>
|
||||
Passing handle of active cothread to this function is not allowed.
|
||||
<hr/>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
Binary file not shown.
Loading…
Reference in New Issue