Compare commits

..
10 Commits
Author SHA1 Message Date
xtaci 8929bb029d upd pgo 2024-01-06 16:07:26 +08:00
xtaci 13f48e04df add vendor 2024-01-05 22:37:46 +08:00
xtaci fa0d5e0765 upd deps to v5.6.7 2024-01-05 22:37:22 +08:00
fuli 86443d924d upgrade deps to v5.6.6 2024-01-05 15:31:45 +08:00
xtaci 0440abbc91 upd deps of kcp-go to @v5.6.5 2023-10-12 23:29:36 +08:00
143991124c Bump golang.org/x/net from 0.14.0 to 0.17.0 (#931)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-12 11:37:01 +08:00
xtaci 55e670033b add default.pgo in client &
added an option to enable pprof on client
2023-08-11 12:49:45 +08:00
xtaci 589fe49232 update Dockerfile to go1.21 2023-08-11 12:08:50 +08:00
xtaci 511c9a5ded upd deps & upgrade to kcp-go@v5.6.3 2023-08-11 12:02:07 +08:00
xtaci 5ad73ea8eb Squashed commit of the following:
commit 90b1b24d0d
Author: xtaci <daniel820313@gmail.com>
Date:   Fri Jul 28 00:56:06 2023 +0800

    upd Dockerfile

commit 3349f6118b
Author: xtaci <daniel820313@gmail.com>
Date:   Fri Jul 28 00:44:26 2023 +0800

    upd dockerfile
2023-07-28 01:01:15 +08:00
444 changed files with 41577 additions and 4047 deletions
+2 -4
View File
@@ -1,9 +1,7 @@
FROM golang:1.20.6-alpine3.18 as builder
FROM golang:1.21.0-alpine3.18 as builder
MAINTAINER xtaci <daniel820313@gmail.com>
ENV GO111MODULE=on
RUN apk update && \
apk upgrade && \
apk add git gcc libc-dev linux-headers
RUN apk add git
RUN git clone https://github.com/xtaci/kcptun.git
RUN cd kcptun && \
go build -mod=vendor -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" -o /client github.com/xtaci/kcptun/client && \
+1
View File
@@ -37,6 +37,7 @@ type Config struct {
SnmpPeriod int `json:"snmpperiod"`
Quiet bool `json:"quiet"`
TCP bool `json:"tcp"`
Pprof bool `json:"pprof"`
}
func parseJSONConfig(config *Config, path string) error {
+2525
View File
File diff suppressed because one or more lines are too long
+13
View File
@@ -7,6 +7,8 @@ import (
"log"
"math/rand"
"net"
"net/http"
_ "net/http/pprof"
"os"
"time"
@@ -243,6 +245,10 @@ func main() {
Value: "", // when the value is not empty, the config path must exists
Usage: "config from json file, which will override the command from shell",
},
cli.BoolFlag{
Name: "pprof",
Usage: "start profiling server on :6060",
},
}
myApp.Action = func(c *cli.Context) error {
config := Config{}
@@ -276,6 +282,7 @@ func main() {
config.SnmpPeriod = c.Int("snmpperiod")
config.Quiet = c.Bool("quiet")
config.TCP = c.Bool("tcp")
config.Pprof = c.Bool("pprof")
if c.String("c") != "" {
err := parseJSONConfig(&config, c.String("c"))
@@ -341,6 +348,7 @@ func main() {
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("quiet:", config.Quiet)
log.Println("tcp:", config.TCP)
log.Println("pprof:", config.Pprof)
// parameters check
if config.SmuxVer > maxSmuxVer {
@@ -443,6 +451,11 @@ func main() {
// start snmp logger
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
// start pprof
if config.Pprof {
go http.ListenAndServe(":6060", nil)
}
// start scavenger
chScavenger := make(chan timedSession, 128)
go scavenger(chScavenger, &config)
+11 -9
View File
@@ -3,25 +3,27 @@ module github.com/xtaci/kcptun
require (
github.com/golang/snappy v0.0.4
github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.12
github.com/xtaci/kcp-go/v5 v5.6.2
github.com/urfave/cli v1.22.14
github.com/xtaci/kcp-go/v5 v5.6.7
github.com/xtaci/smux v1.5.24
github.com/xtaci/tcpraw v1.2.25
golang.org/x/crypto v0.5.0
golang.org/x/crypto v0.17.0
)
require (
github.com/coreos/go-iptables v0.6.0 // indirect
github.com/coreos/go-iptables v0.7.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/klauspost/reedsolomon v1.11.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/reedsolomon v1.12.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/templexxx/cpu v0.1.0 // indirect
github.com/templexxx/xorsimd v0.4.2 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.16.0 // indirect
)
go 1.17
go 1.21
toolchain go1.21.0
+21 -54
View File
@@ -1,11 +1,11 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -33,13 +33,10 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/klauspost/cpuid/v2 v2.0.14/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU=
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/reedsolomon v1.10.0/go.mod h1:qHMIzMkuZUWqIh8mS/GruPdo3u0qwX2jk/LH440ON7Y=
github.com/klauspost/reedsolomon v1.11.6 h1:h0MUpEzmretucmlelC3EefQHKgk6vWpKz/ctB/tmaEs=
github.com/klauspost/reedsolomon v1.11.6/go.mod h1:cuXqklb3LNaurR5MVjy7WLXAEUqGz4I0Uc+rnQ7POUg=
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/reedsolomon v1.12.0 h1:I5FEp3xSwVCcEh3F5A7dofEfhXdF/bWhQWPH+XwBFno=
github.com/klauspost/reedsolomon v1.12.0/go.mod h1:EPLZJeh4l27pUGC3aXOjheaoh1I9yut7xTURiW3LQ9Y=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -50,46 +47,40 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
github.com/templexxx/cpu v0.0.9/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/xtaci/kcp-go/v5 v5.6.2 h1:pSXMa5MOsb+EIZKe4sDBqlTExu2A/2Z+DFhoX2qtt2A=
github.com/xtaci/kcp-go/v5 v5.6.2/go.mod h1:LsinWoru+lWWJHb+EM9HeuqYxV6bb9rNcK12v67jYzQ=
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/xtaci/kcp-go/v5 v5.6.6 h1:SxSjZoaaLzQKxbIfzE1FYLMKtR2veox5mvKO7AliZ5I=
github.com/xtaci/kcp-go/v5 v5.6.6/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
github.com/xtaci/kcp-go/v5 v5.6.7 h1:7+rnxNFIsjEwTXQk4cSZpXM4pO0hqtpwE1UFFoJBffA=
github.com/xtaci/kcp-go/v5 v5.6.7/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=
github.com/xtaci/smux v1.5.24/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk=
github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -97,51 +88,27 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+42 -3
View File
@@ -52,7 +52,8 @@ func (e *Error) IsNotExist() bool {
}
msgNoRuleExist := "Bad rule (does a matching rule exist in that chain?).\n"
msgNoChainExist := "No chain/target/match by that name.\n"
return strings.Contains(e.msg, msgNoRuleExist) || strings.Contains(e.msg, msgNoChainExist)
msgENOENT := "No such file or directory"
return strings.Contains(e.msg, msgNoRuleExist) || strings.Contains(e.msg, msgNoChainExist) || strings.Contains(e.msg, msgENOENT)
}
// Protocol to differentiate between IPv4 and IPv6
@@ -109,6 +110,7 @@ func Timeout(timeout int) option {
// For backwards compatibility, by default always uses IPv4 and timeout 0.
// i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing
// the IPFamily and Timeout options as follow:
//
// ip6t := New(IPFamily(ProtocolIPv6), Timeout(5))
func New(opts ...option) (*IPTables, error) {
@@ -185,6 +187,26 @@ func (ipt *IPTables) Insert(table, chain string, pos int, rulespec ...string) er
return ipt.run(cmd...)
}
// Replace replaces rulespec to specified table/chain (in specified pos)
func (ipt *IPTables) Replace(table, chain string, pos int, rulespec ...string) error {
cmd := append([]string{"-t", table, "-R", chain, strconv.Itoa(pos)}, rulespec...)
return ipt.run(cmd...)
}
// InsertUnique acts like Insert except that it won't insert a duplicate (no matter the position in the chain)
func (ipt *IPTables) InsertUnique(table, chain string, pos int, rulespec ...string) error {
exists, err := ipt.Exists(table, chain, rulespec...)
if err != nil {
return err
}
if !exists {
return ipt.Insert(table, chain, pos, rulespec...)
}
return nil
}
// Append appends rulespec to specified table/chain
func (ipt *IPTables) Append(table, chain string, rulespec ...string) error {
cmd := append([]string{"-t", table, "-A", chain}, rulespec...)
@@ -219,6 +241,16 @@ func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) err
return err
}
// List rules in specified table/chain
func (ipt *IPTables) ListById(table, chain string, id int) (string, error) {
args := []string{"-t", table, "-S", chain, strconv.Itoa(id)}
rule, err := ipt.executeList(args)
if err != nil {
return "", err
}
return rule[0], nil
}
// List rules in specified table/chain
func (ipt *IPTables) List(table, chain string) ([]string, error) {
args := []string{"-t", table, "-S", chain}
@@ -291,6 +323,11 @@ func (ipt *IPTables) Stats(table, chain string) ([][]string, error) {
ipv6 := ipt.proto == ProtocolIPv6
// Skip the warning if exist
if strings.HasPrefix(lines[0], "#") {
lines = lines[1:]
}
rows := [][]string{}
for i, line := range lines {
// Skip over chain name and field header
@@ -510,7 +547,9 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
syscall.Close(fmu.fd)
return err
}
defer ul.Unlock()
defer func() {
_ = ul.Unlock()
}()
}
var stderr bytes.Buffer
@@ -619,7 +658,7 @@ func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool {
return false
}
//Checks if an iptablse version is after 1.6.0, when --wait support second
// Checks if an iptablse version is after 1.6.0, when --wait support second
func iptablesWaitSupportSecond(v1 int, v2 int, v3 int) bool {
if v1 > 1 {
return true
+22 -6
View File
@@ -9,16 +9,19 @@ You can access the CPU information by accessing the shared CPU variable of the c
Package home: https://github.com/klauspost/cpuid
[![PkgGoDev](https://pkg.go.dev/badge/github.com/klauspost/cpuid)](https://pkg.go.dev/github.com/klauspost/cpuid/v2)
[![Build Status][3]][4]
[3]: https://travis-ci.org/klauspost/cpuid.svg?branch=master
[4]: https://travis-ci.org/klauspost/cpuid
[![Go](https://github.com/klauspost/cpuid/actions/workflows/go.yml/badge.svg)](https://github.com/klauspost/cpuid/actions/workflows/go.yml)
## installing
`go get -u github.com/klauspost/cpuid/v2` using modules.
Drop `v2` for others.
Installing binary:
`go install github.com/klauspost/cpuid/v2/cmd/cpuid@latest`
Or download binaries from release page: https://github.com/klauspost/cpuid/releases
### Homebrew
For macOS/Linux users, you can install via [brew](https://brew.sh/)
@@ -279,7 +282,12 @@ Exit Code 1
| AMXINT8 | Tile computational operations on 8-bit integers |
| AMXFP16 | Tile computational operations on FP16 numbers |
| AMXTILE | Tile architecture |
| APX_F | Intel APX |
| AVX | AVX functions |
| AVX10 | If set the Intel AVX10 Converged Vector ISA is supported |
| AVX10_128 | If set indicates that AVX10 128-bit vector support is present |
| AVX10_256 | If set indicates that AVX10 256-bit vector support is present |
| AVX10_512 | If set indicates that AVX10 512-bit vector support is present |
| AVX2 | AVX2 functions |
| AVX512BF16 | AVX-512 BFLOAT16 Instructions |
| AVX512BITALG | AVX-512 Bit Algorithms |
@@ -302,6 +310,7 @@ Exit Code 1
| AVXSLOW | Indicates the CPU performs 2 128 bit operations instead of one |
| AVXVNNI | AVX (VEX encoded) VNNI neural network instructions |
| AVXVNNIINT8 | AVX-VNNI-INT8 instructions |
| BHI_CTRL | Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598 |
| BMI1 | Bit Manipulation Instruction Set 1 |
| BMI2 | Bit Manipulation Instruction Set 2 |
| CETIBT | Intel CET Indirect Branch Tracking |
@@ -355,8 +364,11 @@ Exit Code 1
| IBS_OPFUSE | AMD: Indicates support for IbsOpFuse |
| IBS_PREVENTHOST | Disallowing IBS use by the host supported |
| IBS_ZEN4 | Fetch and Op IBS support IBS extensions added with Zen4 |
| IDPRED_CTRL | IPRED_DIS |
| INT_WBINVD | WBINVD/WBNOINVD are interruptible. |
| INVLPGB | NVLPGB and TLBSYNC instruction supported |
| KEYLOCKER | Key locker |
| KEYLOCKERW | Key locker wide |
| LAHF | LAHF/SAHF in long mode |
| LAM | If set, CPU supports Linear Address Masking |
| LBRVIRT | LBR virtualization |
@@ -374,6 +386,7 @@ Exit Code 1
| MPX | Intel MPX (Memory Protection Extensions) |
| MOVU | MOVU SSE instructions are more efficient and should be preferred to SSE MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD |
| MSRIRC | Instruction Retired Counter MSR available |
| MSRLIST | Read/Write List of Model Specific Registers |
| MSR_PAGEFLUSH | Page Flush MSR available |
| NRIPS | Indicates support for NRIP save on VMEXIT |
| NX | NX (No-Execute) bit |
@@ -381,12 +394,13 @@ Exit Code 1
| PCONFIG | PCONFIG for Intel Multi-Key Total Memory Encryption |
| POPCNT | POPCNT instruction |
| PPIN | AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled |
| PREFETCHI | PREFETCHIT0/1 instructions |
| PSFD | AMD: Predictive Store Forward Disable |
| PREFETCHI | PREFETCHIT0/1 instructions |
| PSFD | Predictive Store Forward Disable |
| RDPRU | RDPRU instruction supported |
| RDRAND | RDRAND instruction is available |
| RDSEED | RDSEED instruction is available |
| RDTSCP | RDTSCP Instruction |
| RRSBA_CTRL | Restricted RSB Alternate |
| RTM | Restricted Transactional Memory |
| RTM_ALWAYS_ABORT | Indicates that the loaded microcode is forcing RTM abort. |
| SERIALIZE | Serialize Instruction Execution |
@@ -425,6 +439,7 @@ Exit Code 1
| SYSCALL | System-Call Extension (SCE): SYSCALL and SYSRET instructions. |
| SYSEE | SYSENTER and SYSEXIT instructions |
| TBM | AMD Trailing Bit Manipulation |
| TDX_GUEST | Intel Trust Domain Extensions Guest |
| TLB_FLUSH_NESTED | AMD: Flushing includes all the nested translations for guest translations |
| TME | Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE. |
| TOPEXT | TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX. |
@@ -439,6 +454,7 @@ Exit Code 1
| VTE | AMD Virtual Transparent Encryption supported |
| WAITPKG | TPAUSE, UMONITOR, UMWAIT |
| WBNOINVD | Write Back and Do Not Invalidate Cache |
| WRMSRNS | Non-Serializing Write to Model Specific Register |
| X87 | FPU |
| XGETBV1 | Supports XGETBV with ECX = 1 |
| XOP | Bulldozer XOP functions |
+76 -10
View File
@@ -76,7 +76,12 @@ const (
AMXFP16 // Tile computational operations on FP16 numbers
AMXINT8 // Tile computational operations on 8-bit integers
AMXTILE // Tile architecture
APX_F // Intel APX
AVX // AVX functions
AVX10 // If set the Intel AVX10 Converged Vector ISA is supported
AVX10_128 // If set indicates that AVX10 128-bit vector support is present
AVX10_256 // If set indicates that AVX10 256-bit vector support is present
AVX10_512 // If set indicates that AVX10 512-bit vector support is present
AVX2 // AVX2 functions
AVX512BF16 // AVX-512 BFLOAT16 Instructions
AVX512BITALG // AVX-512 Bit Algorithms
@@ -99,6 +104,7 @@ const (
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one
AVXVNNI // AVX (VEX encoded) VNNI neural network instructions
AVXVNNIINT8 // AVX-VNNI-INT8 instructions
BHI_CTRL // Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598
BMI1 // Bit Manipulation Instruction Set 1
BMI2 // Bit Manipulation Instruction Set 2
CETIBT // Intel CET Indirect Branch Tracking
@@ -152,8 +158,11 @@ const (
IBS_OPFUSE // AMD: Indicates support for IbsOpFuse
IBS_PREVENTHOST // Disallowing IBS use by the host supported
IBS_ZEN4 // AMD: Fetch and Op IBS support IBS extensions added with Zen4
IDPRED_CTRL // IPRED_DIS
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
INVLPGB // NVLPGB and TLBSYNC instruction supported
KEYLOCKER // Key locker
KEYLOCKERW // Key locker wide
LAHF // LAHF/SAHF in long mode
LAM // If set, CPU supports Linear Address Masking
LBRVIRT // LBR virtualization
@@ -171,6 +180,7 @@ const (
MOVU // AMD: MOVU SSE instructions are more efficient and should be preferred to SSE MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD
MPX // Intel MPX (Memory Protection Extensions)
MSRIRC // Instruction Retired Counter MSR available
MSRLIST // Read/Write List of Model Specific Registers
MSR_PAGEFLUSH // Page Flush MSR available
NRIPS // Indicates support for NRIP save on VMEXIT
NX // NX (No-Execute) bit
@@ -179,11 +189,12 @@ const (
POPCNT // POPCNT instruction
PPIN // AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled
PREFETCHI // PREFETCHIT0/1 instructions
PSFD // AMD: Predictive Store Forward Disable
PSFD // Predictive Store Forward Disable
RDPRU // RDPRU instruction supported
RDRAND // RDRAND instruction is available
RDSEED // RDSEED instruction is available
RDTSCP // RDTSCP Instruction
RRSBA_CTRL // Restricted RSB Alternate
RTM // Restricted Transactional Memory
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
SERIALIZE // Serialize Instruction Execution
@@ -222,6 +233,7 @@ const (
SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions.
SYSEE // SYSENTER and SYSEXIT instructions
TBM // AMD Trailing Bit Manipulation
TDX_GUEST // Intel Trust Domain Extensions Guest
TLB_FLUSH_NESTED // AMD: Flushing includes all the nested translations for guest translations
TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE.
TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
@@ -236,6 +248,7 @@ const (
VTE // AMD Virtual Transparent Encryption supported
WAITPKG // TPAUSE, UMONITOR, UMWAIT
WBNOINVD // Write Back and Do Not Invalidate Cache
WRMSRNS // Non-Serializing Write to Model Specific Register
X87 // FPU
XGETBV1 // Supports XGETBV with ECX = 1
XOP // Bulldozer XOP functions
@@ -296,9 +309,10 @@ type CPUInfo struct {
L2 int // L2 Cache (per core or shared). Will be -1 if undetected
L3 int // L3 Cache (per core, per ccx or shared). Will be -1 if undetected
}
SGX SGXSupport
maxFunc uint32
maxExFunc uint32
SGX SGXSupport
AVX10Level uint8
maxFunc uint32
maxExFunc uint32
}
var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
@@ -1159,6 +1173,7 @@ func support() flagSet {
fs.setIf(ecx&(1<<10) != 0, VPCLMULQDQ)
fs.setIf(ecx&(1<<13) != 0, TME)
fs.setIf(ecx&(1<<25) != 0, CLDEMOTE)
fs.setIf(ecx&(1<<23) != 0, KEYLOCKER)
fs.setIf(ecx&(1<<27) != 0, MOVDIRI)
fs.setIf(ecx&(1<<28) != 0, MOVDIR64B)
fs.setIf(ecx&(1<<29) != 0, ENQCMD)
@@ -1181,13 +1196,8 @@ func support() flagSet {
fs.setIf(edx&(1<<30) != 0, IA32_CORE_CAP)
fs.setIf(edx&(1<<31) != 0, SPEC_CTRL_SSBD)
// CPUID.(EAX=7, ECX=1).EDX
fs.setIf(edx&(1<<4) != 0, AVXVNNIINT8)
fs.setIf(edx&(1<<5) != 0, AVXNECONVERT)
fs.setIf(edx&(1<<14) != 0, PREFETCHI)
// CPUID.(EAX=7, ECX=1).EAX
eax1, _, _, _ := cpuidex(7, 1)
eax1, _, _, edx1 := cpuidex(7, 1)
fs.setIf(fs.inSet(AVX) && eax1&(1<<4) != 0, AVXVNNI)
fs.setIf(eax1&(1<<7) != 0, CMPCCXADD)
fs.setIf(eax1&(1<<10) != 0, MOVSB_ZL)
@@ -1197,6 +1207,13 @@ func support() flagSet {
fs.setIf(eax1&(1<<23) != 0, AVXIFMA)
fs.setIf(eax1&(1<<26) != 0, LAM)
// CPUID.(EAX=7, ECX=1).EDX
fs.setIf(edx1&(1<<4) != 0, AVXVNNIINT8)
fs.setIf(edx1&(1<<5) != 0, AVXNECONVERT)
fs.setIf(edx1&(1<<14) != 0, PREFETCHI)
fs.setIf(edx1&(1<<19) != 0, AVX10)
fs.setIf(edx1&(1<<21) != 0, APX_F)
// Only detect AVX-512 features if XGETBV is supported
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
// Check for OS support
@@ -1232,13 +1249,33 @@ func support() flagSet {
fs.setIf(edx&(1<<25) != 0, AMXINT8)
// eax1 = CPUID.(EAX=7, ECX=1).EAX
fs.setIf(eax1&(1<<5) != 0, AVX512BF16)
fs.setIf(eax1&(1<<19) != 0, WRMSRNS)
fs.setIf(eax1&(1<<21) != 0, AMXFP16)
fs.setIf(eax1&(1<<27) != 0, MSRLIST)
}
}
// CPUID.(EAX=7, ECX=2)
_, _, _, edx = cpuidex(7, 2)
fs.setIf(edx&(1<<0) != 0, PSFD)
fs.setIf(edx&(1<<1) != 0, IDPRED_CTRL)
fs.setIf(edx&(1<<2) != 0, RRSBA_CTRL)
fs.setIf(edx&(1<<4) != 0, BHI_CTRL)
fs.setIf(edx&(1<<5) != 0, MCDT_NO)
// Add keylocker features.
if fs.inSet(KEYLOCKER) && mfi >= 0x19 {
_, ebx, _, _ := cpuidex(0x19, 0)
fs.setIf(ebx&5 == 5, KEYLOCKERW) // Bit 0 and 2 (1+4)
}
// Add AVX10 features.
if fs.inSet(AVX10) && mfi >= 0x24 {
_, ebx, _, _ := cpuidex(0x24, 0)
fs.setIf(ebx&(1<<16) != 0, AVX10_128)
fs.setIf(ebx&(1<<17) != 0, AVX10_256)
fs.setIf(ebx&(1<<18) != 0, AVX10_512)
}
}
// Processor Extended State Enumeration Sub-leaf (EAX = 0DH, ECX = 1)
@@ -1381,9 +1418,38 @@ func support() flagSet {
fs.setIf((a>>24)&1 == 1, VMSA_REGPROT)
}
if mfi >= 0x20 {
// Microsoft has decided to purposefully hide the information
// of the guest TEE when VMs are being created using Hyper-V.
//
// This leads us to check for the Hyper-V cpuid features
// (0x4000000C), and then for the `ebx` value set.
//
// For Intel TDX, `ebx` is set as `0xbe3`, being 3 the part
// we're mostly interested about,according to:
// https://github.com/torvalds/linux/blob/d2f51b3516dade79269ff45eae2a7668ae711b25/arch/x86/include/asm/hyperv-tlfs.h#L169-L174
_, ebx, _, _ := cpuid(0x4000000C)
fs.setIf(ebx == 0xbe3, TDX_GUEST)
}
if mfi >= 0x21 {
// Intel Trusted Domain Extensions Guests have their own cpuid leaf (0x21).
_, ebx, ecx, edx := cpuid(0x21)
identity := string(valAsString(ebx, edx, ecx))
fs.setIf(identity == "IntelTDX ", TDX_GUEST)
}
return fs
}
func (c *CPUInfo) supportAVX10() uint8 {
if c.maxFunc >= 0x24 && c.featureSet.inSet(AVX10) {
_, ebx, _, _ := cpuidex(0x24, 0)
return uint8(ebx)
}
return 0
}
func valAsString(values ...uint32) []byte {
r := make([]byte, 4*len(values))
for i, v := range values {
+1
View File
@@ -31,6 +31,7 @@ func addInfo(c *CPUInfo, safe bool) {
c.LogicalCores = logicalCores()
c.PhysicalCores = physicalCores()
c.VendorID, c.VendorString = vendorID()
c.AVX10Level = c.supportAVX10()
c.cacheSize()
c.frequencies()
}
+207 -194
View File
@@ -16,204 +16,217 @@ func _() {
_ = x[AMXFP16-6]
_ = x[AMXINT8-7]
_ = x[AMXTILE-8]
_ = x[AVX-9]
_ = x[AVX2-10]
_ = x[AVX512BF16-11]
_ = x[AVX512BITALG-12]
_ = x[AVX512BW-13]
_ = x[AVX512CD-14]
_ = x[AVX512DQ-15]
_ = x[AVX512ER-16]
_ = x[AVX512F-17]
_ = x[AVX512FP16-18]
_ = x[AVX512IFMA-19]
_ = x[AVX512PF-20]
_ = x[AVX512VBMI-21]
_ = x[AVX512VBMI2-22]
_ = x[AVX512VL-23]
_ = x[AVX512VNNI-24]
_ = x[AVX512VP2INTERSECT-25]
_ = x[AVX512VPOPCNTDQ-26]
_ = x[AVXIFMA-27]
_ = x[AVXNECONVERT-28]
_ = x[AVXSLOW-29]
_ = x[AVXVNNI-30]
_ = x[AVXVNNIINT8-31]
_ = x[BMI1-32]
_ = x[BMI2-33]
_ = x[CETIBT-34]
_ = x[CETSS-35]
_ = x[CLDEMOTE-36]
_ = x[CLMUL-37]
_ = x[CLZERO-38]
_ = x[CMOV-39]
_ = x[CMPCCXADD-40]
_ = x[CMPSB_SCADBS_SHORT-41]
_ = x[CMPXCHG8-42]
_ = x[CPBOOST-43]
_ = x[CPPC-44]
_ = x[CX16-45]
_ = x[EFER_LMSLE_UNS-46]
_ = x[ENQCMD-47]
_ = x[ERMS-48]
_ = x[F16C-49]
_ = x[FLUSH_L1D-50]
_ = x[FMA3-51]
_ = x[FMA4-52]
_ = x[FP128-53]
_ = x[FP256-54]
_ = x[FSRM-55]
_ = x[FXSR-56]
_ = x[FXSROPT-57]
_ = x[GFNI-58]
_ = x[HLE-59]
_ = x[HRESET-60]
_ = x[HTT-61]
_ = x[HWA-62]
_ = x[HYBRID_CPU-63]
_ = x[HYPERVISOR-64]
_ = x[IA32_ARCH_CAP-65]
_ = x[IA32_CORE_CAP-66]
_ = x[IBPB-67]
_ = x[IBRS-68]
_ = x[IBRS_PREFERRED-69]
_ = x[IBRS_PROVIDES_SMP-70]
_ = x[IBS-71]
_ = x[IBSBRNTRGT-72]
_ = x[IBSFETCHSAM-73]
_ = x[IBSFFV-74]
_ = x[IBSOPCNT-75]
_ = x[IBSOPCNTEXT-76]
_ = x[IBSOPSAM-77]
_ = x[IBSRDWROPCNT-78]
_ = x[IBSRIPINVALIDCHK-79]
_ = x[IBS_FETCH_CTLX-80]
_ = x[IBS_OPDATA4-81]
_ = x[IBS_OPFUSE-82]
_ = x[IBS_PREVENTHOST-83]
_ = x[IBS_ZEN4-84]
_ = x[INT_WBINVD-85]
_ = x[INVLPGB-86]
_ = x[LAHF-87]
_ = x[LAM-88]
_ = x[LBRVIRT-89]
_ = x[LZCNT-90]
_ = x[MCAOVERFLOW-91]
_ = x[MCDT_NO-92]
_ = x[MCOMMIT-93]
_ = x[MD_CLEAR-94]
_ = x[MMX-95]
_ = x[MMXEXT-96]
_ = x[MOVBE-97]
_ = x[MOVDIR64B-98]
_ = x[MOVDIRI-99]
_ = x[MOVSB_ZL-100]
_ = x[MOVU-101]
_ = x[MPX-102]
_ = x[MSRIRC-103]
_ = x[MSR_PAGEFLUSH-104]
_ = x[NRIPS-105]
_ = x[NX-106]
_ = x[OSXSAVE-107]
_ = x[PCONFIG-108]
_ = x[POPCNT-109]
_ = x[PPIN-110]
_ = x[PREFETCHI-111]
_ = x[PSFD-112]
_ = x[RDPRU-113]
_ = x[RDRAND-114]
_ = x[RDSEED-115]
_ = x[RDTSCP-116]
_ = x[RTM-117]
_ = x[RTM_ALWAYS_ABORT-118]
_ = x[SERIALIZE-119]
_ = x[SEV-120]
_ = x[SEV_64BIT-121]
_ = x[SEV_ALTERNATIVE-122]
_ = x[SEV_DEBUGSWAP-123]
_ = x[SEV_ES-124]
_ = x[SEV_RESTRICTED-125]
_ = x[SEV_SNP-126]
_ = x[SGX-127]
_ = x[SGXLC-128]
_ = x[SHA-129]
_ = x[SME-130]
_ = x[SME_COHERENT-131]
_ = x[SPEC_CTRL_SSBD-132]
_ = x[SRBDS_CTRL-133]
_ = x[SSE-134]
_ = x[SSE2-135]
_ = x[SSE3-136]
_ = x[SSE4-137]
_ = x[SSE42-138]
_ = x[SSE4A-139]
_ = x[SSSE3-140]
_ = x[STIBP-141]
_ = x[STIBP_ALWAYSON-142]
_ = x[STOSB_SHORT-143]
_ = x[SUCCOR-144]
_ = x[SVM-145]
_ = x[SVMDA-146]
_ = x[SVMFBASID-147]
_ = x[SVML-148]
_ = x[SVMNP-149]
_ = x[SVMPF-150]
_ = x[SVMPFT-151]
_ = x[SYSCALL-152]
_ = x[SYSEE-153]
_ = x[TBM-154]
_ = x[TLB_FLUSH_NESTED-155]
_ = x[TME-156]
_ = x[TOPEXT-157]
_ = x[TSCRATEMSR-158]
_ = x[TSXLDTRK-159]
_ = x[VAES-160]
_ = x[VMCBCLEAN-161]
_ = x[VMPL-162]
_ = x[VMSA_REGPROT-163]
_ = x[VMX-164]
_ = x[VPCLMULQDQ-165]
_ = x[VTE-166]
_ = x[WAITPKG-167]
_ = x[WBNOINVD-168]
_ = x[X87-169]
_ = x[XGETBV1-170]
_ = x[XOP-171]
_ = x[XSAVE-172]
_ = x[XSAVEC-173]
_ = x[XSAVEOPT-174]
_ = x[XSAVES-175]
_ = x[AESARM-176]
_ = x[ARMCPUID-177]
_ = x[ASIMD-178]
_ = x[ASIMDDP-179]
_ = x[ASIMDHP-180]
_ = x[ASIMDRDM-181]
_ = x[ATOMICS-182]
_ = x[CRC32-183]
_ = x[DCPOP-184]
_ = x[EVTSTRM-185]
_ = x[FCMA-186]
_ = x[FP-187]
_ = x[FPHP-188]
_ = x[GPA-189]
_ = x[JSCVT-190]
_ = x[LRCPC-191]
_ = x[PMULL-192]
_ = x[SHA1-193]
_ = x[SHA2-194]
_ = x[SHA3-195]
_ = x[SHA512-196]
_ = x[SM3-197]
_ = x[SM4-198]
_ = x[SVE-199]
_ = x[lastID-200]
_ = x[APX_F-9]
_ = x[AVX-10]
_ = x[AVX10-11]
_ = x[AVX10_128-12]
_ = x[AVX10_256-13]
_ = x[AVX10_512-14]
_ = x[AVX2-15]
_ = x[AVX512BF16-16]
_ = x[AVX512BITALG-17]
_ = x[AVX512BW-18]
_ = x[AVX512CD-19]
_ = x[AVX512DQ-20]
_ = x[AVX512ER-21]
_ = x[AVX512F-22]
_ = x[AVX512FP16-23]
_ = x[AVX512IFMA-24]
_ = x[AVX512PF-25]
_ = x[AVX512VBMI-26]
_ = x[AVX512VBMI2-27]
_ = x[AVX512VL-28]
_ = x[AVX512VNNI-29]
_ = x[AVX512VP2INTERSECT-30]
_ = x[AVX512VPOPCNTDQ-31]
_ = x[AVXIFMA-32]
_ = x[AVXNECONVERT-33]
_ = x[AVXSLOW-34]
_ = x[AVXVNNI-35]
_ = x[AVXVNNIINT8-36]
_ = x[BHI_CTRL-37]
_ = x[BMI1-38]
_ = x[BMI2-39]
_ = x[CETIBT-40]
_ = x[CETSS-41]
_ = x[CLDEMOTE-42]
_ = x[CLMUL-43]
_ = x[CLZERO-44]
_ = x[CMOV-45]
_ = x[CMPCCXADD-46]
_ = x[CMPSB_SCADBS_SHORT-47]
_ = x[CMPXCHG8-48]
_ = x[CPBOOST-49]
_ = x[CPPC-50]
_ = x[CX16-51]
_ = x[EFER_LMSLE_UNS-52]
_ = x[ENQCMD-53]
_ = x[ERMS-54]
_ = x[F16C-55]
_ = x[FLUSH_L1D-56]
_ = x[FMA3-57]
_ = x[FMA4-58]
_ = x[FP128-59]
_ = x[FP256-60]
_ = x[FSRM-61]
_ = x[FXSR-62]
_ = x[FXSROPT-63]
_ = x[GFNI-64]
_ = x[HLE-65]
_ = x[HRESET-66]
_ = x[HTT-67]
_ = x[HWA-68]
_ = x[HYBRID_CPU-69]
_ = x[HYPERVISOR-70]
_ = x[IA32_ARCH_CAP-71]
_ = x[IA32_CORE_CAP-72]
_ = x[IBPB-73]
_ = x[IBRS-74]
_ = x[IBRS_PREFERRED-75]
_ = x[IBRS_PROVIDES_SMP-76]
_ = x[IBS-77]
_ = x[IBSBRNTRGT-78]
_ = x[IBSFETCHSAM-79]
_ = x[IBSFFV-80]
_ = x[IBSOPCNT-81]
_ = x[IBSOPCNTEXT-82]
_ = x[IBSOPSAM-83]
_ = x[IBSRDWROPCNT-84]
_ = x[IBSRIPINVALIDCHK-85]
_ = x[IBS_FETCH_CTLX-86]
_ = x[IBS_OPDATA4-87]
_ = x[IBS_OPFUSE-88]
_ = x[IBS_PREVENTHOST-89]
_ = x[IBS_ZEN4-90]
_ = x[IDPRED_CTRL-91]
_ = x[INT_WBINVD-92]
_ = x[INVLPGB-93]
_ = x[KEYLOCKER-94]
_ = x[KEYLOCKERW-95]
_ = x[LAHF-96]
_ = x[LAM-97]
_ = x[LBRVIRT-98]
_ = x[LZCNT-99]
_ = x[MCAOVERFLOW-100]
_ = x[MCDT_NO-101]
_ = x[MCOMMIT-102]
_ = x[MD_CLEAR-103]
_ = x[MMX-104]
_ = x[MMXEXT-105]
_ = x[MOVBE-106]
_ = x[MOVDIR64B-107]
_ = x[MOVDIRI-108]
_ = x[MOVSB_ZL-109]
_ = x[MOVU-110]
_ = x[MPX-111]
_ = x[MSRIRC-112]
_ = x[MSRLIST-113]
_ = x[MSR_PAGEFLUSH-114]
_ = x[NRIPS-115]
_ = x[NX-116]
_ = x[OSXSAVE-117]
_ = x[PCONFIG-118]
_ = x[POPCNT-119]
_ = x[PPIN-120]
_ = x[PREFETCHI-121]
_ = x[PSFD-122]
_ = x[RDPRU-123]
_ = x[RDRAND-124]
_ = x[RDSEED-125]
_ = x[RDTSCP-126]
_ = x[RRSBA_CTRL-127]
_ = x[RTM-128]
_ = x[RTM_ALWAYS_ABORT-129]
_ = x[SERIALIZE-130]
_ = x[SEV-131]
_ = x[SEV_64BIT-132]
_ = x[SEV_ALTERNATIVE-133]
_ = x[SEV_DEBUGSWAP-134]
_ = x[SEV_ES-135]
_ = x[SEV_RESTRICTED-136]
_ = x[SEV_SNP-137]
_ = x[SGX-138]
_ = x[SGXLC-139]
_ = x[SHA-140]
_ = x[SME-141]
_ = x[SME_COHERENT-142]
_ = x[SPEC_CTRL_SSBD-143]
_ = x[SRBDS_CTRL-144]
_ = x[SSE-145]
_ = x[SSE2-146]
_ = x[SSE3-147]
_ = x[SSE4-148]
_ = x[SSE42-149]
_ = x[SSE4A-150]
_ = x[SSSE3-151]
_ = x[STIBP-152]
_ = x[STIBP_ALWAYSON-153]
_ = x[STOSB_SHORT-154]
_ = x[SUCCOR-155]
_ = x[SVM-156]
_ = x[SVMDA-157]
_ = x[SVMFBASID-158]
_ = x[SVML-159]
_ = x[SVMNP-160]
_ = x[SVMPF-161]
_ = x[SVMPFT-162]
_ = x[SYSCALL-163]
_ = x[SYSEE-164]
_ = x[TBM-165]
_ = x[TDX_GUEST-166]
_ = x[TLB_FLUSH_NESTED-167]
_ = x[TME-168]
_ = x[TOPEXT-169]
_ = x[TSCRATEMSR-170]
_ = x[TSXLDTRK-171]
_ = x[VAES-172]
_ = x[VMCBCLEAN-173]
_ = x[VMPL-174]
_ = x[VMSA_REGPROT-175]
_ = x[VMX-176]
_ = x[VPCLMULQDQ-177]
_ = x[VTE-178]
_ = x[WAITPKG-179]
_ = x[WBNOINVD-180]
_ = x[WRMSRNS-181]
_ = x[X87-182]
_ = x[XGETBV1-183]
_ = x[XOP-184]
_ = x[XSAVE-185]
_ = x[XSAVEC-186]
_ = x[XSAVEOPT-187]
_ = x[XSAVES-188]
_ = x[AESARM-189]
_ = x[ARMCPUID-190]
_ = x[ASIMD-191]
_ = x[ASIMDDP-192]
_ = x[ASIMDHP-193]
_ = x[ASIMDRDM-194]
_ = x[ATOMICS-195]
_ = x[CRC32-196]
_ = x[DCPOP-197]
_ = x[EVTSTRM-198]
_ = x[FCMA-199]
_ = x[FP-200]
_ = x[FPHP-201]
_ = x[GPA-202]
_ = x[JSCVT-203]
_ = x[LRCPC-204]
_ = x[PMULL-205]
_ = x[SHA1-206]
_ = x[SHA2-207]
_ = x[SHA3-208]
_ = x[SHA512-209]
_ = x[SM3-210]
_ = x[SM4-211]
_ = x[SVE-212]
_ = x[lastID-213]
_ = x[firstID-0]
}
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8BMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4INT_WBINVDINVLPGBLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 65, 69, 79, 91, 99, 107, 115, 123, 130, 140, 150, 158, 168, 179, 187, 197, 215, 230, 237, 249, 256, 263, 274, 278, 282, 288, 293, 301, 306, 312, 316, 325, 343, 351, 358, 362, 366, 380, 386, 390, 394, 403, 407, 411, 416, 421, 425, 429, 436, 440, 443, 449, 452, 455, 465, 475, 488, 501, 505, 509, 523, 540, 543, 553, 564, 570, 578, 589, 597, 609, 625, 639, 650, 660, 675, 683, 693, 700, 704, 707, 714, 719, 730, 737, 744, 752, 755, 761, 766, 775, 782, 790, 794, 797, 803, 816, 821, 823, 830, 837, 843, 847, 856, 860, 865, 871, 877, 883, 886, 902, 911, 914, 923, 938, 951, 957, 971, 978, 981, 986, 989, 992, 1004, 1018, 1028, 1031, 1035, 1039, 1043, 1048, 1053, 1058, 1063, 1077, 1088, 1094, 1097, 1102, 1111, 1115, 1120, 1125, 1131, 1138, 1143, 1146, 1162, 1165, 1171, 1181, 1189, 1193, 1202, 1206, 1218, 1221, 1231, 1234, 1241, 1249, 1252, 1259, 1262, 1267, 1273, 1281, 1287, 1293, 1301, 1306, 1313, 1320, 1328, 1335, 1340, 1345, 1352, 1356, 1358, 1362, 1365, 1370, 1375, 1380, 1384, 1388, 1392, 1398, 1401, 1404, 1407, 1413}
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 67, 70, 75, 84, 93, 102, 106, 116, 128, 136, 144, 152, 160, 167, 177, 187, 195, 205, 216, 224, 234, 252, 267, 274, 286, 293, 300, 311, 319, 323, 327, 333, 338, 346, 351, 357, 361, 370, 388, 396, 403, 407, 411, 425, 431, 435, 439, 448, 452, 456, 461, 466, 470, 474, 481, 485, 488, 494, 497, 500, 510, 520, 533, 546, 550, 554, 568, 585, 588, 598, 609, 615, 623, 634, 642, 654, 670, 684, 695, 705, 720, 728, 739, 749, 756, 765, 775, 779, 782, 789, 794, 805, 812, 819, 827, 830, 836, 841, 850, 857, 865, 869, 872, 878, 885, 898, 903, 905, 912, 919, 925, 929, 938, 942, 947, 953, 959, 965, 975, 978, 994, 1003, 1006, 1015, 1030, 1043, 1049, 1063, 1070, 1073, 1078, 1081, 1084, 1096, 1110, 1120, 1123, 1127, 1131, 1135, 1140, 1145, 1150, 1155, 1169, 1180, 1186, 1189, 1194, 1203, 1207, 1212, 1217, 1223, 1230, 1235, 1238, 1247, 1263, 1266, 1272, 1282, 1290, 1294, 1303, 1307, 1319, 1322, 1332, 1335, 1342, 1350, 1357, 1360, 1367, 1370, 1375, 1381, 1389, 1395, 1401, 1409, 1414, 1421, 1428, 1436, 1443, 1448, 1453, 1460, 1464, 1466, 1470, 1473, 1478, 1483, 1488, 1492, 1496, 1500, 1506, 1509, 1512, 1515, 1521}
func (i FeatureID) String() string {
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
+15
View File
@@ -534,6 +534,21 @@ BenchmarkGaloisXor128K-160 862.02 7905.00 9.17x
BenchmarkGaloisXor1M-160 784.60 6296.65 8.03x
```
# Legal
> None of section below is legal advice. Seek your own legal counsel.
> As stated by the [LICENSE](LICENSE) the authors will not be held reliable for any use of this library.
> Users are encouraged to independently verify they comply with all legal requirements.
As can be seen in [recent news](https://www.datanami.com/2023/10/16/cloudera-hit-with-240-million-judgement-over-erasure-coding/)
there has been lawsuits related to possible patents of aspects of erasure coding functionality.
As a possible mitigation it is possible to use the tag `nopshufb` when compiling any code which includes this package.
This will remove all inclusion and use of `PSHUFB` and equivalent on other platforms.
This is done by adding `-tags=nopshufb` to `go build` and similar commands that produce binary output.
The removed code may not be infringing and even after `-tags=nopshufb` there may still be infringing code left.
# Links
* [Backblaze Open Sources Reed-Solomon Erasure Coding Source Code](https://www.backblaze.com/blog/reed-solomon/).
+16 -9
View File
@@ -6,7 +6,9 @@
package reedsolomon
import "encoding/binary"
import (
"encoding/binary"
)
const (
// The number of elements in the field.
@@ -60,21 +62,17 @@ var logTable = [fieldSize]byte{
/**
* Inverse of the logarithm table. Maps integer logarithms
* to members of the field. There is no entry for 255
* because the highest log is 254.
* to members of the field. Entry 255 is the same as entry 0 sue to mod 255.
*
* This table was generated by `go run gentables.go`
* Table has been truncated to 256 bytes, since no lookups are bigger.
*/
var expTable = []byte{0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x3, 0x6, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46, 0x8c, 0x5, 0xa, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0xf, 0x1e, 0x3c, 0x78, 0xf0, 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0xd, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x7, 0xe, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x9, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0xb, 0x16, 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x3, 0x6, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46, 0x8c, 0x5, 0xa, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0xf, 0x1e, 0x3c, 0x78, 0xf0, 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0xd, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x7, 0xe, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x9, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0xb, 0x16, 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e}
var expTable = [256]byte{0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x3, 0x6, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, 0x46, 0x8c, 0x5, 0xa, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0xf, 0x1e, 0x3c, 0x78, 0xf0, 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0xd, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x7, 0xe, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x9, 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0xb, 0x16, 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x1}
func galAdd(a, b byte) byte {
return a ^ b
}
func galSub(a, b byte) byte {
return a ^ b
}
// Table from https://github.com/templexxx/reedsolomon
var invTable = [256]byte{0x0, 0x1, 0x8e, 0xf4, 0x47, 0xa7, 0x7a, 0xba, 0xad, 0x9d, 0xdd, 0x98, 0x3d, 0xaa, 0x5d, 0x96, 0xd8, 0x72, 0xc0, 0x58, 0xe0, 0x3e, 0x4c, 0x66, 0x90, 0xde, 0x55, 0x80, 0xa0, 0x83, 0x4b, 0x2a, 0x6c, 0xed, 0x39, 0x51, 0x60, 0x56, 0x2c, 0x8a, 0x70, 0xd0, 0x1f, 0x4a, 0x26, 0x8b, 0x33, 0x6e, 0x48, 0x89, 0x6f, 0x2e, 0xa4, 0xc3, 0x40, 0x5e, 0x50, 0x22, 0xcf, 0xa9, 0xab, 0xc, 0x15, 0xe1, 0x36, 0x5f, 0xf8, 0xd5, 0x92, 0x4e, 0xa6, 0x4, 0x30, 0x88, 0x2b, 0x1e, 0x16, 0x67, 0x45, 0x93, 0x38, 0x23, 0x68, 0x8c, 0x81, 0x1a, 0x25, 0x61, 0x13, 0xc1, 0xcb, 0x63, 0x97, 0xe, 0x37, 0x41, 0x24, 0x57, 0xca, 0x5b, 0xb9, 0xc4, 0x17, 0x4d, 0x52, 0x8d, 0xef, 0xb3, 0x20, 0xec, 0x2f, 0x32, 0x28, 0xd1, 0x11, 0xd9, 0xe9, 0xfb, 0xda, 0x79, 0xdb, 0x77, 0x6, 0xbb, 0x84, 0xcd, 0xfe, 0xfc, 0x1b, 0x54, 0xa1, 0x1d, 0x7c, 0xcc, 0xe4, 0xb0, 0x49, 0x31, 0x27, 0x2d, 0x53, 0x69, 0x2, 0xf5, 0x18, 0xdf, 0x44, 0x4f, 0x9b, 0xbc, 0xf, 0x5c, 0xb, 0xdc, 0xbd, 0x94, 0xac, 0x9, 0xc7, 0xa2, 0x1c, 0x82, 0x9f, 0xc6, 0x34, 0xc2, 0x46, 0x5, 0xce, 0x3b, 0xd, 0x3c, 0x9c, 0x8, 0xbe, 0xb7, 0x87, 0xe5, 0xee, 0x6b, 0xeb, 0xf2, 0xbf, 0xaf, 0xc5, 0x64, 0x7, 0x7b, 0x95, 0x9a, 0xae, 0xb6, 0x12, 0x59, 0xa5, 0x35, 0x65, 0xb8, 0xa3, 0x9e, 0xd2, 0xf7, 0x62, 0x5a, 0x85, 0x7d, 0xa8, 0x3a, 0x29, 0x71, 0xc8, 0xf6, 0xf9, 0x43, 0xd7, 0xd6, 0x10, 0x73, 0x76, 0x78, 0x99, 0xa, 0x19, 0x91, 0x14, 0x3f, 0xe6, 0xf0, 0x86, 0xb1, 0xe2, 0xf1, 0xfa, 0x74, 0xf3, 0xb4, 0x6d, 0x21, 0xb2, 0x6a, 0xe3, 0xe7, 0xb5, 0xea, 0x3, 0x8f, 0xd3, 0xc9, 0x42, 0xd4, 0xe8, 0x75, 0x7f, 0xff, 0x7e, 0xfd}
@@ -881,6 +879,15 @@ func galDivide(a, b byte) byte {
if logResult < 0 {
logResult += 255
}
return expTable[uint8(logResult)]
}
// galOneOver is the same as galDivide(1, a).
func galOneOver(a byte) byte {
if a == 0 {
panic("Argument 'divisor' is 0")
}
logResult := logTable[a] ^ 255
return expTable[logResult]
}
@@ -900,7 +907,7 @@ func galExp(a byte, n int) byte {
for logResult >= 255 {
logResult -= 255
}
return expTable[logResult]
return expTable[uint8(logResult)]
}
func genAvx2Matrix(matrixRows [][]byte, inputs, inIdx, outputs int, dst []byte) []byte {
+3 -11
View File
@@ -1,10 +1,11 @@
//go:build !noasm && !appengine && !gccgo
// +build !noasm,!appengine,!gccgo
//go:build !noasm && !appengine && !gccgo && !nopshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
package reedsolomon
const pshufb = true
//go:noescape
func galMulSSSE3(low, high, in, out []byte)
@@ -17,21 +18,12 @@ func galMulAVX2Xor(low, high, in, out []byte)
//go:noescape
func galMulAVX2(low, high, in, out []byte)
//go:noescape
func sSE2XorSlice(in, out []byte)
//go:noescape
func galMulAVX2Xor_64(low, high, in, out []byte)
//go:noescape
func galMulAVX2_64(low, high, in, out []byte)
//go:noescape
func sSE2XorSlice_64(in, out []byte)
//go:noescape
func avx2XorSlice_64(in, out []byte)
// This is what the assembler routines do in blocks of 16 bytes:
/*
func galMulSSSE3(low, high, in, out []byte) {
+1 -85
View File
@@ -1,6 +1,7 @@
//+build !noasm
//+build !appengine
//+build !gccgo
//+build !nopshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
@@ -215,28 +216,6 @@ done_avx2:
VZEROUPPER
RET
// func sSE2XorSlice(in, out []byte)
TEXT ·sSE2XorSlice(SB), 7, $0
MOVQ in+0(FP), SI // SI: &in
MOVQ in_len+8(FP), R9 // R9: len(in)
MOVQ out+24(FP), DX // DX: &out
SHRQ $4, R9 // len(in) / 16
CMPQ R9, $0
JEQ done_xor_sse2
loopback_xor_sse2:
MOVOU (SI), X0 // in[x]
MOVOU (DX), X1 // out[x]
PXOR X0, X1
MOVOU X1, (DX)
ADDQ $16, SI // in+=16
ADDQ $16, DX // out+=16
SUBQ $1, R9
JNZ loopback_xor_sse2
done_xor_sse2:
RET
// func galMulAVX2Xor_64(low, high, in, out []byte)
TEXT ·galMulAVX2Xor_64(SB), 7, $0
MOVQ low+0(FP), SI // SI: &low
@@ -329,66 +308,3 @@ loopback_avx2_64:
done_avx2_64:
VZEROUPPER
RET
// func sSE2XorSlice_64(in, out []byte)
TEXT ·sSE2XorSlice_64(SB), 7, $0
MOVQ in+0(FP), SI // SI: &in
MOVQ in_len+8(FP), R9 // R9: len(in)
MOVQ out+24(FP), DX // DX: &out
SHRQ $6, R9 // len(in) / 64
CMPQ R9, $0
JEQ done_xor_sse2_64
loopback_xor_sse2_64:
MOVOU (SI), X0 // in[x]
MOVOU 16(SI), X2 // in[x]
MOVOU 32(SI), X4 // in[x]
MOVOU 48(SI), X6 // in[x]
MOVOU (DX), X1 // out[x]
MOVOU 16(DX), X3 // out[x]
MOVOU 32(DX), X5 // out[x]
MOVOU 48(DX), X7 // out[x]
PXOR X0, X1
PXOR X2, X3
PXOR X4, X5
PXOR X6, X7
MOVOU X1, (DX)
MOVOU X3, 16(DX)
MOVOU X5, 32(DX)
MOVOU X7, 48(DX)
ADDQ $64, SI // in+=64
ADDQ $64, DX // out+=64
SUBQ $1, R9
JNZ loopback_xor_sse2_64
done_xor_sse2_64:
RET
// func avx2XorSlice_64(in, out []byte)
TEXT ·avx2XorSlice_64(SB), 7, $0
MOVQ in+0(FP), SI // SI: &in
MOVQ in_len+8(FP), R9 // R9: len(in)
MOVQ out+24(FP), DX // DX: &out
SHRQ $6, R9 // len(in) / 64
CMPQ R9, $0
JEQ done_xor_avx2_64
loopback_xor_avx2_64:
VMOVDQU (SI), Y0
VMOVDQU 32(SI), Y2
VMOVDQU (DX), Y1
VMOVDQU 32(DX), Y3
VPXOR Y0, Y1, Y1
VPXOR Y2, Y3, Y3
VMOVDQU Y1, (DX)
VMOVDQU Y3, 32(DX)
ADDQ $64, SI // in+=64
ADDQ $64, DX // out+=64
SUBQ $1, R9
JNZ loopback_xor_avx2_64
VZEROUPPER
done_xor_avx2_64:
RET
+5 -21
View File
@@ -1,20 +1,18 @@
//go:build !noasm && !appengine && !gccgo
// +build !noasm,!appengine,!gccgo
//go:build !noasm && !appengine && !gccgo && !nopshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
// Copyright 2017, Minio, Inc.
package reedsolomon
const pshufb = true
//go:noescape
func galMulNEON(low, high, in, out []byte)
//go:noescape
func galMulXorNEON(low, high, in, out []byte)
//go:noescape
func galXorNEON(in, out []byte)
func galMulSlice(c byte, in, out []byte, o *options) {
if c == 1 {
copy(out, in)
@@ -51,20 +49,6 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}
// simple slice xor
func sliceXor(in, out []byte, o *options) {
galXorNEON(in, out)
done := (len(in) >> 5) << 5
remain := len(in) - done
if remain > 0 {
for i := done; i < len(in); i++ {
out[i] ^= in[i]
}
}
}
// 4-way butterfly
func ifftDIT4(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe, o *options) {
ifftDIT4Ref(work, dist, log_m01, log_m23, log_m02, o)
@@ -90,7 +74,7 @@ func fftDIT2(x, y []byte, log_m ffe, o *options) {
// Reference version:
refMulAdd(x, y, log_m)
// 64 byte aligned, always full.
galXorNEON(x, y)
xorSliceNEON(x, y)
}
// 2-way butterfly forward
@@ -103,7 +87,7 @@ func fftDIT28(x, y []byte, log_m ffe8, o *options) {
// 2-way butterfly
func ifftDIT2(x, y []byte, log_m ffe, o *options) {
// 64 byte aligned, always full.
galXorNEON(x, y)
xorSliceNEON(x, y)
// Reference version:
refMulAdd(x, y, log_m)
}
+1 -26
View File
@@ -1,6 +1,7 @@
//+build !noasm
//+build !appengine
//+build !gccgo
//+build !nopshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
// Copyright 2017, Minio, Inc.
@@ -99,29 +100,3 @@ loopXor:
completeXor:
RET
// func galXorNEON(in, out []byte)
TEXT ·galXorNEON(SB), 7, $0
MOVD in_base+0(FP), R1
MOVD in_len+8(FP), R2 // length of message
MOVD out_base+24(FP), R5
SUBS $32, R2
BMI completeXor
loopXor:
// Main loop
VLD1.P 32(R1), [V0.B16, V1.B16]
VLD1 (R5), [V20.B16, V21.B16]
VEOR V20.B16, V0.B16, V4.B16
VEOR V21.B16, V1.B16, V5.B16
// Store result
VST1.P [V4.D2, V5.D2], 32(R5)
SUBS $32, R2
BPL loopXor
completeXor:
RET
+10 -1
View File
@@ -1,11 +1,20 @@
// Code generated by command: go run gen.go -out ../galois_gen_amd64.s -stubs ../galois_gen_amd64.go -pkg=reedsolomon. DO NOT EDIT.
//go:build !appengine && !noasm && !nogen && gc
//go:build !appengine && !noasm && !nogen && !nopshufb && gc
package reedsolomon
func _dummy_()
//go:noescape
func sSE2XorSlice(in []byte, out []byte)
//go:noescape
func sSE2XorSlice_64(in []byte, out []byte)
//go:noescape
func avx2XorSlice_64(in []byte, out []byte)
// mulAvxTwo_1x1 takes 1 inputs and produces 1 outputs.
// The output is initialized to 0.
//
+93 -1
View File
@@ -1,6 +1,6 @@
// Code generated by command: go run gen.go -out ../galois_gen_amd64.s -stubs ../galois_gen_amd64.go -pkg=reedsolomon. DO NOT EDIT.
//go:build !appengine && !noasm && !nogen && gc
//go:build !appengine && !noasm && !nogen && !nopshufb && gc
#include "textflag.h"
@@ -18,6 +18,98 @@ TEXT ·_dummy_(SB), $0
#endif
RET
// sSE2XorSlice will XOR in with out and store in out.
// Processes 16 bytes/loop.
// func sSE2XorSlice(in []byte, out []byte)
// Requires: SSE2
TEXT ·sSE2XorSlice(SB), $0-48
MOVQ in_base+0(FP), AX
MOVQ out_base+24(FP), CX
MOVQ in_len+8(FP), DX
SHRQ $0x04, DX
JZ end
loop:
MOVOU (AX), X0
MOVOU (CX), X1
PXOR X0, X1
MOVOU X1, (CX)
ADDQ $0x10, AX
ADDQ $0x10, CX
DECQ DX
JNZ loop
end:
RET
// sSE2XorSlice_64 will XOR in with out and store in out.
// Processes 64 bytes/loop.
// func sSE2XorSlice_64(in []byte, out []byte)
// Requires: SSE2
TEXT ·sSE2XorSlice_64(SB), $0-48
MOVQ in_base+0(FP), AX
MOVQ out_base+24(FP), CX
MOVQ in_len+8(FP), DX
SHRQ $0x06, DX
JZ end
loop:
MOVOU (AX), X0
MOVOU 16(AX), X2
MOVOU 32(AX), X4
MOVOU 48(AX), X6
MOVOU (CX), X1
MOVOU 16(CX), X3
MOVOU 32(CX), X5
MOVOU 48(CX), X7
PXOR X0, X1
PXOR X2, X3
PXOR X4, X5
PXOR X6, X7
MOVOU X1, (CX)
MOVOU X3, 16(CX)
MOVOU X5, 32(CX)
MOVOU X7, 48(CX)
ADDQ $0x40, AX
ADDQ $0x40, CX
DECQ DX
JNZ loop
end:
RET
// avx2XorSlice_64 will XOR in with out and store in out.
// Processes 64 bytes/loop.
// func avx2XorSlice_64(in []byte, out []byte)
// Requires: AVX, AVX2
TEXT ·avx2XorSlice_64(SB), $0-48
MOVQ in_base+0(FP), AX
MOVQ out_base+24(FP), CX
MOVQ in_len+8(FP), DX
SHRQ $0x06, DX
JZ end
loop:
VMOVDQU (AX), Y0
VMOVDQU 32(AX), Y2
VMOVDQU (CX), Y1
VMOVDQU 32(CX), Y3
VPXOR Y0, Y1, Y1
VPXOR Y2, Y3, Y3
VMOVDQU Y1, (CX)
VMOVDQU Y3, 32(CX)
ADDQ $0x40, AX
ADDQ $0x40, CX
DECQ DX
JNZ loop
end:
VZEROUPPER
RET
// func mulAvxTwo_1x1(matrix []byte, in [][]byte, out [][]byte, start int, n int)
// Requires: AVX, AVX2, SSE2
TEXT ·mulAvxTwo_1x1(SB), NOSPLIT, $0-88
-1
View File
@@ -1,5 +1,4 @@
//go:build !amd64 || noasm || appengine || gccgo || nogen
// +build !amd64 noasm appengine gccgo nogen
package reedsolomon
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,7 +1,7 @@
// Code generated by command: go generate gen.go. DO NOT EDIT.
//go:build !appengine && !noasm && gc && !nogen
// +build !appengine,!noasm,gc,!nogen
//go:build !appengine && !noasm && gc && !nogen && !nopshufb
// +build !appengine,!noasm,gc,!nogen,!nopshufb
package reedsolomon
@@ -0,0 +1,697 @@
// Code generated by command: go generate gen.go. DO NOT EDIT.
//go:build !appengine && !noasm && gc && !nogen && nopshufb
// +build !appengine,!noasm,gc,!nogen,nopshufb
package reedsolomon
import (
"fmt"
)
const (
avx2CodeGen = true
maxAvx2Inputs = 10
maxAvx2Outputs = 10
minAvx2Size = 64
avxSizeMask = maxInt - (minAvx2Size - 1)
)
func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int { panic(`no pshufb`) }
func galMulSlicesAvx2Xor(matrix []byte, in, out [][]byte, start, stop int) int { panic(`no pshufb`) }
func galMulSlicesGFNI(matrix []uint64, in, out [][]byte, start, stop int) int {
n := (stop - start) & avxSizeMask
switch len(in) {
case 1:
switch len(out) {
case 1:
mulGFNI_1x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_1x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_1x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_1x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_1x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_1x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_1x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_1x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_1x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_1x10_64(matrix, in, out, start, n)
return n
}
case 2:
switch len(out) {
case 1:
mulGFNI_2x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_2x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_2x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_2x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_2x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_2x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_2x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_2x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_2x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_2x10_64(matrix, in, out, start, n)
return n
}
case 3:
switch len(out) {
case 1:
mulGFNI_3x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_3x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_3x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_3x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_3x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_3x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_3x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_3x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_3x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_3x10_64(matrix, in, out, start, n)
return n
}
case 4:
switch len(out) {
case 1:
mulGFNI_4x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_4x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_4x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_4x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_4x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_4x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_4x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_4x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_4x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_4x10_64(matrix, in, out, start, n)
return n
}
case 5:
switch len(out) {
case 1:
mulGFNI_5x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_5x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_5x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_5x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_5x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_5x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_5x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_5x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_5x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_5x10_64(matrix, in, out, start, n)
return n
}
case 6:
switch len(out) {
case 1:
mulGFNI_6x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_6x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_6x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_6x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_6x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_6x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_6x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_6x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_6x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_6x10_64(matrix, in, out, start, n)
return n
}
case 7:
switch len(out) {
case 1:
mulGFNI_7x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_7x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_7x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_7x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_7x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_7x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_7x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_7x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_7x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_7x10_64(matrix, in, out, start, n)
return n
}
case 8:
switch len(out) {
case 1:
mulGFNI_8x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_8x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_8x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_8x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_8x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_8x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_8x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_8x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_8x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_8x10_64(matrix, in, out, start, n)
return n
}
case 9:
switch len(out) {
case 1:
mulGFNI_9x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_9x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_9x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_9x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_9x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_9x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_9x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_9x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_9x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_9x10_64(matrix, in, out, start, n)
return n
}
case 10:
switch len(out) {
case 1:
mulGFNI_10x1_64(matrix, in, out, start, n)
return n
case 2:
mulGFNI_10x2_64(matrix, in, out, start, n)
return n
case 3:
mulGFNI_10x3_64(matrix, in, out, start, n)
return n
case 4:
mulGFNI_10x4_64(matrix, in, out, start, n)
return n
case 5:
mulGFNI_10x5_64(matrix, in, out, start, n)
return n
case 6:
mulGFNI_10x6_64(matrix, in, out, start, n)
return n
case 7:
mulGFNI_10x7_64(matrix, in, out, start, n)
return n
case 8:
mulGFNI_10x8_64(matrix, in, out, start, n)
return n
case 9:
mulGFNI_10x9_64(matrix, in, out, start, n)
return n
case 10:
mulGFNI_10x10_64(matrix, in, out, start, n)
return n
}
}
panic(fmt.Sprintf("unhandled size: %dx%d", len(in), len(out)))
}
func galMulSlicesGFNIXor(matrix []uint64, in, out [][]byte, start, stop int) int {
n := (stop - start) & avxSizeMask
switch len(in) {
case 1:
switch len(out) {
case 1:
mulGFNI_1x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_1x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_1x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_1x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_1x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_1x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_1x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_1x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_1x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_1x10_64Xor(matrix, in, out, start, n)
return n
}
case 2:
switch len(out) {
case 1:
mulGFNI_2x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_2x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_2x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_2x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_2x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_2x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_2x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_2x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_2x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_2x10_64Xor(matrix, in, out, start, n)
return n
}
case 3:
switch len(out) {
case 1:
mulGFNI_3x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_3x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_3x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_3x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_3x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_3x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_3x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_3x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_3x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_3x10_64Xor(matrix, in, out, start, n)
return n
}
case 4:
switch len(out) {
case 1:
mulGFNI_4x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_4x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_4x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_4x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_4x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_4x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_4x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_4x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_4x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_4x10_64Xor(matrix, in, out, start, n)
return n
}
case 5:
switch len(out) {
case 1:
mulGFNI_5x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_5x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_5x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_5x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_5x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_5x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_5x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_5x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_5x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_5x10_64Xor(matrix, in, out, start, n)
return n
}
case 6:
switch len(out) {
case 1:
mulGFNI_6x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_6x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_6x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_6x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_6x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_6x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_6x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_6x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_6x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_6x10_64Xor(matrix, in, out, start, n)
return n
}
case 7:
switch len(out) {
case 1:
mulGFNI_7x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_7x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_7x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_7x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_7x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_7x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_7x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_7x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_7x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_7x10_64Xor(matrix, in, out, start, n)
return n
}
case 8:
switch len(out) {
case 1:
mulGFNI_8x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_8x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_8x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_8x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_8x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_8x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_8x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_8x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_8x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_8x10_64Xor(matrix, in, out, start, n)
return n
}
case 9:
switch len(out) {
case 1:
mulGFNI_9x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_9x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_9x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_9x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_9x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_9x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_9x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_9x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_9x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_9x10_64Xor(matrix, in, out, start, n)
return n
}
case 10:
switch len(out) {
case 1:
mulGFNI_10x1_64Xor(matrix, in, out, start, n)
return n
case 2:
mulGFNI_10x2_64Xor(matrix, in, out, start, n)
return n
case 3:
mulGFNI_10x3_64Xor(matrix, in, out, start, n)
return n
case 4:
mulGFNI_10x4_64Xor(matrix, in, out, start, n)
return n
case 5:
mulGFNI_10x5_64Xor(matrix, in, out, start, n)
return n
case 6:
mulGFNI_10x6_64Xor(matrix, in, out, start, n)
return n
case 7:
mulGFNI_10x7_64Xor(matrix, in, out, start, n)
return n
case 8:
mulGFNI_10x8_64Xor(matrix, in, out, start, n)
return n
case 9:
mulGFNI_10x9_64Xor(matrix, in, out, start, n)
return n
case 10:
mulGFNI_10x10_64Xor(matrix, in, out, start, n)
return n
}
}
panic(fmt.Sprintf("unhandled size: %dx%d", len(in), len(out)))
}
+3 -9
View File
@@ -1,12 +1,11 @@
//go:build (!amd64 || noasm || appengine || gccgo) && (!arm64 || noasm || appengine || gccgo) && (!ppc64le || noasm || appengine || gccgo)
// +build !amd64 noasm appengine gccgo
// +build !arm64 noasm appengine gccgo
// +build !ppc64le noasm appengine gccgo
//go:build (!amd64 || noasm || appengine || gccgo) && (!arm64 || noasm || appengine || gccgo || nopshufb) && (!ppc64le || noasm || appengine || gccgo || nopshufb)
// Copyright 2015, Klaus Post, see LICENSE for details.
package reedsolomon
const pshufb = false
func galMulSlice(c byte, in, out []byte, o *options) {
out = out[:len(in)]
if c == 1 {
@@ -31,11 +30,6 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}
// simple slice xor
func sliceXor(in, out []byte, o *options) {
sliceXorGo(in, out, o)
}
func init() {
defaultOptions.useAVX512 = false
}
+146
View File
@@ -0,0 +1,146 @@
// Copyright 2015, Klaus Post, see LICENSE for details
//go:build nopshufb && !noasm
package reedsolomon
// bigSwitchover is the size where 64 bytes are processed per loop.
const bigSwitchover = 128
const pshufb = false
// simple slice xor
func sliceXor(in, out []byte, o *options) {
if o.useSSE2 {
if len(in) >= bigSwitchover {
if o.useAVX2 {
avx2XorSlice_64(in, out)
done := (len(in) >> 6) << 6
in = in[done:]
out = out[done:]
} else {
sSE2XorSlice_64(in, out)
done := (len(in) >> 6) << 6
in = in[done:]
out = out[done:]
}
}
if len(in) >= 16 {
sSE2XorSlice(in, out)
done := (len(in) >> 4) << 4
in = in[done:]
out = out[done:]
}
} else {
sliceXorGo(in, out, o)
return
}
out = out[:len(in)]
for i := range in {
out[i] ^= in[i]
}
}
func galMulSlice(c byte, in, out []byte, o *options) {
out = out[:len(in)]
if c == 1 {
copy(out, in)
return
}
mt := mulTable[c][:256]
for len(in) >= 4 {
ii := (*[4]byte)(in)
oo := (*[4]byte)(out)
oo[0] = mt[ii[0]]
oo[1] = mt[ii[1]]
oo[2] = mt[ii[2]]
oo[3] = mt[ii[3]]
in = in[4:]
out = out[4:]
}
for n, input := range in {
out[n] = mt[input]
}
}
func galMulSliceXor(c byte, in, out []byte, o *options) {
out = out[:len(in)]
if c == 1 {
sliceXor(in, out, o)
return
}
mt := mulTable[c][:256]
for len(in) >= 4 {
ii := (*[4]byte)(in)
oo := (*[4]byte)(out)
oo[0] ^= mt[ii[0]]
oo[1] ^= mt[ii[1]]
oo[2] ^= mt[ii[2]]
oo[3] ^= mt[ii[3]]
in = in[4:]
out = out[4:]
}
for n, input := range in {
out[n] ^= mt[input]
}
}
func init() {
defaultOptions.useAVX512 = false
}
// 4-way butterfly
func ifftDIT4(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe, o *options) {
ifftDIT4Ref(work, dist, log_m01, log_m23, log_m02, o)
}
// 4-way butterfly
func ifftDIT48(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe8, o *options) {
ifftDIT4Ref8(work, dist, log_m01, log_m23, log_m02, o)
}
// 4-way butterfly
func fftDIT4(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe, o *options) {
fftDIT4Ref(work, dist, log_m01, log_m23, log_m02, o)
}
// 4-way butterfly
func fftDIT48(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe8, o *options) {
fftDIT4Ref8(work, dist, log_m01, log_m23, log_m02, o)
}
// 2-way butterfly forward
func fftDIT2(x, y []byte, log_m ffe, o *options) {
// Reference version:
refMulAdd(x, y, log_m)
sliceXor(x, y, o)
}
// 2-way butterfly forward
func fftDIT28(x, y []byte, log_m ffe8, o *options) {
// Reference version:
refMulAdd8(x, y, log_m)
sliceXor(x, y, o)
}
// 2-way butterfly inverse
func ifftDIT2(x, y []byte, log_m ffe, o *options) {
// Reference version:
sliceXor(x, y, o)
refMulAdd(x, y, log_m)
}
// 2-way butterfly inverse
func ifftDIT28(x, y []byte, log_m ffe8, o *options) {
// Reference version:
sliceXor(x, y, o)
refMulAdd8(x, y, log_m)
}
func mulgf16(x, y []byte, log_m ffe, o *options) {
refMul(x, y, log_m)
}
func mulgf8(x, y []byte, log_m ffe8, o *options) {
refMul8(x, y, log_m)
}
+1 -2
View File
@@ -1,5 +1,4 @@
//go:build !amd64 || noasm || appengine || gccgo
// +build !amd64 noasm appengine gccgo
//go:build !amd64 || noasm || appengine || gccgo || pshufb
// Copyright 2020, Klaus Post, see LICENSE for details.
+3 -7
View File
@@ -1,11 +1,12 @@
//go:build !noasm && !appengine && !gccgo
// +build !noasm,!appengine,!gccgo
//go:build !noasm && !appengine && !gccgo && !nopshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
// Copyright 2018, Minio, Inc.
package reedsolomon
const pshufb = true
//go:noescape
func galMulPpc(low, high, in, out []byte)
@@ -66,11 +67,6 @@ func galMulSliceXor(c byte, in, out []byte, o *options) {
}
}
// slice galois add
func sliceXor(in, out []byte, o *options) {
sliceXorGo(in, out, o)
}
// 4-way butterfly
func ifftDIT4(work [][]byte, dist int, log_m01, log_m23, log_m02 ffe, o *options) {
ifftDIT4Ref(work, dist, log_m01, log_m23, log_m02, o)
+1
View File
@@ -1,6 +1,7 @@
//+build !noasm
//+build !appengine
//+build !gccgo
//+build !pshufb
// Copyright 2015, Klaus Post, see LICENSE for details.
// Copyright 2018, Minio, Inc.
+3 -3
View File
@@ -122,7 +122,7 @@ func (r *leopardFF16) Encode(shards [][]byte) error {
func (r *leopardFF16) encode(shards [][]byte) error {
shardSize := shardSize(shards)
if shardSize%64 != 0 {
return ErrShardSize
return ErrInvalidShardSize
}
m := ceilPow2(r.parityShards)
@@ -303,7 +303,7 @@ func (r *leopardFF16) Split(data []byte) ([][]byte, error) {
// Copy partial shards
copyFrom := data[perShard*fullShards : dataLen]
for i := range padding {
if len(copyFrom) <= 0 {
if len(copyFrom) == 0 {
break
}
copyFrom = copyFrom[copy(padding[i], copyFrom):]
@@ -409,7 +409,7 @@ func (r *leopardFF16) reconstruct(shards [][]byte, recoverAll bool) error {
shardSize := shardSize(shards)
if shardSize%64 != 0 {
return ErrShardSize
return ErrInvalidShardSize
}
m := ceilPow2(r.parityShards)
+3 -3
View File
@@ -134,7 +134,7 @@ func (r *leopardFF8) Encode(shards [][]byte) error {
func (r *leopardFF8) encode(shards [][]byte) error {
shardSize := shardSize(shards)
if shardSize%64 != 0 {
return ErrShardSize
return ErrInvalidShardSize
}
m := ceilPow2(r.parityShards)
@@ -344,7 +344,7 @@ func (r *leopardFF8) Split(data []byte) ([][]byte, error) {
// Copy partial shards
copyFrom := data[perShard*fullShards : dataLen]
for i := range padding {
if len(copyFrom) <= 0 {
if len(copyFrom) == 0 {
break
}
copyFrom = copyFrom[copy(padding[i], copyFrom):]
@@ -442,7 +442,7 @@ func (r *leopardFF8) reconstruct(shards [][]byte, recoverAll bool) error {
shardSize := shardSize(shards)
if shardSize%64 != 0 {
return ErrShardSize
return ErrInvalidShardSize
}
// Use only if we are missing less than 1/4 parity,
+4 -5
View File
@@ -67,11 +67,11 @@ var errColSizeMismatch = errors.New("column size is not the same for all rows")
func (m matrix) Check() error {
rows := len(m)
if rows <= 0 {
if rows == 0 {
return errInvalidRowSize
}
cols := len(m[0])
if cols <= 0 {
if cols == 0 {
return errInvalidColSize
}
@@ -175,8 +175,7 @@ func (m matrix) SwapRows(r1, r2 int) error {
return nil
}
// IsSquare will return true if the matrix is square
// and nil if the matrix is square
// IsSquare will return true if the matrix is square, otherwise false.
func (m matrix) IsSquare() bool {
return len(m) == len(m[0])
}
@@ -232,7 +231,7 @@ func (m matrix) gaussianElimination() error {
}
// Scale to 1.
if m[r][r] != 1 {
scale := galDivide(1, m[r][r])
scale := galOneOver(m[r][r])
for c := 0; c < columns; c++ {
m[r][c] = galMultiply(m[r][c], scale)
}
+77 -35
View File
@@ -13,6 +13,7 @@ package reedsolomon
import (
"bytes"
"errors"
"fmt"
"io"
"runtime"
"sync"
@@ -171,7 +172,8 @@ type reedSolomon struct {
tree *inversionTree
parity [][]byte
o options
mPool sync.Pool
mPoolSz int
mPool sync.Pool // Pool for temp matrices, etc
}
var _ = Extensions(&reedSolomon{})
@@ -281,7 +283,7 @@ func buildMatrixJerasure(dataShards, totalShards int) (matrix, error) {
// Multiply by the inverted matrix (same as vm.Multiply(vm[0:dataShards].Invert()))
if vm[i][i] != 1 {
// Make vm[i][i] = 1 by dividing the column by vm[i][i]
tmp := galDivide(1, vm[i][i])
tmp := galOneOver(vm[i][i])
for j := 0; j < totalShards; j++ {
vm[j][i] = galMultiply(vm[j][i], tmp)
}
@@ -301,7 +303,7 @@ func buildMatrixJerasure(dataShards, totalShards int) (matrix, error) {
for j := 0; j < dataShards; j++ {
tmp := vm[dataShards][j]
if tmp != 1 {
tmp = galDivide(1, tmp)
tmp = galOneOver(tmp)
for i := dataShards; i < totalShards; i++ {
vm[i][j] = galMultiply(vm[i][j], tmp)
}
@@ -312,7 +314,7 @@ func buildMatrixJerasure(dataShards, totalShards int) (matrix, error) {
for i := dataShards + 1; i < totalShards; i++ {
tmp := vm[i][0]
if tmp != 1 {
tmp = galDivide(1, tmp)
tmp = galOneOver(tmp)
for j := 0; j < dataShards; j++ {
vm[i][j] = galMultiply(vm[i][j], tmp)
}
@@ -475,11 +477,17 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
// Calculate what we want per round
r.o.perRound = cpuid.CPU.Cache.L2
if r.o.perRound < 128<<10 {
r.o.perRound = 128 << 10
}
divide := parityShards + 1
if avx2CodeGen && r.o.useAVX2 && (dataShards > maxAvx2Inputs || parityShards > maxAvx2Outputs) {
// Base on L1 cache if we have many inputs.
r.o.perRound = cpuid.CPU.Cache.L1D
if r.o.perRound < 32<<10 {
r.o.perRound = 32 << 10
}
divide = 0
if dataShards > maxAvx2Inputs {
divide += maxAvx2Inputs
@@ -493,11 +501,6 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
}
}
if r.o.perRound <= 0 {
// Set to 128K if undetectable.
r.o.perRound = 128 << 10
}
if cpuid.CPU.ThreadsPerCore > 1 && r.o.maxGoroutines > cpuid.CPU.PhysicalCores {
// If multiple threads per core, make sure they don't contend for cache.
r.o.perRound /= cpuid.CPU.ThreadsPerCore
@@ -508,6 +511,11 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
// Align to 64 bytes.
r.o.perRound = ((r.o.perRound + 63) / 64) * 64
// Final sanity check...
if r.o.perRound < 1<<10 {
r.o.perRound = 1 << 10
}
if r.o.minSplitSize <= 0 {
// Set minsplit as high as we can, but still have parity in L1.
cacheSize := cpuid.CPU.Cache.L1D
@@ -571,12 +579,28 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
if avx2CodeGen && r.o.useAVX2 {
sz := r.dataShards * r.parityShards * 2 * 32
r.mPool.New = func() interface{} {
return make([]byte, sz)
return AllocAligned(1, sz)[0]
}
r.mPoolSz = sz
}
return &r, err
}
func (r *reedSolomon) getTmpSlice() []byte {
return r.mPool.Get().([]byte)
}
func (r *reedSolomon) putTmpSlice(b []byte) {
if b != nil && cap(b) >= r.mPoolSz {
r.mPool.Put(b[:r.mPoolSz])
return
}
if false {
// Sanity check
panic(fmt.Sprintf("got short tmp returned, want %d, got %d", r.mPoolSz, cap(b)))
}
}
// ErrTooFewShards is returned if too few shards where given to
// Encode/Verify/Reconstruct/Update. It will also be returned from Reconstruct
// if there were too few shards to reconstruct the missing data.
@@ -628,6 +652,19 @@ func (r *reedSolomon) EncodeIdx(dataShard []byte, idx int, parity [][]byte) erro
return ErrShardSize
}
if avx2CodeGen && len(dataShard) >= r.o.perRound && len(parity) >= avx2CodeGenMinShards && ((pshufb && r.o.useAVX2) || r.o.useGFNI) {
m := make([][]byte, r.parityShards)
for iRow := range m {
m[iRow] = r.parity[iRow][idx : idx+1]
}
if r.o.useGFNI {
r.codeSomeShardsGFNI(m, [][]byte{dataShard}, parity, len(dataShard), false)
} else {
r.codeSomeShardsAVXP(m, [][]byte{dataShard}, parity, len(dataShard), false)
}
return nil
}
// Process using no goroutines for now.
start, end := 0, r.o.perRound
if end > len(dataShard) {
@@ -766,7 +803,7 @@ func (r *reedSolomon) Verify(shards [][]byte) (bool, error) {
}
func (r *reedSolomon) canAVX2C(byteCount int, inputs, outputs int) bool {
return avx2CodeGen && r.o.useAVX2 &&
return avx2CodeGen && pshufb && r.o.useAVX2 &&
byteCount >= avx2CodeGenMinSize && inputs+outputs >= avx2CodeGenMinShards &&
inputs <= maxAvx2Inputs && outputs <= maxAvx2Outputs
}
@@ -806,16 +843,16 @@ func (r *reedSolomon) codeSomeShards(matrixRows, inputs, outputs [][]byte, byteC
start += galMulSlicesGFNI(m, inputs, outputs, 0, byteCount)
end = len(inputs[0])
} else if r.canAVX2C(byteCount, len(inputs), len(outputs)) {
m := genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.mPool.Get().([]byte))
m := genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
start += galMulSlicesAvx2(m, inputs, outputs, 0, byteCount)
r.mPool.Put(m)
r.putTmpSlice(m)
end = len(inputs[0])
} else if len(inputs)+len(outputs) > avx2CodeGenMinShards && r.canAVX2C(byteCount, maxAvx2Inputs, maxAvx2Outputs) {
var gfni [maxAvx2Inputs * maxAvx2Outputs]uint64
end = len(inputs[0])
inIdx := 0
m := r.mPool.Get().([]byte)
defer r.mPool.Put(m)
m := r.getTmpSlice()
defer r.putTmpSlice(m)
ins := inputs
for len(ins) > 0 {
inPer := ins
@@ -888,19 +925,19 @@ func (r *reedSolomon) codeSomeShardsP(matrixRows, inputs, outputs [][]byte, byte
var tmp [maxAvx2Inputs * maxAvx2Outputs]uint64
gfniMatrix = genGFNIMatrix(matrixRows, len(inputs), 0, len(outputs), tmp[:])
} else if useAvx2 {
avx2Matrix = genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.mPool.Get().([]byte))
defer r.mPool.Put(avx2Matrix)
avx2Matrix = genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
defer r.putTmpSlice(avx2Matrix)
} else if r.o.useGFNI && byteCount < 10<<20 && len(inputs)+len(outputs) > avx2CodeGenMinShards &&
r.canAVX2C(byteCount/4, maxAvx2Inputs, maxAvx2Outputs) {
r.canGFNI(byteCount/4, maxAvx2Inputs, maxAvx2Outputs) {
// It appears there is a switchover point at around 10MB where
// Regular processing is faster...
r.codeSomeShardsAVXP(matrixRows, inputs, outputs, byteCount)
r.codeSomeShardsGFNI(matrixRows, inputs, outputs, byteCount, true)
return
} else if r.o.useAVX2 && byteCount < 10<<20 && len(inputs)+len(outputs) > avx2CodeGenMinShards &&
r.canAVX2C(byteCount/4, maxAvx2Inputs, maxAvx2Outputs) {
// It appears there is a switchover point at around 10MB where
// Regular processing is faster...
r.codeSomeShardsAVXP(matrixRows, inputs, outputs, byteCount)
r.codeSomeShardsAVXP(matrixRows, inputs, outputs, byteCount, true)
return
}
@@ -964,7 +1001,8 @@ func (r *reedSolomon) codeSomeShardsP(matrixRows, inputs, outputs [][]byte, byte
// Perform the same as codeSomeShards, but split the workload into
// several goroutines.
func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, byteCount int) {
// If clear is set, the first write will overwrite the output.
func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool) {
var wg sync.WaitGroup
gor := r.o.maxGoroutines
@@ -977,10 +1015,8 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
// Make a plan...
plan := make([]state, 0, ((len(inputs)+maxAvx2Inputs-1)/maxAvx2Inputs)*((len(outputs)+maxAvx2Outputs-1)/maxAvx2Outputs))
tmp := r.mPool.Get().([]byte)
defer func(b []byte) {
r.mPool.Put(b)
}(tmp)
tmp := r.getTmpSlice()
defer r.putTmpSlice(tmp)
// Flips between input first to output first.
// We put the smallest data load in the inner loop.
@@ -1006,7 +1042,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
input: inPer,
output: outPer,
m: m,
first: inIdx == 0,
first: inIdx == 0 && clear,
})
outIdx += len(outPer)
outs = outs[len(outPer):]
@@ -1038,7 +1074,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
input: inPer,
output: outPer,
m: m,
first: inIdx == 0,
first: inIdx == 0 && clear,
})
inIdx += len(inPer)
ins = ins[len(inPer):]
@@ -1054,6 +1090,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
}
exec := func(start, stop int) {
defer wg.Done()
lstart, lstop := start, start+r.o.perRound
if lstop > stop {
lstop = stop
@@ -1081,7 +1118,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
for c := range inputs {
in := inputs[c][lstart:lstop]
for iRow := 0; iRow < len(outputs); iRow++ {
if c == 0 {
if c == 0 && clear {
galMulSlice(matrixRows[iRow][c], in, outputs[iRow][lstart:lstop], &r.o)
} else {
galMulSliceXor(matrixRows[iRow][c], in, outputs[iRow][lstart:lstop], &r.o)
@@ -1094,7 +1131,6 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
lstop = stop
}
}
wg.Done()
}
if gor == 1 {
wg.Add(1)
@@ -1119,7 +1155,8 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
// Perform the same as codeSomeShards, but split the workload into
// several goroutines.
func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, byteCount int) {
// If clear is set, the first write will overwrite the output.
func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool) {
var wg sync.WaitGroup
gor := r.o.maxGoroutines
@@ -1155,7 +1192,7 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
input: inPer,
output: outPer,
m: m,
first: inIdx == 0,
first: inIdx == 0 && clear,
})
outIdx += len(outPer)
outs = outs[len(outPer):]
@@ -1186,7 +1223,7 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
input: inPer,
output: outPer,
m: m,
first: inIdx == 0,
first: inIdx == 0 && clear,
})
inIdx += len(inPer)
ins = ins[len(inPer):]
@@ -1202,6 +1239,7 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
}
exec := func(start, stop int) {
defer wg.Done()
lstart, lstop := start, start+r.o.perRound
if lstop > stop {
lstop = stop
@@ -1229,7 +1267,7 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
for c := range inputs {
in := inputs[c][lstart:lstop]
for iRow := 0; iRow < len(outputs); iRow++ {
if c == 0 {
if c == 0 && clear {
galMulSlice(matrixRows[iRow][c], in, outputs[iRow][lstart:lstop], &r.o)
} else {
galMulSliceXor(matrixRows[iRow][c], in, outputs[iRow][lstart:lstop], &r.o)
@@ -1242,8 +1280,8 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
lstop = stop
}
}
wg.Done()
}
if gor == 1 {
wg.Add(1)
exec(0, byteCount)
@@ -1292,6 +1330,10 @@ var ErrShardNoData = errors.New("no shard data")
// shards.
var ErrShardSize = errors.New("shard sizes do not match")
// ErrInvalidShardSize is returned if shard length doesn't meet the requirements,
// typically a multiple of N.
var ErrInvalidShardSize = errors.New("invalid shard size")
// checkShards will check if shards are the same size
// or 0, if allowed. An error is returned if this fails.
// An error is also returned if all shards are size 0.
@@ -1591,7 +1633,7 @@ func (r *reedSolomon) Split(data []byte) ([][]byte, error) {
// Copy partial shards
copyFrom := data[perShard*fullShards : dataLen]
for i := range padding {
if len(copyFrom) <= 0 {
if len(copyFrom) == 0 {
break
}
copyFrom = copyFrom[copy(padding[i], copyFrom):]
+19
View File
@@ -0,0 +1,19 @@
//go:build !noasm && !appengine && !gccgo
package reedsolomon
//go:noescape
func xorSliceNEON(in, out []byte)
// simple slice xor
func sliceXor(in, out []byte, o *options) {
xorSliceNEON(in, out)
done := (len(in) >> 5) << 5
remain := len(in) - done
if remain > 0 {
for i := done; i < len(in); i++ {
out[i] ^= in[i]
}
}
}
+29
View File
@@ -0,0 +1,29 @@
//+build !noasm
//+build !appengine
//+build !gccgo
// func xorSliceNEON(in, out []byte)
TEXT ·xorSliceNEON(SB), 7, $0
MOVD in_base+0(FP), R1
MOVD in_len+8(FP), R2 // length of message
MOVD out_base+24(FP), R5
SUBS $32, R2
BMI completeXor
loopXor:
// Main loop
VLD1.P 32(R1), [V0.B16, V1.B16]
VLD1 (R5), [V20.B16, V21.B16]
VEOR V20.B16, V0.B16, V4.B16
VEOR V21.B16, V1.B16, V5.B16
// Store result
VST1.P [V4.D2, V5.D2], 32(R5)
SUBS $32, R2
BPL loopXor
completeXor:
RET
+7
View File
@@ -0,0 +1,7 @@
//go:build noasm || gccgo || appengine || (!amd64 && !arm64)
package reedsolomon
func sliceXor(in, out []byte, o *options) {
sliceXorGo(in, out, o)
}
+40 -34
View File
@@ -3,6 +3,7 @@ package kcp
import (
"encoding/binary"
"sync/atomic"
"time"
"github.com/klauspost/reedsolomon"
)
@@ -41,14 +42,12 @@ type fecDecoder struct {
decodeCache [][]byte
flagCache []bool
// zeros
zeros []byte
// RS decoder
codec reedsolomon.Encoder
// auto tune fec parameter
autoTune autoTune
autoTune autoTune
shouldTune bool
}
func newFECDecoder(dataShards, parityShards int) *fecDecoder {
@@ -68,7 +67,6 @@ func newFECDecoder(dataShards, parityShards int) *fecDecoder {
dec.codec = codec
dec.decodeCache = make([][]byte, dec.shardSize)
dec.flagCache = make([]bool, dec.shardSize)
dec.zeros = make([]byte, mtuLimit)
return dec
}
@@ -82,18 +80,17 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
}
// check if FEC parameters is out of sync
var shouldTune bool
if int(in.seqid())%dec.shardSize < dec.dataShards {
if in.flag() != typeData { // expect typeData
shouldTune = true
dec.shouldTune = true
}
} else {
if in.flag() != typeParity {
shouldTune = true
dec.shouldTune = true
}
}
if shouldTune {
if dec.shouldTune {
autoDS := dec.autoTune.FindPeriod(true)
autoPS := dec.autoTune.FindPeriod(false)
@@ -112,11 +109,17 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
dec.codec = codec
dec.decodeCache = make([][]byte, dec.shardSize)
dec.flagCache = make([]bool, dec.shardSize)
dec.shouldTune = false
//log.Println("autotune to :", dec.dataShards, dec.parityShards)
}
}
}
// parameters in tuning
if dec.shouldTune {
return nil
}
// insertion
n := len(dec.rx) - 1
insertIdx := 0
@@ -199,7 +202,7 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
if shards[k] != nil {
dlen := len(shards[k])
shards[k] = shards[k][:maxlen]
copy(shards[k][dlen:], dec.zeros)
clear(shards[k][dlen:])
} else if k < dec.dataShards {
shards[k] = xmitBuf.Get().([]byte)[:0]
}
@@ -276,11 +279,9 @@ type (
payloadOffset int // FEC payload offset
// caches
shardCache [][]byte
encodeCache [][]byte
// zeros
zeros []byte
shardCache [][]byte
encodeCache [][]byte
tsLatestPacket int64
// RS encoder
codec reedsolomon.Encoder
@@ -311,13 +312,12 @@ func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder {
for k := range enc.shardCache {
enc.shardCache[k] = make([]byte, mtuLimit)
}
enc.zeros = make([]byte, mtuLimit)
return enc
}
// encodes the packet, outputs parity shards if we have collected quorum datashards
// notice: the contents of 'ps' will be re-written in successive calling
func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
func (enc *fecEncoder) encode(b []byte, rto uint32) (ps [][]byte) {
// The header format:
// | FEC SEQID(4B) | FEC TYPE(2B) | SIZE (2B) | PAYLOAD(SIZE-2) |
// |<-headerOffset |<-payloadOffset
@@ -336,26 +336,30 @@ func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
}
// Generation of Reed-Solomon Erasure Code
now := time.Now().UnixMilli()
if enc.shardCount == enc.dataShards {
// fill '0' into the tail of each datashard
for i := 0; i < enc.dataShards; i++ {
shard := enc.shardCache[i]
slen := len(shard)
copy(shard[slen:enc.maxSize], enc.zeros)
}
// generate the rs-code only if the data is continuous.
if now-enc.tsLatestPacket < int64(rto) {
// fill '0' into the tail of each datashard
for i := 0; i < enc.dataShards; i++ {
shard := enc.shardCache[i]
slen := len(shard)
clear(shard[slen:enc.maxSize])
}
// construct equal-sized slice with stripped header
cache := enc.encodeCache
for k := range cache {
cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
}
// construct equal-sized slice with stripped header
cache := enc.encodeCache
for k := range cache {
cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
}
// encoding
if err := enc.codec.Encode(cache); err == nil {
ps = enc.shardCache[enc.dataShards:]
for k := range ps {
enc.markParity(ps[k][enc.headerOffset:])
ps[k] = ps[k][:enc.maxSize]
// encoding
if err := enc.codec.Encode(cache); err == nil {
ps = enc.shardCache[enc.dataShards:]
for k := range ps {
enc.markParity(ps[k][enc.headerOffset:])
ps[k] = ps[k][:enc.maxSize]
}
}
}
@@ -364,6 +368,8 @@ func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
enc.maxSize = 0
}
enc.tsLatestPacket = now
return
}
+1 -1
View File
@@ -531,7 +531,7 @@ func (s *UDPSession) output(buf []byte) {
// 1. FEC encoding
if s.fecEncoder != nil {
ecc = s.fecEncoder.encode(buf)
ecc = s.fecEncoder.encode(buf, s.kcp.rx_rto)
}
// 2&3. crc32 & encryption
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !purego
// +build !purego
// Package alias implements memory aliasing tests.
package alias
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build purego
// +build purego
// Package alias implements memory aliasing tests.
package alias
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
package salsa
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !amd64 || purego || !gc
// +build !amd64 purego !gc
package salsa
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && linux
// +build arm mips mipsle 386 ppc
// +build linux
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
// +build amd64,solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || windows || zos
// +build aix windows zos
package socket
-1
View File
@@ -3,6 +3,5 @@
// license that can be found in the LICENSE file.
//go:build darwin && go1.12
// +build darwin,go1.12
// This exists solely so we can linkname in symbols from syscall.
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
// +build arm mips mipsle 386 ppc
// +build darwin dragonfly freebsd linux netbsd openbsd
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
// +build amd64,solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !linux && !netbsd
// +build !aix,!linux,!netbsd
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || linux || netbsd
// +build aix linux netbsd
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd
// +build aix darwin dragonfly freebsd netbsd
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm || mips || mipsle || 386 || ppc) && linux
// +build arm mips mipsle 386 ppc
// +build linux
package socket
-2
View File
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
// +build arm64 amd64 loong64 ppc64 ppc64le mips64 mips64le riscv64 s390x
// +build linux
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build amd64 && solaris
// +build amd64,solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build s390x && zos
// +build s390x,zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !race
// +build !race
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build race
// +build race
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
// +build !linux
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
// +build aix darwin dragonfly freebsd openbsd solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux && !s390x && !386
// +build linux,!s390x,!386
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build loong64
// +build loong64
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build riscv64
// +build riscv64
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package socket
-1
View File
@@ -3,7 +3,6 @@
// Added for go1.11 compatibility
//go:build aix
// +build aix
package socket
-1
View File
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build loong64
// +build loong64
package socket
-1
View File
@@ -2,7 +2,6 @@
// cgo -godefs defs_linux.go
//go:build riscv64
// +build riscv64
package socket
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
// +build aix darwin dragonfly freebsd netbsd openbsd
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || linux || solaris
// +build darwin linux solaris
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
// +build !linux
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!zos
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows zos
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos
package ipv4
-1
View File
@@ -4,7 +4,6 @@
// Added for go1.11 compatibility
//go:build aix
// +build aix
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows
// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows
// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || freebsd || linux
// +build darwin freebsd linux
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !darwin && !freebsd && !linux
// +build !darwin,!freebsd,!linux
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
// +build linux
package ipv4
-1
View File
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !linux
// +build !linux
package ipv4

Some files were not shown because too many files have changed in this diff Show More