From 43ecfce7d20360a5fdc53e5ced266eccc8723242 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Fri, 29 May 2020 14:41:05 -0700 Subject: blas code update --- include/libmath.h | 17 +++++-- include/libmath/blas.h | 46 ++++++++++-------- include/libn.h | 38 +++++++-------- include/u.h | 1 + rules.mk | 2 +- sys/cmd/rules.mk | 3 ++ sys/libmath/blas.c | 29 +++++++---- sys/libmath/blas1.c | 7 ++- sys/libmath/loop.h | 127 +++++++++++++++++++++++++++++++++++++++---------- sys/libmath/rules.mk | 4 +- sys/libn/error.c | 56 +++++++++++++++++++++- sys/libn/memory.c | 20 ++++++++ sys/libn/string.c | 22 ++++++--- 13 files changed, 278 insertions(+), 94 deletions(-) diff --git a/include/libmath.h b/include/libmath.h index 40ae4ee..c605d24 100644 --- a/include/libmath.h +++ b/include/libmath.h @@ -134,17 +134,26 @@ float math·truncf(float); typedef struct math·Vector { - double *data; + double *d; int len; + int inc; } math·Vector; -#define math·slicev(vec, lo, hi) (struct math·Vector){.len=((hi)-(lo)), .data=((vec).data + (lo))} +#define iota(x) 1 << (x) +enum +{ + mat·trans = iota(1), + mat·symm = iota(2), + mat·posdef = iota(3), + mat·negdef = iota(4), +}; typedef struct math·Matrix { - double *data; - uint32 kind; + double *d; + uint state; int dim[2]; + int inc; } math·Matrix; // TODO: tensor ala numpy diff --git a/include/libmath/blas.h b/include/libmath/blas.h index 83acb2c..b8930a8 100644 --- a/include/libmath/blas.h +++ b/include/libmath/blas.h @@ -10,8 +10,6 @@ enum blas·LeftSide = 16u, }; -typedef uint32 blas·Flag; - /* * Floats */ @@ -31,17 +29,21 @@ int blas·fargmax(int len, float *x, int inc); int blas·fargmin(int len, float *x, int inc); // level 2 -void blas·tpmvf(blas·Flag f, int n, float *m, float *x); -error blas·gemvf(int nrow, int ncol, float a, float *m, int incm, float *x, int incx, float b, float *y, int incy) ; -void blas·tpsvf(blas·Flag f, int n, float *m, float *x); -void blas·gerf(int nrow, int ncol, float a, float *x, int incx, float *y, int incy, float *m, int incm); -void blas·herf(int n, float a, float *x, float *m); -void blas·syrf(int nrow, int ncol, float a, float *x, float *m); +error blas·fgemv(uint f, int nrow, int ncol, float a, float *m, int incm, float *x, int incx, float b, float *y, int incy); +void blas·fsymv(uint f, int n, float a, float* m, int incm, float *x, int incx, float b, float *y, int incy); +void blas·fspmv(uint f, int n, float a, float* m, float *x, int incx, float b, float *y, int incm); +void blas·ftrmv(uint f, int n, float* m, int incm, float *x, int incx); +void blas·ftpmv(uint f, int n, float *m, float *x, int incx); +void blas·ftrsv(uint f, int n, float *m, int incm, float *x, int incx); +void blas·ftpsv(uint f, int n, float *m, float *x, int incx); +void blas·fger(int nrow, int ncol, float a, float *x, int incx, float *y, int incy, float *m, int incm); +void blas·fsyr(uint f, int n, float a, float *x, int incx, float *m, int incm); +void blas·fspr(uint f, int n, float a, float *x, int incx, float *m); // level 3 -void blas·gemmf(int n1, int n2, int n3, float a, float *m1, float *m2, float b, float *m3); -void blas·trmmf(blas·Flag f, int nrow, int ncol, float a, float *m1, float *m2); -void blas·trsmf(blas·Flag f, int nrow, int ncol, float a, float *m1, float *m2); +void blas·fgemm(uint tr1, uint tr2, int n1, int n2, int n3, float a, float *m1, int inc1, float *m2, int inc2, float b, float *m3, int inc3); +void blas·ftrmm(uint f, int nrow, int ncol, float a, float *m1, float *m2); +void blas·ftrsm(uint f, int nrow, int ncol, float a, float *m1, float *m2); /* * Doubles @@ -62,17 +64,21 @@ int blas·dargmax(int len, double *x, int inc); int blas·dargmin(int len, double *x, int inc); // level 2 -void blas·tpmvd(blas·Flag f, int n, double *m, double *x); -error blas·gemvd(int nrow, int ncol, double a, double *m, int incm, double *x, int incx, double b, double *y, int incy) ; -void blas·tpsvd(blas·Flag f, int n, double *m, double *x); -void blas·gerd(int nrow, int ncol, double a, double *x, int incx, double *y, int incy, double *m, int incm); -void blas·herd(int n, double a, double *x, double *m); -void blas·syrd(int nrow, int ncol, double a, double *x, double *m); +error blas·dgemv(uint f, int nrow, int ncol, double a, double *m, int incm, double *x, int incx, double b, double *y, int incy); +void blas·dsymv(uint f, int n, double a, double* m, int incm, double *x, int incx, double b, double *y, int incy); +void blas·dspmv(uint f, int n, double a, double* m, double *x, int incx, double b, double *y, int incy); +void blas·dtrmv(uint f, int n, double *m, int incm, double *x, int incx); +void blas·dtpmv(uint f, int n, double *m, double *x, int incx); +void blas·dtrsv(uint f, int n, double *m, int incm, double *x, int incx); +void blas·dtpsv(uint f, int n, double *m, double *x, int incx); +void blas·dger(int nrow, int ncol, double a, double *x, int incx, double *y, int incy, double *m, int incm); +void blas·dsyr(uint flag, int n, double a, double *x, int incx, double *m, int incm); +void blas·dspr(uint flag, int n, double a, double *x, int incx, double *m); // level 3 -void blas·gemmd(int n1, int n2, int n3, double a, double *m1, double *m2, double b, double *m3); -void blas·trmmd(blas·Flag f, int nrow, int ncol, double a, double *m1, double *m2); -void blas·trsmd(blas·Flag f, int nrow, int ncol, double a, double *m1, double *m2); +void blas·dgemm(uint tr1, uint tr2, int n1, int n2, int n3, double a, double *m1, int inc1, double *m2, int inc2, double b, double *m3, int inc3); +void blas·dtrmm(uint f, int nrow, int ncol, double a, double *m1, double *m2); +void blas·dtrsm(uint f, int nrow, int ncol, double a, double *m1, double *m2); /* * TODO: Complex diff --git a/include/libn.h b/include/libn.h index 835d2c1..721defd 100644 --- a/include/libn.h +++ b/include/libn.h @@ -65,21 +65,17 @@ typedef struct mem·Allocator { void (*free)(void *iface, void *ptr); } mem·Allocator; -/* system implementation */ -static -void ·free(void* _, void* ptr) { - return free(ptr); -} - -static -void *·alloc(void* _, uint n, ulong size) { - return malloc(n*size); -} +typedef struct mem·Reallocator { + void *(*alloc)(void *iface, uint n, ulong size); + void *(*realloc)(void *iface, void *ptr, uint n, ulong size); + void (*free)(void *iface, void *ptr); +} mem·Reallocator; -static -void *·calloc(void* _, uint n, ulong size) { - return calloc(n, size); -} +/* system implementation */ +extern void ·free(void* _, void *ptr); +extern void *·alloc(void* _, uint n, ulong size); +extern void *·calloc(void* _, uint n, ulong size); +extern void *·realloc(void* _, void *ptr, uint n, ulong size); // TODO(nnoll): Allow for nil iterfaces? static @@ -123,10 +119,10 @@ int str·cap(const string s); void str·clear(string *s); void str·grow(string *s, vlong delta); void str·fit(string *s); -void str·appendlen(string *s, vlong len, const byte *b); -void str·append(string *s, const byte* b); -void str·appendf(string *s, const byte* fmt, ...); -void str·appendbyte(string *s, const byte b); +int str·appendlen(string *s, vlong len, const byte *b); +int str·append(string *s, const byte* b); +int str·appendf(string *s, const byte* fmt, ...); +int str·appendbyte(string *s, const byte b); bool str·equals(const string s, const string t); int str·find(string s, const byte* substr); void str·lower(string s); @@ -344,9 +340,9 @@ vlong gz·seek(gz·Stream *s, long off, enum SeekPos whence); // ----------------------------------------------------------------------------- // error handling functions -void errorf(const byte* fmt, ...); - -#define panicf(...) (errorf(__VA_ARGS__), assert(0)) +void errorf(byte* fmt, ...); +void panicf(byte *fmt, ...); +void vpanicf(byte *fmt, va_list args); // ----------------------------------------------------------------------------- // sorting diff --git a/include/u.h b/include/u.h index 3fafcda..8044fe0 100644 --- a/include/u.h +++ b/include/u.h @@ -51,6 +51,7 @@ typedef int error; #endif #define arrlen(Array) (sizeof(Array) / sizeof((Array)[0])) +#define arrend(Array) ((Array) + arrlen(Array)) #define MAX(x, y) ((x) >= (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) diff --git a/rules.mk b/rules.mk index eea0dcb..43fe31b 100644 --- a/rules.mk +++ b/rules.mk @@ -7,7 +7,7 @@ all: targets debug: CFLAGS += -DDEBUG debug: targets -release: CFLAGS += -O3 -flto -ffast-math #-DNDEBUG +release: CFLAGS += -O3 -mtune=native -flto -ffast-math #-DNDEBUG release: targets # Targets & array of sources & intermediates diff --git a/sys/cmd/rules.mk b/sys/cmd/rules.mk index 81c1cbe..6e4a3cb 100644 --- a/sys/cmd/rules.mk +++ b/sys/cmd/rules.mk @@ -8,6 +8,9 @@ include $(DIR)/rules.mk # DIR := $(d)/cc # include $(DIR)/rules.mk +DIR := $(d)/edo +include $(DIR)/rules.mk + DIR := $(d)/rc include $(DIR)/rules.mk diff --git a/sys/libmath/blas.c b/sys/libmath/blas.c index 224480b..4c9e67b 100644 --- a/sys/libmath/blas.c +++ b/sys/libmath/blas.c @@ -6,38 +6,47 @@ #include -#define NCOL 20000 -#define NROW 20000 -#define NIT 2000 +#define NCOL 2*512 +#define NROW 2*512 +#define NSUM 2*512 +#define NIT 10 #define INC 1 error main() { int i, j, nit; - double *x, *y, res[2]; + double *x, *y, *z, *w, res[2]; clock_t t; double tprof[2] = { 0 }; rng·init(0); - x = malloc(sizeof(*x)*NCOL); - y = malloc(sizeof(*x)*NROW); + x = malloc(sizeof(*x)*NROW*NCOL); + y = malloc(sizeof(*x)*NROW*NCOL); + z = malloc(sizeof(*x)*NROW*NCOL); + w = malloc(sizeof(*x)*NROW*NCOL); #define DO_0 t = clock(); \ - res[0] += blas·dasum(NROW/INC, x, INC); \ + blas·dgemm(0,0,NROW,NCOL,NSUM,10.1,x,NROW,y,NROW,1.2,z,NROW);\ t = clock() - t; \ + res[0] += blas·dasum(NROW*NCOL,z,INC); \ tprof[0] += 1000.*t/CLOCKS_PER_SEC; \ #define DO_1 t = clock(); \ - res[1] += cblas_dasum(NROW/INC, x, INC); \ + cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,NROW,NCOL,NSUM,10.1,x,NROW,y,NROW,1.2,w,NROW);\ t = clock() - t; \ + res[1] += cblas_dasum(NROW*NCOL,w,INC); \ tprof[1] += 1000.*t/CLOCKS_PER_SEC; for (nit = 0; nit < NIT; nit++) { for (i = 0; i < NROW; i++) { - x[i] = rng·random(); - y[i] = rng·random(); + for (j = 0; j < NCOL; j++) { + x[j + NROW*i] = rng·random(); + y[j + NROW*i] = rng·random(); + z[j + NROW*i] = rng·random(); + w[j + NROW*i] = z[j + NROW*i]; + } } switch (nit % 2) { diff --git a/sys/libmath/blas1.c b/sys/libmath/blas1.c index d9792f6..a8ca085 100644 --- a/sys/libmath/blas1.c +++ b/sys/libmath/blas1.c @@ -1,9 +1,6 @@ #include #include -#define UNROLL 8 -#define INT uintptr - // ----------------------------------------------------------------------- // Templates @@ -45,10 +42,12 @@ // ----------------------------------------------------------------------- // Implementation +#define UNROLL 8 +#define INT int + #define FLOAT double #define func(name) blas·d##name #include "blas1body" -#undef FLOAT #undef FLOAT #undef func diff --git a/sys/libmath/loop.h b/sys/libmath/loop.h index 9a425a7..a877d84 100644 --- a/sys/libmath/loop.h +++ b/sys/libmath/loop.h @@ -1,37 +1,114 @@ #pragma once +/* increment operator */ +#define INC2(x) INC_##x +#define INC1(x) INC2(x) +#define INC(x) INC1(x) + +#define INC_0 1 +#define INC_1 2 +#define INC_2 3 +#define INC_3 4 +#define INC_4 5 +#define INC_5 6 +#define INC_6 7 +#define INC_7 8 +#define INC_8 9 +#define INC_9 10 +#define INC_10 11 +#define INC_11 12 +#define INC_12 13 +#define INC_13 14 +#define INC_14 15 +#define INC_15 16 + +#define ROUNDBY(x, n) ((x) & ~((n)-1)) + +/* subtraction tables */ +#define SUB2(x, y) SUB_##x##_##y +#define SUB1(x, y) SUB2(x, y) +#define SUB(x, y) SUB1(x, y) +#define SUB_8_0 8 +#define SUB_8_1 7 +#define SUB_8_2 6 +#define SUB_8_3 5 +#define SUB_8_4 4 +#define SUB_8_5 3 +#define SUB_8_6 2 +#define SUB_8_7 1 +#define SUB_8_8 0 +#define SUB_7_0 7 +#define SUB_7_1 6 +#define SUB_7_2 5 +#define SUB_7_3 4 +#define SUB_7_4 3 +#define SUB_7_5 2 +#define SUB_7_6 1 +#define SUB_7_7 0 +#define SUB_6_0 6 +#define SUB_6_1 5 +#define SUB_6_2 4 +#define SUB_6_3 3 +#define SUB_6_4 2 +#define SUB_6_5 1 +#define SUB_6_6 0 +#define SUB_5_0 5 +#define SUB_5_1 4 +#define SUB_5_2 3 +#define SUB_5_3 2 +#define SUB_5_4 1 +#define SUB_5_5 0 +#define SUB_4_0 4 +#define SUB_4_1 3 +#define SUB_4_2 2 +#define SUB_4_3 1 +#define SUB_4_4 0 +#define SUB_3_0 3 +#define SUB_3_1 2 +#define SUB_3_2 1 +#define SUB_3_3 0 +#define SUB_2_0 2 +#define SUB_2_1 1 +#define SUB_2_2 0 +#define SUB_1_0 1 +#define SUB_1_1 0 + +/* rounding operator */ #define ROUNDBY(x, n) ((x) & ~((n)-1)) /* loop unrolling (vertical) */ #define LOOP1(I,STMT,...) STMT(I,__VA_ARGS__) -#define LOOP2(I,STMT,...) STMT(I,__VA_ARGS__) LOOP1((I+1),STMT,__VA_ARGS__) -#define LOOP3(I,STMT,...) STMT(I,__VA_ARGS__) LOOP2((I+1),STMT,__VA_ARGS__) -#define LOOP4(I,STMT,...) STMT(I,__VA_ARGS__) LOOP3((I+1),STMT,__VA_ARGS__) -#define LOOP5(I,STMT,...) STMT(I,__VA_ARGS__) LOOP4((I+1),STMT,__VA_ARGS__) -#define LOOP6(I,STMT,...) STMT(I,__VA_ARGS__) LOOP5((I+1),STMT,__VA_ARGS__) -#define LOOP7(I,STMT,...) STMT(I,__VA_ARGS__) LOOP6((I+1),STMT,__VA_ARGS__) -#define LOOP8(I,STMT,...) STMT(I,__VA_ARGS__) LOOP7((I+1),STMT,__VA_ARGS__) -#define LOOP9(I,STMT,...) STMT(I,__VA_ARGS__) LOOP8((I+1),STMT,__VA_ARGS__) -#define LOOP10(I,STMT,...) STMT(I,__VA_ARGS__) LOOP9((I+1),STMT,__VA_ARGS__) -#define LOOP11(I,STMT,...) STMT(I,__VA_ARGS__) LOOP10((I+1),STMT,__VA_ARGS__) -#define LOOP12(I,STMT,...) STMT(I,__VA_ARGS__) LOOP11((I+1),STMT,__VA_ARGS__) -#define LOOP13(I,STMT,...) STMT(I,__VA_ARGS__) LOOP12((I+1),STMT,__VA_ARGS__) -#define LOOP14(I,STMT,...) STMT(I,__VA_ARGS__) LOOP13((I+1),STMT,__VA_ARGS__) -#define LOOP15(I,STMT,...) STMT(I,__VA_ARGS__) LOOP14((I+1),STMT,__VA_ARGS__) -#define LOOP16(I,STMT,...) STMT(I,__VA_ARGS__) LOOP15((I+1),STMT,__VA_ARGS__) +#define LOOP2(I,STMT,...) STMT(I,__VA_ARGS__) LOOP1(INC(I),STMT,__VA_ARGS__) +#define LOOP3(I,STMT,...) STMT(I,__VA_ARGS__) LOOP2(INC(I),STMT,__VA_ARGS__) +#define LOOP4(I,STMT,...) STMT(I,__VA_ARGS__) LOOP3(INC(I),STMT,__VA_ARGS__) +#define LOOP5(I,STMT,...) STMT(I,__VA_ARGS__) LOOP4(INC(I),STMT,__VA_ARGS__) +#define LOOP6(I,STMT,...) STMT(I,__VA_ARGS__) LOOP5(INC(I),STMT,__VA_ARGS__) +#define LOOP7(I,STMT,...) STMT(I,__VA_ARGS__) LOOP6(INC(I),STMT,__VA_ARGS__) +#define LOOP8(I,STMT,...) STMT(I,__VA_ARGS__) LOOP7(INC(I),STMT,__VA_ARGS__) +#define LOOP9(I,STMT,...) STMT(I,__VA_ARGS__) LOOP8(INC(I),STMT,__VA_ARGS__) +#define LOOP10(I,STMT,...) STMT(I,__VA_ARGS__) LOOP9(INC(I),STMT,__VA_ARGS__) +#define LOOP11(I,STMT,...) STMT(I,__VA_ARGS__) LOOP10(INC(I),STMT,__VA_ARGS__) +#define LOOP12(I,STMT,...) STMT(I,__VA_ARGS__) LOOP11(INC(I),STMT,__VA_ARGS__) +#define LOOP13(I,STMT,...) STMT(I,__VA_ARGS__) LOOP12(INC(I),STMT,__VA_ARGS__) +#define LOOP14(I,STMT,...) STMT(I,__VA_ARGS__) LOOP13(INC(I),STMT,__VA_ARGS__) +#define LOOP15(I,STMT,...) STMT(I,__VA_ARGS__) LOOP14(INC(I),STMT,__VA_ARGS__) +#define LOOP16(I,STMT,...) STMT(I,__VA_ARGS__) LOOP15(INC(I),STMT,__VA_ARGS__) #define _LOOP_(n,I,STMT,...) LOOP##n(I,STMT,__VA_ARGS__) #define LOOP(n,I,STMT,...) _LOOP_(n,I,STMT,__VA_ARGS__) /* loop expansion (horizontal) */ +#define EXPAND0(I,TERM,OP,...) #define EXPAND1(I,TERM,OP,...) TERM(I,__VA_ARGS__) -#define EXPAND2(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND1((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND3(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND2((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND4(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND3((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND5(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND4((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND6(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND5((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND7(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND6((I+1),TERM,OP,__VA_ARGS__) -#define EXPAND8(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND7((I+1),TERM,OP,__VA_ARGS__) - -#define _EXPAND_(n,I,TERM,OP,...) EXPAND##n(I,TERM,OP,__VA_ARGS__) -#define EXPAND(n,I,TERM,OP, ...) _EXPAND_(n,I,TERM,OP,__VA_ARGS__) +#define EXPAND2(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND1(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND3(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND2(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND4(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND3(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND5(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND4(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND6(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND5(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND7(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND6(INC(I),TERM,OP,__VA_ARGS__) +#define EXPAND8(I,TERM,OP,...) TERM(I,__VA_ARGS__) OP EXPAND7(INC(I),TERM,OP,__VA_ARGS__) + +#define _EXPAND_(n,I,TERM,OP,...) EXPAND##n(I,TERM,OP,__VA_ARGS__) +#define EXPAND(n,I,TERM,OP,...) _EXPAND_(n,I,TERM,OP,__VA_ARGS__) +#define EXPAND_TRI1(n,I,TERM,OP,...) EXPAND(n,I,TERM,OP,__VA_ARGS__) +#define EXPAND_TRI(n,I,TERM,OP,...) EXPAND_TRI1(SUB(n,I),I,TERM,OP,__VA_ARGS__) diff --git a/sys/libmath/rules.mk b/sys/libmath/rules.mk index fddd74a..9e44ce4 100644 --- a/sys/libmath/rules.mk +++ b/sys/libmath/rules.mk @@ -5,7 +5,9 @@ include share/push.mk # Local sources SRCS_$(d) := \ $(d)/basic.c \ - $(d)/blas1.c + $(d)/blas1.c \ + $(d)/blas2.c \ + $(d)/blas3.c LIBS_$(d) := $(d)/libmath.a BINS_$(d) := TSTS_$(d) := \ diff --git a/sys/libn/error.c b/sys/libn/error.c index 15611a3..9b6a28a 100644 --- a/sys/libn/error.c +++ b/sys/libn/error.c @@ -2,7 +2,7 @@ #include void -errorf(const byte* fmt, ...) +errorf(byte* fmt, ...) { va_list args; va_start(args, fmt); @@ -13,3 +13,57 @@ errorf(const byte* fmt, ...) va_end(args); } + +void +panicf(byte* fmt, ...) +{ + int n; + va_list args; + static byte buf[4*1024]; + va_start(args, fmt); + + buf[0] = 'p'; + buf[1] = 'a'; + buf[2] = 'n'; + buf[3] = 'i'; + buf[4] = 'c'; + buf[5] = ':'; + buf[6] = ' '; + n = vsnprintf(buf+7, arrlen(buf)-8, fmt, args); + if (n < 0) + return; + buf[n] = 0; + + perror(buf); + va_end(args); + + /* TODO: portable stack unwinding */ + exit(1); +} + +void +vpanicf(byte* fmt, va_list args) +{ + int n; + va_list nargs; + static byte buf[4*1024]; + va_copy(nargs, args); + + buf[0] = 'p'; + buf[1] = 'a'; + buf[2] = 'n'; + buf[3] = 'i'; + buf[4] = 'c'; + buf[5] = ':'; + buf[6] = ' '; + n = vsnprintf(buf+7, arrlen(buf)-8, fmt, args); + if (n < 0) + return; + buf[n] = 0; + + perror(buf); + va_end(nargs); + + /* TODO: portable stack unwinding */ + exit(1); +} diff --git a/sys/libn/memory.c b/sys/libn/memory.c index dce0c36..7993ca2 100644 --- a/sys/libn/memory.c +++ b/sys/libn/memory.c @@ -1,6 +1,26 @@ #include #include +void +·free(void* _, void* ptr) { + return free(ptr); +} + +void * +·alloc(void* _, uint n, ulong size) { + return malloc(n*size); +} + +void * +·calloc(void* _, uint n, ulong size) { + return calloc(n, size); +} + +void * +·realloc(void* _, void *ptr, uint n, ulong size) { + return realloc(ptr, n*size); +} + // ------------------------------------------------------------------------- // Dynamic buffer. diff --git a/sys/libn/string.c b/sys/libn/string.c index 7c152e3..e2cdddf 100644 --- a/sys/libn/string.c +++ b/sys/libn/string.c @@ -349,25 +349,29 @@ str·fit(string *s) // structure. This variant can append a substring of length len of the given // string to our buffer. The result is reallocated if not enough room is present // in the buffer. -void +int str·appendlen(string *s, vlong n, const byte* b) { - vlong bl = strlen(b); + /* + bl = strlen(b); if (n > bl) panicf("attempted to make a substring longer than string"); + */ str·grow(s, n); - if (*s == nil) return; + if (*s == nil) return 0; Hdr* h = (Hdr*)(*s - sizeof(Hdr)); memcpy(*s + str·len(*s), b, n); h->len += n; (*s)[h->len] = '\0'; + + return n; } // Append will append the given null terminated C string to the string data // structure. This variant will append the entire string. -void +int str·append(string *s, const byte* b) { return str·appendlen(s, strlen(b), b); @@ -376,17 +380,19 @@ str·append(string *s, const byte* b) // AppendByte will append the given byte to our string. // NOTE: As the byte is on the stack, it is not null-terminated. // Can not pass to the above functions. -void +int str·appendbyte(string *s, const byte b) { str·grow(s, 1); - if (*s == nil) return; + if (*s == nil) return 0; Hdr* h = (Hdr*)(*s - sizeof(Hdr)); *(*s + str·len(*s)) = b; h->len++; (*s)[h->len] = '\0'; // NOTE: I don't think an explicit zero is required..? + + return 1; } /* @@ -394,7 +400,7 @@ str·appendbyte(string *s, const byte b) * Returns the newly minted string */ -void +int str·appendf(string *s, const byte* fmt, ...) { va_list args; @@ -415,6 +421,8 @@ str·appendf(string *s, const byte* fmt, ...) Hdr* h = (Hdr*)(*s - sizeof(Hdr)); h->len += n; + + return n; } // Equals returns true if string s and t are equivalent. -- cgit v1.2.1