diff 73ffc757d57e3b84fe62d679425be6be209fcfac uncommitted --- a/sys/src/9/pc/ether8169.c +++ b/sys/src/9/pc/ether8169.c @@ -125,7 +125,7 @@ Macv40 = 0x4c000000, /* RTL8168G */ Macv42 = 0x50800000, /* RTL8168GU */ Macv44 = 0x5c800000, /* RTL8411B */ - Macv45 = 0x54000000, /* RTL8111HN */ + Macv45 = 0x54000000, /* RTL8111HN/8168H */ Macv51 = 0x50000000, /* RTL8168EP */ Ifg0 = 0x01000000, /* Interframe Gap 0 */ @@ -714,7 +714,9 @@ cplusc |= Txenb|Mulrw; switch(ctlr->macv){ case Macv40: + case Macv42: case Macv44: + case Macv45: case Macv51: cplusc |= Macstatdis; break; @@ -732,7 +734,20 @@ csr32w(ctlr, Rdsar+4, pa>>32); csr32w(ctlr, Rdsar, pa); - csr8w(ctlr, Cr, Te|Re); + /* pre-RTL8168G controllers need TX/RX before configuration */ + switch(ctlr->macv){ + case Macv40: + case Macv42: + case Macv44: + case Macv45: + case Macv51: + /* RXDV gating */ + i = csr32r(ctlr, 0x00F0); + csr32w(ctlr, 0x00F0, i&~0x00080000); + break; + default: + csr8w(ctlr, Cr, Te|Re); + } csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); ctlr->tcr = csr32r(ctlr, Tcr); @@ -769,6 +784,16 @@ csr32w(ctlr, Mpc, 0); + switch(ctlr->macv){ + case Macv40: + case Macv42: + case Macv44: + case Macv45: + case Macv51: + csr8w(ctlr, Cr, Te|Re); + default: + break; + } iunlock(ctlr); }
Sun Dec 3 13:44:05 EST 2023
ether8169: enable RX/TX only after the configuration step on modern models, RXDV gate should be enabled to traffic to go on this follows OpenBSD's sys/dev/pci/if_rge.c and FreeBSD's sys/dev/re/if_re.c RXDV gate should define wheter the traffic goes through dma or fifo on the controller
Sun Dec 3 11:32:51 EST 2023
diff 73ffc757d57e3b84fe62d679425be6be209fcfac uncommitted --- a/sys/src/9/pc/ether8169.c +++ b/sys/src/9/pc/ether8169.c @@ -125,7 +125,7 @@ Macv40 = 0x4c000000, /* RTL8168G */ Macv42 = 0x50800000, /* RTL8168GU */ Macv44 = 0x5c800000, /* RTL8411B */ - Macv45 = 0x54000000, /* RTL8111HN */ + Macv45 = 0x54000000, /* RTL8111HN/8168H */ Macv51 = 0x50000000, /* RTL8168EP */ Ifg0 = 0x01000000, /* Interframe Gap 0 */ @@ -714,7 +714,9 @@ cplusc |= Txenb|Mulrw; switch(ctlr->macv){ case Macv40: + case Macv42: case Macv44: + case Macv45: case Macv51: cplusc |= Macstatdis; break; @@ -732,7 +734,17 @@ csr32w(ctlr, Rdsar+4, pa>>32); csr32w(ctlr, Rdsar, pa); - csr8w(ctlr, Cr, Te|Re); + /* pre-RTL8168G controllers need early TX/RX before configuration */ + switch(ctlr->macv){ + case Macv42: + case Macv45: + /* RXDV gating */ + i = csr32r(ctlr, 0x00F0); + csr32w(ctlr, 0x00F0, i&~0x00080000); + break; + default: + csr8w(ctlr, Cr, Te|Re); + } csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); ctlr->tcr = csr32r(ctlr, Tcr); @@ -769,6 +781,13 @@ csr32w(ctlr, Mpc, 0); + switch(ctlr->macv){ + case Macv42: + case Macv45: + csr8w(ctlr, Cr, Te|Re); + default: + break; + } iunlock(ctlr); }
Sun Dec 3 11:30:57 EST 2023
diff 22cf5562fae445333c83d7d562156943dbe1716b uncommitted --- a/sys/src/9/pc/ether8169.c +++ b/sys/src/9/pc/ether8169.c @@ -125,7 +125,7 @@ Macv40 = 0x4c000000, /* RTL8168G */ Macv42 = 0x50800000, /* RTL8168GU */ Macv44 = 0x5c800000, /* RTL8411B */ - Macv45 = 0x54000000, /* RTL8111HN */ + Macv45 = 0x54000000, /* RTL8111HN/8168H */ Macv51 = 0x50000000, /* RTL8168EP */ Ifg0 = 0x01000000, /* Interframe Gap 0 */ @@ -714,7 +714,9 @@ cplusc |= Txenb|Mulrw; switch(ctlr->macv){ case Macv40: + case Macv42: case Macv44: + case Macv45: case Macv51: cplusc |= Macstatdis; break; @@ -732,7 +734,17 @@ csr32w(ctlr, Rdsar+4, pa>>32); csr32w(ctlr, Rdsar, pa); - csr8w(ctlr, Cr, Te|Re); + /* pre-RTL8168G controllers need early TX/RX before configuration */ + switch(ctlr->macv){ + case Macv42: + case Macv45: + /* RXDV gating */ + i = csr32r(ctlr, 0x00F0); + csr32w(ctlr, 0x00F0, i&~0x00080000); + break; + default: + csr8w(ctlr, Cr, Te|Re); + } csr32w(ctlr, Tcr, Ifg1|Ifg0|Mtxdmaunlimited); ctlr->tcr = csr32r(ctlr, Tcr); @@ -769,6 +781,13 @@ csr32w(ctlr, Mpc, 0); + switch(ctlr->macv){ + case Macv42: + case Macv45: + csr8w(ctlr, Cr, Te|Re); + default: + break; + } iunlock(ctlr); }
Sun Dec 3 10:14:42 EST 2023
#include <stdio.h> #include <string.h> #include <stdint.h> #include <stdlib.h> #include <assert.h> #define CCMP(num, len, val) do { \ if(!strncmp(cptr, num, len)) { \ cptr += len; \ ret = val; \ break; \ } \ } while(0) #define CMP(num, val) CCMP(num, strlen(num), val) int wtonum(char *cptr, char **rptr){ int ret = -1; switch(*cptr){ case 'o': CMP("one", 1); break; case 't': CMP("two", 2); CMP("three", 3); break; case 'f': CMP("four", 4); CMP("five", 5); break; case 's': CMP("six", 6); CMP("seven", 7); break; case 'e': CMP("eight", 8); break; case 'n': CMP("nine", 9); break; } if(rptr){ *rptr = cptr; } return ret; } int next_num(char *buf, size_t len, size_t *pos){ for(; len>*pos; *pos+=1) { char *cptr = buf + *pos, *rptr; int c = *cptr; if(c >= '0' && c <= '9'){ *pos+=1; return c-'0'; } c = wtonum(cptr, &rptr); if(cptr != rptr){ assert(rptr > buf); *pos = rptr - buf; return c; } } return -1; } int main() { char buf[BUFSIZ]; int state=0, num=0, tmp=0, c; uint64_t tot=0; while(fgets(buf, BUFSIZ, stdin) != NULL){ size_t pos=0, l=strlen(buf); while((c = next_num(buf, l, &pos)) != -1){ switch(state){ case 0: state=1; num = tmp = c; num = num * 10; break; case 1: tmp = c; } } num += tmp; tot += (uint64_t)num; printf("total: %zu, num: %d, line: %s\n", tot, num, buf); state=0; tmp=0; num=0; } printf("%zu\n", tot); }
Sat Dec 2 19:49:16 EST 2023
diff b07a6e33bd1d0653709e4789ee7463a6ff102f67 uncommitted --- /dev/null +++ b/sys/man/2/error @@ -1,0 +1,85 @@ +.TH ERROR 2 +.SH NAME +error, nexterror, poperror, pusherrlab, waserror \- per-process private storage management +.SH SYNOPSIS +.B #include <u.h> +.br +.B #include <libc.h> +.br +.B #include <error.h> +.ta \w'jmp_bufmmm'u +.PP +.B +void error(char *fmt, ...) +.br +void nexterror(void); +.br +void poperror(void); +.br +jmp_buf* pusherrlab(void); +.br +#define waserror() (setjmp(*pusherrlab())) +.SH DESCRIPTION +These routines provide error handling using a stack of +.IR longjmp (2) +targets similar in function to +.IR error (9). +The stack of error labels is local to a process and not copied upon process fork. +If the calling program is using +.IR libthread (2) +then the error labels are local to a thread instead. +.PP +.I Error +takes a print style format string and arguments, +and uses them to set the error string before popping an error label off the stack and jumping to it. +.PP +.I Nexterror +pops an error label off the stack and jumps to it without setting the error string. +.PP +.I Poperror +is used to pop the latest error label off the stack. +.PP +.I Waserror +pushes a location on to the error label stack. +When called to set the label the return value will be zero, when +jumped to execution will resume from where waserror() was called +except with the return value set to one. +.PP +Typically for each +.I waserror +call there is a matching +.I poperror +to pop the handler after all operations that could fail have succeeded. +.SH EXAMPLE +.IP +.EX +void* +emalloc(ulong sz) +{ + void *v; + + v = mallocz(sz, 1); + setmalloctag(v, getcallerpc(&sz)); + if(v == nil) + error("malloc: %r"); + return v; +} + +void +main(int, char**) +{ + char *p, *q; + + if(waserror()) + sysfatal("caught error: %r"); + p = emalloc(512); + q = emalloc(512); + poperror(); +} +.EE +.SH SOURCE +.B /sys/src/liberror +.SH SEE ALSO +.IR errstr (2), +.IR setjmp (2), +.IR error (9) --- /dev/null +++ b/sys/src/liberror/err.c @@ -1,0 +1,79 @@ +#include <u.h> +#include <libc.h> +#include <error.h> + +enum { + Maxerrlab = 64, +}; + +typedef struct Errlab Errlab; +struct Errlab { + jmp_buf *s; + int n; +}; + +static Lock alloclock; +static int allocslot = -1; + +static Errlab* +errorchk(void) +{ + Errlab **e; + + lock(&alloclock); + if(allocslot == -1) + allocslot = localalloc(); + unlock(&alloclock); + + e = localget(allocslot); + if(*e != nil) + return *e; + + *e = mallocz(sizeof **e, 1); + (*e)->s = mallocz(sizeof(jmp_buf) * Maxerrlab, 1); + (*e)->n = 0; + if(waserror()) + abort(); + return *e; +} + +_Noreturn void +nexterror(void) +{ + Errlab *e; + + e = errorchk(); + if(e->n <= 0) + abort(); + longjmp(e->s[--e->n], 1); +} + +_Noreturn void +error(char *fmt, ...) +{ + va_list arg; + char buf[ERRMAX]; + + va_start(arg, fmt); + vseprint(buf, buf+ERRMAX, fmt, arg); + va_end(arg); + errstr(buf, ERRMAX); + + nexterror(); +} + +void +poperror(void) +{ + if(--errorchk()->n < 0) + abort(); +} + +jmp_buf* +pusherrlab(void) +{ + Errlab *e; + + e = errorchk(); + return e->s + e->n++; +} --- /dev/null +++ b/sys/src/liberror/mkfile @@ -1,0 +1,13 @@ +</$objtype/mkfile + +LIB=/$objtype/lib/liberror.a +OFILES=\ + err.$O\ + +HFILES=/sys/include/error.h + +UPDATE=\ + mkfile\ + $HFILES\ + +</sys/src/cmd/mksyslib --- /dev/null +++ b/sys/src/liberror/test/basic.c @@ -1,0 +1,24 @@ +#include <u.h> +#include <libc.h> +#include <error.h> + +int n; + +void +main(int, char**) +{ + n = 0; + if(waserror()){ + if(n != 2) + sysfatal("missed label"); + exits(nil); + } + + if(waserror()){ + n++; + nexterror(); + } + + n++; + error("fail"); +} --- /dev/null +++ b/sys/src/liberror/test/mkfile @@ -1,0 +1,7 @@ +</$objtype/mkfile + +TEST=\ + basic\ + thread\ + +</sys/src/cmd/mktest --- /dev/null +++ b/sys/src/liberror/test/thread.c @@ -1,0 +1,25 @@ +#include <u.h> +#include <libc.h> +#include <error.h> +#include <thread.h> + +int n; + +void +threadmain(int, char**) +{ + n = 0; + if(waserror()){ + if(n != 2) + sysfatal("missed label"); + exits(nil); + } + + if(waserror()){ + n++; + nexterror(); + } + + n++; + error("fail"); +}
Sat Dec 2 19:49:06 EST 2023
diff b07a6e33bd1d0653709e4789ee7463a6ff102f67 uncommitted --- a/sys/include/libc.h +++ b/sys/include/libc.h @@ -527,7 +527,14 @@ extern void rsleep(Rendez*); /* unlocks r->l, sleeps, locks r->l again */ extern int rwakeup(Rendez*); extern int rwakeupall(Rendez*); + +enum +{ + NPRIVATES=16, /* keep in sync with main9*.s */ +}; extern void** privalloc(void); +extern int localalloc(void); +extern void** localget(int); extern void procsetname(char*, ...); #pragma varargck argpos procsetname 1 --- a/sys/man/2/privalloc +++ b/sys/man/2/privalloc @@ -1,6 +1,6 @@ .TH PRIVALLOC 2 .SH NAME -privalloc \- per-process private storage management +privalloc, localalloc, localget \- per-process private storage management .SH SYNOPSIS .B #include <u.h> .br @@ -9,6 +9,10 @@ .PP .B void** privalloc(void) +.br +int localalloc(void); +.br +void** localget(int); .SH DESCRIPTION .I Privalloc returns a pointer to a per-process private storage location. @@ -17,6 +21,17 @@ It returns .B nil if there are no free slots available. +On process fork the values of these slots are set to zero. +.PP +.I Localalloc +returns a handle that may be passed to +.I localget +to access a per-context private storage location. +For programs that use +.IR libthread (2) +the context is per-thread. +For those that do not, the context is per-process exactly as +.IR privalloc . .SH SOURCE .B /sys/src/libc/9sys/privalloc.c .SH SEE ALSO --- a/sys/src/libc/9sys/mkfile +++ b/sys/src/libc/9sys/mkfile @@ -40,6 +40,7 @@ read9pmsg.$O\ readv.$O\ rerrstr.$O\ + rfork.$O\ sbrk.$O\ setnetmtpt.$O\ sysfatal.$O\ --- a/sys/src/libc/9sys/privalloc.c +++ b/sys/src/libc/9sys/privalloc.c @@ -20,3 +20,37 @@ return p; } + +static int +_localallocimpl(void) +{ + int r; + + lock(&privlock); + assert(_nprivates > 0); + r = --_nprivates; + unlock(&privlock); + return r; +} + +static void** +_localgetimpl(int i) +{ + assert(i >= 0 && i < NPRIVATES); + return &_privates[i]; +} + +int (*_localalloc)(void) = _localallocimpl; +void** (*_localget)(int) = _localgetimpl; + +int +localalloc(void) +{ + return _localalloc(); +} + +void** +localget(int i) +{ + return _localget(i); +} --- /dev/null +++ b/sys/src/libc/9sys/rfork.c @@ -1,0 +1,16 @@ +#include <u.h> +#include <libc.h> + +extern int rfork_(int); +extern void **_privates; + +int +rfork(int flags) +{ + int p; + + p = rfork_(flags); + if(p == 0 && (flags&RFPROC)) + memset(_privates, 0, sizeof(*_privates)*NPRIVATES); + return p; +} --- a/sys/src/libc/9syscall/sys.h +++ b/sys/src/libc/9syscall/sys.h @@ -17,7 +17,7 @@ #define OSEEK 16 #define SLEEP 17 #define _STAT 18 -#define RFORK 19 +#define RFORK_ 19 #define _WRITE 20 #define PIPE 21 #define CREATE 22 --- a/sys/src/libthread/lib.c +++ b/sys/src/libthread/lib.c @@ -36,3 +36,17 @@ fprint(2, "%s\n", buf); threadexitsall(buf); } + +int +_threadlocalalloc(void) +{ + assert(_threadgetproc()->thread->nprivates < NPRIVATES); + return _threadgetproc()->thread->nprivates++; +} + +void** +_threadlocalget(int i) +{ + assert(i >= 0 && i < NPRIVATES); + return &_threadgetproc()->thread->privates[i]; +} --- a/sys/src/libthread/main.c +++ b/sys/src/libthread/main.c @@ -4,6 +4,8 @@ #include "threadimpl.h" extern void (*_sysfatal)(char*, va_list); +extern int (*_localalloc)(void); +extern void** (*_localget)(int); extern void (*__assert)(char*); int mainstacksize; @@ -27,6 +29,8 @@ _threadprocp = privalloc(); _qlockinit(_threadrendezvous); _sysfatal = _threadsysfatal; + _localalloc = _threadlocalalloc; + _localget = _threadlocalget; __assert = _threadassert; notify(_threadnote); if(mainstacksize == 0) --- a/sys/src/libthread/threadimpl.h +++ b/sys/src/libthread/threadimpl.h @@ -90,6 +90,9 @@ Chanstate chan; /* which channel operation is current */ Alt *alt; /* pointer to current alt structure (debugging) */ + void* privates[NPRIVATES]; + int nprivates; + void* udata; /* User per-thread data pointer */ }; @@ -169,6 +172,8 @@ void _threadready(Thread*); void* _threadrendezvous(void*, void*); void _threadsysfatal(char*, va_list); +int _threadlocalalloc(void); +void** _threadlocalget(int); Proc **_threadprocp; #define _threadgetproc() (*_threadprocp)
Sat Dec 2 18:45:45 EST 2023
void* emalloc(ulong sz) { void *v; v = malloc(sz); if(v == nil) error("malloc failed"); return v; } void dothing(void) { if(waserror()){ print("could not malloc"); nexterror(); } p = emalloc(123); use(p) free(p); poperror(); } void main(int, char**) { char *p, *q; if(waserror()) sysfatal("caught error: %r"); dothing(); poperror(); }
Sat Dec 2 18:35:33 EST 2023
PRIVALLOC(2) PRIVALLOC(2) NAME privalloc, localalloc, localget - per-process private storage management SYNOPSIS #include <u.h> #include <libc.h> void** privalloc(void) int localalloc(void); void** localget(int); DESCRIPTION Privalloc returns a pointer to a per-process private storage location. The location is not shared among processes, even if they share the same data segments. It returns nil if there are no free slots available. On process fork the val- ues of these slots are set to zero. Localalloc returns a handle that may be passed to localget to access a per-context private storage location. For pro- grams that use libthread(2) the context is per thread. For those that do not, the context is per-process exactly as privalloc. SOURCE /sys/src/libc/9sys/privalloc.c SEE ALSO exec(2)
Sat Dec 2 18:35:22 EST 2023
ERROR(2) ERROR(2) NAME error, nexterror, poperror, pusherrlab, waserror - per- process private storage management SYNOPSIS #include <u.h> #include <libc.h> #include <error.h> void error(char *fmt, ...) void nexterror(void); void poperror(void); jmp_buf* pusherrlab(void); #define waserror() (setjmp(*pusherrlab())) DESCRIPTION These routines provide error handling using a stack of longjmp(2) targets similar in function to error(9). The stack of error labels is local to a process and not copied upon process fork. If the calling program is using libthread(2) then the error labels are local to a thread instead. Error takes a print style format string and arguments, and uses them to set the error string before popping an error label off the stack and jumping to it. Nexterror pops an error label off the stack and jumps to it without setting the error string. Poperror is used to pop the latest error label off the stack. Waserror is called to register a location on to the error label stack. When called to set the label the return value will be zero, when jumped to execution will resume from where waserror() was called except with the return value set to one. EXAMPLE void* emalloc(ulong sz) { void *v; v = malloc(sz); if(v == nil) error("malloc failed"); return v; } void main(int, char**) { char *p, *q; if(waserror()) sysfatal("caught error: %r"); p = emalloc(1024); q = emalloc(1024); } SOURCE /sys/src/liberror/ SEE ALSO errstr(2), setjmp(2), error(9)
Sat Dec 2 16:12:36 EST 2023
; 6.out min op/s 98% 96% 75% med avg min max fmin 283 4568225 4565163 4563893 3543909 3527765 2488743 4571387 fmin_sse 414 2424605 2420142 2417015 2414723 2415306 2409636 2426538 2d dot product op/s 98% 96% 75% med avg min max dotvec2 267 3744010 3742209 3737007 3735923 3736518 3731135 3767934 dotvec2_sse 73 13698430 13695892 13693351 13692214 13692714 13690210 13698510 dotvec2_sse4 75 13283629 13280936 13278169 13277493 13277783 13275146 13286098 dotvec2_avx 75 13283761 13279452 13278088 13277284 13277534 13275028 13287380 dotvec2_sse_a 373 2881463 2669431 2667139 2665984 2679081 2627220 3743409 dotvec2_sse4_a 393 2569252 2568403 2563474 2531893 2540101 2488852 3467011 dotvec2_avx_a 342 2910797 2906958 2905773 2905043 2915722 2903536 3964388 3d dot product op/s 98% 96% 75% med avg min max dotvec3 206 5304768 5210421 4784381 4760076 4833173 4756544 5677615 dotvec3_sse4 65 15355526 15353759 15352531 15351795 15351913 15349422 15357083 dotvec3_avx 65 15354566 15354048 15352757 15351779 15351973 15349416 15357971 dotvec3_sse4_a 337 2959474 2957670 2956259 2955527 2963219 2926466 3756403 3d cross product op/s 98% 96% 75% med avg min max crossvec3 91 10986157 10983141 10971494 10968571 10969827 10962082 10989235 crossvec3_sse 143 7001828 7000719 6998587 6996428 6974455 6863747 7199104 Pt2 op/s 98% 96% 75% med avg min max Pt2 227 4415172 4408012 4398711 4397851 4399747 4381089 4559482 Pt2b 277 3608261 3607181 3604815 3603066 3603403 3599702 3609269 multiply + add op/s 98% 96% 75% med avg min max madd 347 2878112 2877760 2876937 2876112 2876230 2874718 2883503 fma_avx 341 2938089 2937966 2936871 2935967 2926577 2802398 2938710 2d point sum op/s 98% 96% 75% med avg min max addpt2 120 8314705 8311729 8310052 8308082 8308210 8285693 8353482 addpt2_sse 89 11204824 11203825 11203201 11202634 11202605 11201048 11205531 addpt2_avx 73 13696975 13696348 13695183 13694241 13694325 13691704 13697637 3d point sum op/s 98% 96% 75% med avg min max addpt3 94 10560908 10537671 10530696 10525254 10528137 10520659 10579957 addpt3_avx 77 12873349 12868526 12867472 12866408 12868654 12863977 13081995 ; aux/cpuid vendor GenuineIntel procmodel 000a0652 / 06100800 typefammod 0 06 0a6 2 features fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat features pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe features pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1 sse4_2 features x2apic movbe popcnt tscdeadline aes xsave osxsave avx f16c rdrnd features fsgsbase sgx bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intelpt features pku sgxlc features xsaveopt xsavec xgetbv1 xsaves extmodel 00000000 / 00000000 extfeatures syscall nx pg1g tscp lm extfeatures ahf64 lzcnt 3dnow!p procname Intel(R) Core(TM) i5-10300H CPU @ 2.50GHz physbits 39 virtbits 48 ; webpaste /dev/text