aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--compile_commands.json48
-rw-r--r--include/u.h14
-rw-r--r--rules.mk8
-rw-r--r--src/coro.c15
-rw-r--r--src/coro_unix_x64.s39
-rw-r--r--src/rules.mk14
-rw-r--r--src/test.c103
8 files changed, 209 insertions, 36 deletions
diff --git a/Makefile b/Makefile
index 9c1307b..f276d13 100644
--- a/Makefile
+++ b/Makefile
@@ -22,8 +22,8 @@ TGTLIBS :=
# Named generic rules (must be evaluated lazily)
COMPILE = $(CC) -MMD $(CFLAGS) $(TGTFLAGS) $(INCS) $(TGTINCS) -o $@ -c $<
LINK = $(CC) -MMD $(CFLAGS) $(TGTFLAGS) -o $@ $^ $(LIBS) $(TGTLIBS)
-COMPLINK = $(CC) -MMD $(CFLAGS) $(TGTFLAGS) $(INCS) $(TGTINCS) -o $@ $< $(LIBS)
+COMPLINK = $(CC) -MMD $(CFLAGS) $(TGTFLAGS) $(INCS) $(TGTINCS) -o $@ $^ $(LIBS)
ASSEMBLE = $(AS) $(AFLAGS) $(TGTFLAGS) -o $@ $<
-ARCHIVE = $(AR) -crs $@ $^
+ARCHIVE = $(AR) crs $@ $^
include rules.mk
diff --git a/compile_commands.json b/compile_commands.json
index c012748..bc87fa4 100644
--- a/compile_commands.json
+++ b/compile_commands.json
@@ -9,6 +9,54 @@
"-fms-extensions",
"-Iinclude",
"-o",
+ "build/string.o",
+ "src/string.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "src/string.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Iinclude",
+ "-o",
+ "build/memory.o",
+ "src/memory.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "src/memory.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Iinclude",
+ "-o",
+ "build/coro.o",
+ "src/coro.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "src/coro.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Iinclude",
+ "-o",
"build/error.o",
"src/error.c"
],
diff --git a/include/u.h b/include/u.h
index b7bd9ca..c03d545 100644
--- a/include/u.h
+++ b/include/u.h
@@ -51,6 +51,8 @@ typedef intptr_t intptr;
typedef int error;
+typedef void* Iface;
+
#define nil NULL
// ----------------------------------------------------------------------------
@@ -90,9 +92,9 @@ void _bufpop(void*, int, vlong);
typedef struct coro coro;
-coro* coro·new(uintptr stk, uintptr (*func)(coro* c, uintptr));
-uintptr coro·yield(coro* c, uintptr arg);
-error coro·free(coro* c);
+coro* coro·new(uintptr stk, uintptr (*func)(coro*, uintptr));
+uintptr coro·yield(coro *c, uintptr arg);
+error coro·free(coro *c);
// -----------------------------------------------------------------------------
// Strings
@@ -107,10 +109,10 @@ error coro·free(coro* c);
// ------------------------------------------------------------------
// Global macros
-#ifndef RELEASE
-#define Assert(x) assert(x)
-#else
+#ifdef RELEASE
#define Assert(x)
+#else
+#define Assert(x) assert(x)
#endif
#define arrlen(Array) (sizeof(Array) / sizeof((Array)[0]))
diff --git a/rules.mk b/rules.mk
index 7a0d8b6..1737cb2 100644
--- a/rules.mk
+++ b/rules.mk
@@ -1,7 +1,7 @@
# Standard housekeeping
.PHONY: all clean install
.SUFFIXES:
-.SUFFIXES: .c .o
+.SUFFIXES: .s .c .o
all: targets
@@ -39,8 +39,10 @@ targets: $(LIBS) $(BINS)
.PHONY: clean
clean:
- rm $(OBJS) $(DEPS)
- rm $(LIBS) $(BINS)
+ rm -f $(OBJS)
+ rm -f $(DEPS)
+ rm -f $(LIBS)
+ rm -f $(BINS)
.PHONY: install
install: targets
diff --git a/src/coro.c b/src/coro.c
index 82ef4f4..af0a359 100644
--- a/src/coro.c
+++ b/src/coro.c
@@ -1,11 +1,20 @@
#include <u.h>
// -----------------------------------------------------------------------
-// Assembly routines.
+// Assembly routines
extern void _newcoro(coro *co, uintptr (*func)(coro*, uintptr), void *stk);
extern uintptr _coroyield(coro *co, uintptr arg);
+// -----------------------------------------------------------------------
+// Globals
+
+// static thread_local coro *CONTEXT;
+
+// -----------------------------------------------------------------------
+// C interface
+
+/* Co-routine context */
struct coro
{
void* sp;
@@ -17,9 +26,7 @@ struct coro
coro*
coro·new(uintptr stk, uintptr (*func)(coro*, uintptr))
{
- if (!func)
- return nil;
-
+ if (!func) return nil;
if (stk == 0) stk = 8192;
byte *block = malloc(stk);
diff --git a/src/coro_unix_x64.s b/src/coro_unix_x64.s
index 98710c2..d7de2a2 100644
--- a/src/coro_unix_x64.s
+++ b/src/coro_unix_x64.s
@@ -36,9 +36,9 @@ rerun:
; func(R7, R6, R2, R1, R8, R9, Z0-7): R0
;
; # Stack layout of an in-flight coro
-; ^coro
-; ^func
-; ^bp (base pointer of stack)
+; *coro
+; *func
+; *bp (base pointer of stack)
; ....... STACK .........
; Saved Clobbers
;
@@ -57,31 +57,33 @@ rerun:
; R14 [1]
; R15 [0]
-%define WORDS 8
-%define SAVES 9
+%define WORDSZ 8
+%define NSAVES 9
-; func sys.newCoro(co ^coro, fn func, bp ^stack)
+; coro *coro·new(co *coro, fn func, bp *stack)
_newcoro:
- lea R0, [coroinit]
- lea R1, [R2 - SAVES*WORDS]
+ lea R0, [coroinit] ; Store address of init function
+ lea R1, [R2 - NSAVES*WORDSZ] ; Store offset address of stack
- mov [R1 + 8*WORDS], R7
- mov [R1 + 7*WORDS], R6
- mov [R1 + 6*WORDS], R0
- mov [R1 + 5*WORDS], R2
+ mov [R1 + 8*WORDSZ], R7 ; Store context pointer
+ mov [R1 + 7*WORDSZ], R6 ; Store function pointer
+ mov [R1 + 6*WORDSZ], R0 ; Store initializer pointer
+ mov [R1 + 5*WORDSZ], R2 ; Store stack base pointer
xor R0, R0
+ ; Start of mutable stack
; Blank out the clobbers
- mov [R1 + 4*WORDS], R0 ; R3
- mov [R1 + 3*WORDS], R0 ; R12
- mov [R1 + 2*WORDS], R0 ; R13
- mov [R1 + 1*WORDS], R0 ; R14
- mov [R1 + 0*WORDS], R0 ; R15
+ mov [R1 + 4*WORDSZ], R0 ; R3
+ mov [R1 + 3*WORDSZ], R0 ; R12
+ mov [R1 + 2*WORDSZ], R0 ; R13
+ mov [R1 + 1*WORDSZ], R0 ; R14
+ mov [R1 + 0*WORDSZ], R0 ; R15
mov [R7], R1
ret
+; Saves register state
%macro pushclobs 0
push RBP
push R3
@@ -91,6 +93,7 @@ _newcoro:
push R15
%endmacro
+; Restores register state
%macro popclobs 0
pop R15
pop R14
@@ -100,7 +103,7 @@ _newcoro:
pop RBP
%endmacro
-; func coro.yield(co ^coro, ret uintptr)
+; uintptr coro.yield(co *coro, data uintptr)
_coroyield:
pushclobs
mov R0, R6 ; Move return value into return register.
diff --git a/src/rules.mk b/src/rules.mk
index ef9b36c..b9efc37 100644
--- a/src/rules.mk
+++ b/src/rules.mk
@@ -4,9 +4,11 @@ DIRSTACK_$(SP) := $(d)
d := $(DIR)
# Iterate through subdirectory tree
+DIR := $(d)/bufio
+include $(DIR)/rules.mk
# ...
-# Local variables
+# Local sources
SRCS_$(d) := $(wildcard $(d)/*.c)
ASMS_$(d) := $(wildcard $(d)/*.s)
OBJS_$(d) := $(SRCS_$(d):.c=.o)
@@ -17,11 +19,14 @@ DEPS_$(d) := $(OBJS_$(d):.o=.d)
OBJS := $(OBJS) $(OBJS_$(d))
DEPS := $(DEPS) $(DEPS_$(d))
+# Local targets
LIBS_$(d) := $(d)/libnbn.a
LIBS_$(d) := $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(LIBS_$(d)))
-BINS_$(d) :=
+LIBS := $(LIBS) $(LIBS_$(d))
-LIBS := $(LIBS) $(LIBS_$(d))
+BINS_$(d) := $(d)/test
+BINS_$(d) := $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(BINS_$(d)))
+BINS := $(BINS) $(BINS_$(d))
# Local rules
# $(LIBS_$(d)) := TGTFLAGS :=
@@ -31,6 +36,9 @@ LIBS := $(LIBS) $(LIBS_$(d))
$(LIBS_$(d)): $(OBJS_$(d))
$(ARCHIVE)
+$(BINS_$(d)): $(OBJ_DIR)/test.o
+ $(LINK)
+
# ---- Pop off stack ----
-include $(DEPS_$(d))
diff --git a/src/test.c b/src/test.c
new file mode 100644
index 0000000..e9743cb
--- /dev/null
+++ b/src/test.c
@@ -0,0 +1,103 @@
+#include <u.h>
+
+uintptr
+printtest(coro *c, uintptr d)
+{
+ printf("--> Recieved %lu\n", d);
+ d = coro·yield(c, d+10);
+ printf("--> Now %lu\n", d);
+
+ return d;
+}
+
+uintptr
+sequence(coro *c, uintptr start)
+{
+ int d = start;
+ for (;;) {
+ coro·yield(c, d++);
+ }
+
+ return d;
+}
+
+struct PrimeMsg
+{
+ coro *seq;
+ int p;
+};
+
+uintptr
+filter(coro *c, uintptr data)
+{
+ int x, p;
+ coro *seq;
+ struct PrimeMsg *msg;
+
+ msg = (struct PrimeMsg*)data;
+ seq = msg->seq;
+ p = msg->p;
+
+ for (;;) {
+ x = coro·yield(seq, x);
+ if (x % p != 0) {
+ x = coro·yield(c, x);
+ }
+ }
+
+ return 0;
+}
+
+int
+main()
+{
+ int i;
+ coro *c[4];
+ uintptr d;
+
+ printf("Starting singleton test\n");
+
+ for (i = 0; i < arrlen(c); i++) {
+ c[i] = coro·new(0, &printtest);
+ }
+
+ /* Singleton test */
+ d = 0;
+ for (i = 0; i < 10; i++) {
+ d = coro·yield(c[0], d);
+ }
+
+ printf("Starting triplet test\n");
+
+ /* Triplet test */
+ for (i = 0; i < 10; i++) {
+ d = coro·yield(c[1], d);
+ d = coro·yield(c[2], d+100);
+ d = coro·yield(c[3], d+200);
+ }
+
+ for (i = 0; i < arrlen(c); i++) {
+ coro·free(c[i]);
+ }
+
+ /* Prime sieve */
+ printf("Starting prime test\n");
+ uintptr num;
+ coro *cur, *seq[50];
+
+ num = 2;
+ seq[0] = coro·new(4096, &sequence);
+ cur = *seq;
+
+ num = coro·yield(cur, num);
+ for (i = 1; i < arrlen(seq); i++) {
+ seq[i] = coro·new(4096, &filter);
+ struct PrimeMsg msg = {
+ .seq = cur,
+ .p = num,
+ };
+ cur = seq[i];
+ num = coro·yield(cur, (uintptr)&msg);
+ printf("--> prime number %lu\n", num);
+ }
+}