diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc78fda
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+cover.out
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..10a8a6e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2019, (0x794E6).toString(36)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ed9a552
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+.PHONY: all help test doc
+
+all: help
+
+help: ## Show this help
+ @scripts/help.sh
+
+test: ## Test potential bugs and race conditions
+ @scripts/test.sh
+
+doc: ## Generate docs
+ @scripts/doc.sh
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ce9f85a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+# tik
+
+[![Documentation](https://godoc.org/github.com/andy2046/tik?status.svg)](http://godoc.org/github.com/andy2046/tik)
+[![GitHub issues](https://img.shields.io/github/issues/andy2046/tik.svg)](https://github.com/andy2046/tik/issues)
+[![license](https://img.shields.io/github/license/andy2046/tik.svg)](https://github.com/andy2046/tik/LICENSE)
+[![Release](https://img.shields.io/github/release/andy2046/tik.svg?label=Release)](https://github.com/andy2046/tik/releases)
+
+----
+
+## hierarchical timing wheel made easy
+
+simplified version of [timeout](https://github.com/wahern/timeout) in Golang
+
+for documentation, view the [API reference](./doc.md)
diff --git a/bit.go b/bit.go
new file mode 100644
index 0000000..23c6c56
--- /dev/null
+++ b/bit.go
@@ -0,0 +1,29 @@
+package tik
+
+import "math/bits"
+
+// ROTR(a, k) is a circular shift to the right of bit string a by k slots.
+// ROTR is a right shift, where overflowing bits to the right are added back to the left, instead of zeros.
+// ROTR(a, k) = ROTL(a, n−k)
+func rotr(a uint64, k int) uint64 {
+ return bits.RotateLeft64(a, -k)
+}
+
+// ROTL(a, k) is a circular shift to the left of bit string a by k slots.
+// ROTL is a left shift, where overflowing bits to the left are added back to the right, instead of zeros.
+func rotl(a uint64, k int) uint64 {
+ return bits.RotateLeft64(a, k)
+}
+
+// ctz input cannot be zero.
+func ctz(a uint64) int {
+ return bits.TrailingZeros64(a)
+}
+
+func clz(a uint64) int {
+ return bits.LeadingZeros64(a)
+}
+
+func fls(a uint64) int {
+ return 64 - clz(a)
+}
diff --git a/doc.md b/doc.md
new file mode 100644
index 0000000..0729e6e
--- /dev/null
+++ b/doc.md
@@ -0,0 +1,309 @@
+
+
+# tik
+`import "github.com/andy2046/tik"`
+
+* [Overview](#pkg-overview)
+* [Index](#pkg-index)
+* [Subdirectories](#pkg-subdirectories)
+
+## Overview
+Package tik implements Hierarchical Timing Wheels.
+
+
+
+
+## Index
+* [Variables](#pkg-variables)
+* [type Callback](#Callback)
+* [type Config](#Config)
+* [type DefaultTimer](#DefaultTimer)
+ * [func (dt *DefaultTimer) Now() uint64](#DefaultTimer.Now)
+ * [func (dt *DefaultTimer) Step() <-chan uint64](#DefaultTimer.Step)
+ * [func (dt *DefaultTimer) Stop()](#DefaultTimer.Stop)
+* [type Option](#Option)
+* [type Ticker](#Ticker)
+ * [func New(options ...Option) *Ticker](#New)
+ * [func (tk *Ticker) AnyExpired() bool](#Ticker.AnyExpired)
+ * [func (tk *Ticker) AnyPending() bool](#Ticker.AnyPending)
+ * [func (tk *Ticker) Cancel(to *Timeout)](#Ticker.Cancel)
+ * [func (tk *Ticker) Close()](#Ticker.Close)
+ * [func (tk *Ticker) IsClosed() bool](#Ticker.IsClosed)
+ * [func (tk *Ticker) Schedule(delay uint64, cb Callback) *Timeout](#Ticker.Schedule)
+* [type Timeout](#Timeout)
+ * [func (to *Timeout) Expired() bool](#Timeout.Expired)
+ * [func (to *Timeout) Pending() bool](#Timeout.Pending)
+* [type Timer](#Timer)
+ * [func NewTimer(interval uint64) Timer](#NewTimer)
+
+
+#### Package files
+[bit.go](/src/github.com/andy2046/tik/bit.go) [ticker.go](/src/github.com/andy2046/tik/ticker.go) [timeout.go](/src/github.com/andy2046/tik/timeout.go) [timer.go](/src/github.com/andy2046/tik/timer.go)
+
+
+
+## Variables
+``` go
+var (
+ // DefaultConfig is the default Ticker Config.
+ DefaultConfig = Config{
+ WheelBitNum: 6,
+ WheelNum: 4,
+ Timer: nil,
+ }
+)
+```
+
+
+
+## type [Callback](/src/target/timeout.go?s=147:162#L12)
+``` go
+type Callback func()
+```
+Callback function to trigger when timeout expires.
+
+
+
+
+
+
+
+
+
+
+## type [Config](/src/target/ticker.go?s=1406:1587#L65)
+``` go
+type Config struct {
+ // number of value bits mapped in each wheel.
+ WheelBitNum uint8
+ // number of wheels.
+ WheelNum uint8
+ // Timer to progress the timing wheel.
+ Timer Timer
+}
+```
+Config used to init Ticker.
+
+
+
+
+
+
+
+
+
+
+## type [DefaultTimer](/src/target/timer.go?s=352:484#L22)
+``` go
+type DefaultTimer struct {
+ // contains filtered or unexported fields
+}
+```
+DefaultTimer implements Timer interface.
+
+
+
+
+
+
+
+
+
+
+### func (\*DefaultTimer) [Now](/src/target/timer.go?s=1157:1193#L62)
+``` go
+func (dt *DefaultTimer) Now() uint64
+```
+Now returns the absolute time when timer started in millisecond.
+
+
+
+
+### func (\*DefaultTimer) [Step](/src/target/timer.go?s=1263:1307#L67)
+``` go
+func (dt *DefaultTimer) Step() <-chan uint64
+```
+Step timing wheel by absolute time in millisecond.
+
+
+
+
+### func (\*DefaultTimer) [Stop](/src/target/timer.go?s=1359:1389#L72)
+``` go
+func (dt *DefaultTimer) Stop()
+```
+Stop the DefaultTimer.
+
+
+
+
+## type [Option](/src/target/ticker.go?s=1634:1656#L75)
+``` go
+type Option = func(*Config)
+```
+Option applies config to Ticker Config.
+
+
+
+
+
+
+
+
+
+
+## type [Ticker](/src/target/ticker.go?s=499:1224#L31)
+``` go
+type Ticker struct {
+ // contains filtered or unexported fields
+}
+```
+Ticker progress the timing wheels.
+
+
+
+
+
+
+
+### func [New](/src/target/ticker.go?s=1832:1867#L88)
+``` go
+func New(options ...Option) *Ticker
+```
+New initiates a new Ticker.
+
+
+
+
+
+### func (\*Ticker) [AnyExpired](/src/target/ticker.go?s=9546:9581#L432)
+``` go
+func (tk *Ticker) AnyExpired() bool
+```
+AnyExpired returns true if expiry queue is not empty, false otherwise.
+
+
+
+
+### func (\*Ticker) [AnyPending](/src/target/ticker.go?s=9687:9722#L437)
+``` go
+func (tk *Ticker) AnyPending() bool
+```
+AnyPending returns true if there is task in wheels, false otherwise.
+
+
+
+
+### func (\*Ticker) [Cancel](/src/target/ticker.go?s=3981:4018#L193)
+``` go
+func (tk *Ticker) Cancel(to *Timeout)
+```
+Cancel the Timeout scheduled if it has not yet expired.
+
+
+
+
+### func (\*Ticker) [Close](/src/target/ticker.go?s=4137:4162#L203)
+``` go
+func (tk *Ticker) Close()
+```
+Close stop processing any task,
+whether it is pending or expired.
+
+
+
+
+### func (\*Ticker) [IsClosed](/src/target/ticker.go?s=4330:4363#L213)
+``` go
+func (tk *Ticker) IsClosed() bool
+```
+IsClosed returns true if closed, false otherwise.
+
+
+
+
+### func (\*Ticker) [Schedule](/src/target/ticker.go?s=3704:3766#L181)
+``` go
+func (tk *Ticker) Schedule(delay uint64, cb Callback) *Timeout
+```
+Schedule creates a one-shot action that executed after the given delay.
+`delay` is the time from now to delay execution,
+the time unit of the delay depends on the Timer provided, default is millisecond.
+`cb` is the task to execute.
+it returns `nil` if Ticker is closed.
+
+
+
+
+## type [Timeout](/src/target/timeout.go?s=208:509#L15)
+``` go
+type Timeout struct {
+ // contains filtered or unexported fields
+}
+```
+Timeout represents user timeout logic.
+
+
+
+
+
+
+
+
+
+
+### func (\*Timeout) [Expired](/src/target/timeout.go?s=1035:1068#L56)
+``` go
+func (to *Timeout) Expired() bool
+```
+Expired returns true if timeout is in expired queue, false otherwise.
+
+
+
+
+### func (\*Timeout) [Pending](/src/target/timeout.go?s=809:842#L48)
+``` go
+func (to *Timeout) Pending() bool
+```
+Pending returns true if timeout is in timing wheel, false otherwise.
+
+
+
+
+## type [Timer](/src/target/timer.go?s=102:304#L10)
+``` go
+type Timer interface {
+ // Now returns the absolute time when timer started.
+ Now() uint64
+
+ // Step channel to step timing wheel by absolute time.
+ Step() <-chan uint64
+
+ // Stop the timer.
+ Stop()
+}
+```
+Timer progress the timing wheel by current time.
+
+
+
+
+
+
+
+### func [NewTimer](/src/target/timer.go?s=551:587#L32)
+``` go
+func NewTimer(interval uint64) Timer
+```
+NewTimer returns DefaultTimer with interval in millisecond.
+
+
+
+
+
+
+
+
+
+- - -
+Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..34cf688
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,9 @@
+module github.com/andy2046/tik
+
+go 1.12
+
+require (
+ github.com/andy2046/gopie v0.7.0
+ github.com/andy2046/maths v0.1.0
+ golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..3d4fef1
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,30 @@
+github.com/andy2046/bitmap v0.2.0/go.mod h1:+standD/cRz4KSf/bp3rqX2EzKx/e5C+p9PynIBP42M=
+github.com/andy2046/gopie v0.7.0 h1:e1jBaJE5SqoXI5ViTwXlOrx9munmbW98I4geDWTRdqc=
+github.com/andy2046/gopie v0.7.0/go.mod h1:jIV4Gk+h5tqcadWLLoeM/kHw+ZMLl1yeyIJlsr4akxc=
+github.com/andy2046/maths v0.1.0 h1:OSw1DCrJ65I1s3+US9hxmW21Mxd+rzb3HvkZpqAknks=
+github.com/andy2046/maths v0.1.0/go.mod h1:N31WEDO1GY6pvCXa1dnZDxkPgferKcCsEcrR2hzUe3U=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-redis/redis v6.14.1+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI=
+golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/scripts/doc.sh b/scripts/doc.sh
new file mode 100755
index 0000000..45dbbd3
--- /dev/null
+++ b/scripts/doc.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+godoc2md github.com/andy2046/tik \
+ > $GOPATH/src/github.com/andy2046/tik/doc.md
diff --git a/scripts/help.sh b/scripts/help.sh
new file mode 100755
index 0000000..f6396b5
--- /dev/null
+++ b/scripts/help.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+echo 'usage: make [target] ...'
+echo
+echo 'targets:'
+fgrep -h "##" ./Makefile | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
diff --git a/scripts/test.sh b/scripts/test.sh
new file mode 100755
index 0000000..fe06f80
--- /dev/null
+++ b/scripts/test.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+go test -count=1 -v -cover -race
+go test -bench=. -run=none -benchtime=3s
+go fmt
+go vet
+golint
diff --git a/ticker.go b/ticker.go
new file mode 100644
index 0000000..9aa6dc9
--- /dev/null
+++ b/ticker.go
@@ -0,0 +1,456 @@
+// Package tik implements Hierarchical Timing Wheels.
+package tik
+
+import (
+ "math"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "unsafe"
+
+ list "github.com/andy2046/gopie/pkg/dll"
+ "github.com/andy2046/gopie/pkg/log"
+ "github.com/andy2046/maths"
+ "golang.org/x/sys/cpu"
+)
+
+const (
+ cacheLinePadSize = unsafe.Sizeof(cpu.CacheLinePad{})
+)
+
+var (
+ logger = log.NewLogger(func(c *log.Config) error {
+ c.Level = log.DEBUG
+ c.Prefix = "\t"
+ return nil
+ })
+)
+
+type (
+ // Ticker progress the timing wheels.
+ Ticker struct {
+ _ [cacheLinePadSize]byte
+ closed uint64
+ _ [cacheLinePadSize - 8%cacheLinePadSize]byte
+
+ curtime uint64
+ wheelLen uint64 // 1< 64 is the largest
+ // number of slots which can be tracked.
+ nWheelBit uint8
+
+ closer chan struct{}
+ timer Timer
+ expired *list.List
+ wheelz []*wheel
+ once sync.Once
+ }
+
+ wheel struct {
+ _ [cacheLinePadSize]byte
+ pending uint64
+ _ [cacheLinePadSize - 8%cacheLinePadSize]byte
+ slot []*list.List
+ }
+
+ // Config used to init Ticker.
+ Config struct {
+ // number of value bits mapped in each wheel.
+ WheelBitNum uint8
+ // number of wheels.
+ WheelNum uint8
+ // Timer to progress the timing wheel.
+ Timer Timer
+ }
+
+ // Option applies config to Ticker Config.
+ Option = func(*Config)
+)
+
+var (
+ // DefaultConfig is the default Ticker Config.
+ DefaultConfig = Config{
+ WheelBitNum: 6,
+ WheelNum: 4,
+ Timer: nil,
+ }
+)
+
+// New initiates a new Ticker.
+func New(options ...Option) *Ticker {
+ tConfig := DefaultConfig
+ setOption(&tConfig, options...)
+
+ if tConfig.WheelBitNum < 3 || tConfig.WheelBitNum > 6 {
+ panic("WheelBitNum should be in range [3, 6]")
+ }
+
+ switch tConfig.WheelNum {
+ case 2:
+ case 4:
+ case 8:
+ default:
+ panic("WheelNum should be in set {2, 4, 8}")
+ }
+
+ if tConfig.Timer == nil {
+ tConfig.Timer = NewTimer(100) // 100 millisecond interval
+ }
+
+ tk := &Ticker{}
+ tk.init(tConfig.WheelBitNum, tConfig.WheelNum, tConfig.Timer)
+
+ return tk
+}
+
+func (tk *Ticker) init(nWheelBit, nWheel uint8, timer Timer) {
+ tk.nWheel = nWheel
+ tk.nWheelBit = nWheelBit
+ tk.wheelLen = 1 << nWheelBit
+ tk.wheelMax = 1<> iWheelBit) > tk.wheelMax {
+ pending = math.MaxUint64
+ } else {
+ elapsedTmp := tk.wheelMask & (elapsed >> iWheelBit)
+ elapsedTmpShift := uint64((1 << elapsedTmp) - 1)
+
+ oslot := tk.wheelMask & (curtimeTK >> iWheelBit)
+ pending = rotl(elapsedTmpShift, int(oslot))
+
+ nslot := tk.wheelMask & (curtime >> iWheelBit)
+ pending |= rotr(rotl(elapsedTmpShift, int(nslot)), int(elapsedTmp))
+ pending |= (1 << nslot)
+ }
+
+ pp := &tk.wheelz[i].pending
+ for pending&atomic.LoadUint64(pp) != 0 {
+ islot := ctz(pending & tk.wheelz[i].pending)
+ l := tk.wheelz[i].slot[islot]
+ for !l.Empty() {
+ ee := l.PopLeft()
+ if e, ok := ee.(*Timeout); ok {
+ todo.PushRight(e)
+ }
+ }
+
+ for l.Empty() {
+ p := atomic.LoadUint64(pp)
+
+ if casPending(pp, p, p&^(1< curtime {
+ rem := tk.rem(expires, curtime)
+ iwheel := tk.wheel(rem)
+ islot := tk.slot(iwheel, expires)
+
+ to.m.Lock()
+ to.iwheel, to.islot = iwheel, islot
+ to.pending = tk.wheelz[iwheel].slot[islot]
+ to.element = to.pending.PushRight(to) // link to List
+ to.expires = expires
+ to.papa = tk
+ pending := to.pending
+ to.m.Unlock()
+
+ for !pending.Empty() {
+ pp := &tk.wheelz[iwheel].pending
+ p := atomic.LoadUint64(pp)
+
+ if p&(1<> (wheel * tk.nWheelBit)) - i))
+}
+
+func (tk *Ticker) rem(expires, curtime uint64) uint64 {
+ return expires - curtime
+}
+
+func (tk *Ticker) getExpired() *Timeout {
+ if tk.expired.Empty() {
+ return nil
+ }
+
+ to := tk.expired.PopLeft().(*Timeout)
+ to.m.Lock()
+ to.pending = nil
+ to.papa = nil
+ to.element = nil
+ to.m.Unlock()
+ return to
+}
+
+/*
+// calculate the interval before needing to process any timeouts pending on
+// any wheel.
+//
+// this might return a timeout value sooner than any installed timeout if
+// only higher-order wheels have timeouts pending. It only known when to
+// process a wheel, not precisely when a timeout is scheduled.
+func (tk *Ticker) interval() uint64 {
+ var timeoutTmp, relmask, pending uint64
+ var timeout uint64 = math.MaxUint64
+ var curtime = atomic.LoadUint64(&tk.curtime)
+
+ for i := uint8(0); i < tk.nWheel; i++ {
+ pending = atomic.LoadUint64(&tk.wheelz[i].pending)
+ if pending != 0 {
+ iWheelBit := i * tk.nWheelBit
+ slot := tk.wheelMask & (curtime >> iWheelBit)
+ j := 1
+ if i == 0 {
+ j = 0
+ }
+ timeoutTmp = uint64(ctz(rotr(pending, int(slot)))+j) << iWheelBit
+ timeoutTmp -= (relmask & curtime)
+
+ timeout = maths.Uint64Var.Min(timeoutTmp, timeout)
+ }
+
+ relmask <<= tk.nWheelBit
+ relmask |= tk.wheelMask
+ }
+
+ return timeout
+}
+*/
+
+// AnyExpired returns true if expiry queue is not empty, false otherwise.
+func (tk *Ticker) AnyExpired() bool {
+ return !tk.expired.Empty()
+}
+
+// AnyPending returns true if there is task in wheels, false otherwise.
+func (tk *Ticker) AnyPending() bool {
+ var p uint64
+
+ for _, w := range tk.wheelz {
+ p |= atomic.LoadUint64(&w.pending) // race
+ }
+
+ return p != 0
+}
+
+// setOption takes one or more Option function and applies them in order to Ticker Config.
+func setOption(p *Config, options ...func(*Config)) {
+ for _, opt := range options {
+ opt(p)
+ }
+}
+
+func casPending(p *uint64, c, n uint64) bool {
+ return atomic.CompareAndSwapUint64(p, c, n)
+}
diff --git a/ticker_test.go b/ticker_test.go
new file mode 100644
index 0000000..b5a49a0
--- /dev/null
+++ b/ticker_test.go
@@ -0,0 +1,228 @@
+package tik
+
+import (
+ "sync"
+ "testing"
+ "time"
+)
+
+func TestOneShotRun(t *testing.T) {
+ tk := New()
+ var l sync.RWMutex
+ i := 0
+ cb := func() {
+ l.Lock()
+ i++
+ l.Unlock()
+ }
+
+ to := tk.Schedule(500, cb)
+
+ if !to.Pending() {
+ t.Error("it should be pending")
+ }
+
+ if to.Expired() {
+ t.Error("it should NOT be expired")
+ }
+
+ for {
+ time.Sleep(100 * time.Millisecond)
+
+ if tk.AnyPending() {
+ continue
+ }
+
+ if tk.AnyExpired() {
+ continue
+ }
+
+ break
+ }
+
+ l.RLock()
+ defer l.RUnlock()
+
+ if i != 1 {
+ t.Error("fail to callback", i)
+ }
+}
+
+func TestOneShotCancel(t *testing.T) {
+ tk := New()
+ i := 0
+ cb := func() {
+ i++
+ }
+
+ to := tk.Schedule(500, cb)
+
+ if !to.Pending() {
+ t.Error("it should be pending")
+ }
+
+ if to.Expired() {
+ t.Error("it should NOT be expired")
+ }
+
+ go func() {
+ time.Sleep(200 * time.Millisecond)
+ tk.Cancel(to)
+ }()
+
+ for {
+ time.Sleep(100 * time.Millisecond)
+
+ if tk.AnyPending() {
+ continue
+ }
+
+ if tk.AnyExpired() {
+ continue
+ }
+
+ break
+ }
+
+ if i != 0 {
+ t.Error("fail to Cancel", i)
+ }
+}
+
+func TestCancelAndCheck(t *testing.T) {
+ tk := New()
+ i := 0
+ cb := func() {
+ i++
+ }
+
+ to := tk.Schedule(500, cb)
+
+ go func() {
+ for i := 0; i < 10; i++ {
+ to.Pending()
+ to.Expired()
+ }
+ }()
+
+ go func() {
+ time.Sleep(100 * time.Millisecond)
+ tk.Cancel(to)
+ }()
+
+ for {
+ time.Sleep(100 * time.Millisecond)
+
+ if tk.AnyPending() {
+ continue
+ }
+
+ if tk.AnyExpired() {
+ continue
+ }
+
+ break
+ }
+
+ if i != 0 {
+ t.Error("fail to Cancel", i)
+ }
+}
+
+func TestRunAndCancel(t *testing.T) {
+ var l sync.RWMutex
+ var to *Timeout
+
+ tk := New()
+ i := 0
+ n := 10
+ cb := func() {
+ l.Lock()
+ i++
+ l.Unlock()
+ }
+
+ go func() {
+ for j := 0; j < n; j++ {
+ to = tk.Schedule(500, cb)
+
+ go func(to *Timeout) {
+ for i := 0; i < 10; i++ {
+ to.Pending()
+ to.Expired()
+ }
+ }(to)
+
+ if 0x1&j == 1 {
+ go func(to *Timeout) {
+ tk.Cancel(to)
+ }(to)
+ }
+ }
+ }()
+
+ for {
+ time.Sleep(100 * time.Millisecond)
+
+ if tk.AnyPending() {
+ continue
+ }
+
+ if tk.AnyExpired() {
+ continue
+ }
+
+ break
+ }
+
+ l.RLock()
+ defer l.RUnlock()
+
+ if i != 5 {
+ t.Error("fail to run", i)
+ }
+}
+
+func TestRunPanic(t *testing.T) {
+ tk := New()
+ cb := func() {
+ panic("test")
+ }
+
+ to := tk.Schedule(100, cb)
+
+ if !to.Pending() {
+ t.Error("it should be pending")
+ }
+
+ if to.Expired() {
+ t.Error("it should NOT be expired")
+ }
+
+ for {
+ time.Sleep(100 * time.Millisecond)
+
+ if tk.AnyPending() {
+ continue
+ }
+
+ if tk.AnyExpired() {
+ continue
+ }
+
+ break
+ }
+}
+
+func TestClose(t *testing.T) {
+ tk := New()
+ cb := func() {}
+
+ tk.Close()
+ to := tk.Schedule(500, cb)
+ tk.Cancel(to)
+
+ if to != nil {
+ t.Error("it should be nil")
+ }
+}
diff --git a/timeout.go b/timeout.go
new file mode 100644
index 0000000..26fea87
--- /dev/null
+++ b/timeout.go
@@ -0,0 +1,61 @@
+package tik
+
+import (
+ "math"
+ "sync"
+
+ list "github.com/andy2046/gopie/pkg/dll"
+)
+
+type (
+ // Callback function to trigger when timeout expires.
+ Callback func()
+
+ // Timeout represents user timeout logic.
+ Timeout struct {
+ // absolute expiration time
+ expires uint64
+ // callbk func when expires
+ callbk Callback
+ // timeout list if pending on wheel or expiry queue
+ pending *list.List
+ // pointer to ticker
+ papa *Ticker
+
+ element *list.Element
+
+ iwheel uint8
+ islot uint8
+
+ m sync.RWMutex
+ }
+)
+
+func newTimeout(cb Callback) *Timeout {
+ to := &Timeout{}
+ to.init(cb)
+ return to
+}
+
+// init initialize timeout.
+func (to *Timeout) init(cb Callback) {
+ to.callbk = cb
+ to.iwheel = math.MaxUint8
+ to.islot = math.MaxUint8
+}
+
+// Pending returns true if timeout is in timing wheel, false otherwise.
+func (to *Timeout) Pending() bool {
+ to.m.RLock()
+ defer to.m.RUnlock()
+
+ return to.pending != nil && to.papa != nil && to.pending != to.papa.expired
+}
+
+// Expired returns true if timeout is in expired queue, false otherwise.
+func (to *Timeout) Expired() bool {
+ to.m.RLock()
+ defer to.m.RUnlock()
+
+ return to.pending != nil && to.papa != nil && to.pending == to.papa.expired
+}
diff --git a/timer.go b/timer.go
new file mode 100644
index 0000000..2d7988e
--- /dev/null
+++ b/timer.go
@@ -0,0 +1,76 @@
+package tik
+
+import (
+ "sync"
+ "time"
+)
+
+type (
+ // Timer progress the timing wheel by current time.
+ Timer interface {
+ // Now returns the absolute time when timer started.
+ Now() uint64
+
+ // Step channel to step timing wheel by absolute time.
+ Step() <-chan uint64
+
+ // Stop the timer.
+ Stop()
+ }
+
+ // DefaultTimer implements Timer interface.
+ DefaultTimer struct {
+ nowTime time.Time
+ interval uint64
+ absolute chan uint64
+ closer chan struct{}
+ once sync.Once
+ }
+)
+
+// NewTimer returns DefaultTimer with interval in millisecond.
+func NewTimer(interval uint64) Timer {
+ dt := &DefaultTimer{
+ nowTime: time.Now(),
+ interval: interval,
+ absolute: make(chan uint64),
+ closer: make(chan struct{}),
+ }
+
+ go func() {
+ tick := time.NewTicker(time.Duration(dt.interval) * time.Millisecond)
+ defer tick.Stop()
+
+ for {
+ select {
+ case <-dt.closer:
+ return
+ case t := <-tick.C:
+ select {
+ // Go>=1.9 uses a monotonic clock for duration
+ case dt.absolute <- uint64(t.Sub(dt.nowTime) / time.Millisecond):
+ default:
+ }
+ }
+ }
+ }()
+
+ return dt
+}
+
+// Now returns the absolute time when timer started in millisecond.
+func (dt *DefaultTimer) Now() uint64 {
+ return 0
+}
+
+// Step timing wheel by absolute time in millisecond.
+func (dt *DefaultTimer) Step() <-chan uint64 {
+ return dt.absolute
+}
+
+// Stop the DefaultTimer.
+func (dt *DefaultTimer) Stop() {
+ dt.once.Do(func() {
+ close(dt.closer)
+ })
+}
diff --git a/vendor/github.com/andy2046/gopie/LICENSE b/vendor/github.com/andy2046/gopie/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/vendor/github.com/andy2046/gopie/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/andy2046/gopie/pkg/dll/amr.go b/vendor/github.com/andy2046/gopie/pkg/dll/amr.go
new file mode 100644
index 0000000..1e3493a
--- /dev/null
+++ b/vendor/github.com/andy2046/gopie/pkg/dll/amr.go
@@ -0,0 +1,74 @@
+package dll
+
+import (
+ "sync/atomic"
+ "unsafe"
+)
+
+type (
+ atomicMarkableReference struct {
+ pair *pair
+ }
+
+ pair struct {
+ reference *Element
+ mark bool
+ }
+)
+
+func newAtomicMarkableReference(initialRef *Element, initialMark bool) *atomicMarkableReference {
+ return &atomicMarkableReference{
+ &pair{
+ reference: initialRef,
+ mark: initialMark,
+ },
+ }
+}
+
+func (amr *atomicMarkableReference) getPair() *pair {
+ return (*pair)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&amr.pair))))
+}
+
+func (amr *atomicMarkableReference) getReference() *Element {
+ p := amr.getPair()
+ return p.reference
+}
+
+func (amr *atomicMarkableReference) isMarked() bool {
+ p := amr.getPair()
+ return p.mark
+}
+
+func (amr *atomicMarkableReference) get() (bool, *Element) {
+ p := amr.getPair()
+ return p.mark, p.reference
+}
+
+func (amr *atomicMarkableReference) compareAndSet(expectedReference *Element,
+ newReference *Element,
+ expectedMark bool,
+ newMark bool) bool {
+ current := amr.getPair()
+ val := &pair{newReference, newMark}
+
+ return expectedReference == current.reference &&
+ expectedMark == current.mark &&
+ ((newReference == current.reference &&
+ newMark == current.mark) ||
+ amr.casPair(current, val))
+}
+
+func (amr *atomicMarkableReference) tryMark(expectedReference *Element, newMark bool) bool {
+ current := amr.getPair()
+ val := &pair{expectedReference, newMark}
+ return expectedReference == current.reference &&
+ (newMark == current.mark ||
+ amr.casPair(current, val))
+}
+
+func (amr *atomicMarkableReference) casPair(cmp *pair, val *pair) bool {
+ return atomic.CompareAndSwapPointer(
+ (*unsafe.Pointer)(unsafe.Pointer(&amr.pair)),
+ unsafe.Pointer(cmp),
+ unsafe.Pointer(val))
+}
diff --git a/vendor/github.com/andy2046/gopie/pkg/dll/dll.go b/vendor/github.com/andy2046/gopie/pkg/dll/dll.go
new file mode 100644
index 0000000..8e82c37
--- /dev/null
+++ b/vendor/github.com/andy2046/gopie/pkg/dll/dll.go
@@ -0,0 +1,426 @@
+// Package dll provides a lock-free implementation of doubly linked list.
+package dll
+
+type (
+ // List represents a doubly linked list.
+ List struct {
+ head *Element
+ tail *Element
+ }
+
+ // Element is an element of a linked list.
+ Element struct {
+ // Next and previous pointers in the doubly-linked list of elements.
+ next, prev *atomicMarkableReference
+
+ // The value stored with this element.
+ Value interface{}
+ }
+)
+
+// New returns an initialized list.
+func New() *List { return new(List).Init() }
+
+// Init initializes or clears list l.
+func (l *List) Init() *List {
+ l.head = &Element{
+ prev: newAtomicMarkableReference(nil, false),
+ next: newAtomicMarkableReference(nil, false),
+ }
+ l.tail = &Element{
+ prev: newAtomicMarkableReference(nil, false),
+ next: newAtomicMarkableReference(nil, false),
+ }
+
+ l.head.next.compareAndSet(nil, l.tail, false, false)
+ l.tail.prev.compareAndSet(nil, l.head, false, false)
+
+ return l
+}
+
+// Empty returns true if list l is empty, false otherwise
+func (l *List) Empty() bool {
+ t := l.head.next.getReference()
+ h := l.tail.prev.getReference()
+
+ if t == l.tail && h == l.head {
+ return true
+ }
+
+ return false
+}
+
+// Remove removes e from l if e is an element of list l.
+// It returns the element value e.Value if succeed, nil otherwise
+func (l *List) Remove(e *Element) interface{} {
+ node := e
+ if node == nil {
+ return nil
+ }
+
+ if node == l.tail || node == l.head {
+ return nil
+ }
+
+ for {
+ removed, nodeNext := node.next.get()
+ if removed {
+ return nil
+ }
+ if node.next.compareAndSet(nodeNext, nodeNext, false, true) {
+ for {
+ removed2, nodePrev := node.prev.get()
+ if removed2 || node.prev.compareAndSet(nodePrev, nodePrev, false, true) {
+ break
+ }
+ }
+
+ l.correctPrev(node.prev.getReference(), nodeNext)
+ return node.Value
+ }
+ }
+}
+
+func (l *List) correctPrev(prev, node *Element) *Element {
+ var lastLink *Element
+
+ for {
+ removed, link1 := node.prev.get()
+ if removed {
+ break
+ }
+ removed2, prevNext := prev.next.get()
+ if removed2 {
+ if lastLink != nil {
+ setMark(prev.prev)
+ lastLink.next.compareAndSet(prev, prevNext, false, false)
+ prev = lastLink
+ lastLink = nil
+ continue
+ }
+ prevNext = prev.prev.getReference()
+ prev = prevNext
+ continue
+ }
+
+ if prevNext != node {
+ lastLink = prev
+ prev = prevNext
+ continue
+ }
+
+ if node.prev.compareAndSet(link1, prev, removed, false) {
+ if prev.prev.isMarked() {
+ continue
+ }
+ break
+ }
+ }
+
+ return prev
+}
+
+func setMark(node *atomicMarkableReference) {
+ for {
+ removed, link := node.get()
+ if removed || node.compareAndSet(link, link, false, true) {
+ break
+ }
+ }
+}
+
+// PopLeft returns the first element of list l or nil if the list is empty.
+func (l *List) PopLeft() interface{} {
+ prev := l.head
+
+ for {
+ node := prev.next.getReference()
+ // deque is empty
+ if node == l.tail {
+ return nil
+ }
+
+ removed, nodeNext := node.next.get()
+ // concurrent pop started to delete this node, help it, then continue
+ if removed {
+ helpDelete(node, "help concurrent")
+ continue
+ }
+
+ // 1 pop step
+ if node.next.compareAndSet(nodeNext, nodeNext, false, true) {
+ // 2, 3 step
+ helpDelete(node, "1st step")
+ next := node.next.getReference()
+ // 4 step
+ helpInsert(prev, next, "popLeft New")
+
+ return node.Value
+ }
+ }
+}
+
+// PopRight returns the last element of list l or nil if the list is empty.
+func (l *List) PopRight() interface{} {
+ next := l.tail
+ node := next.prev.getReference()
+
+ for {
+ if !node.next.compareAndSet(next, next, false, false) {
+ node = helpInsert(node, next, "popRight")
+ continue
+ }
+
+ if node == l.head {
+ return nil
+ }
+
+ if node.next.compareAndSet(next, next, false, true) {
+ helpDelete(node, "")
+ prev := node.prev.getReference()
+ helpInsert(prev, next, "popRight")
+
+ return node.Value
+ }
+ }
+}
+
+// PushLeft inserts a new element e with value v at the front of list l and returns e.
+func (l *List) PushLeft(v interface{}) *Element {
+ node := &Element{Value: v}
+ prev := l.head
+ next := prev.next.getReference()
+
+ for {
+ if !prev.next.compareAndSet(next, next, false, false) {
+ next = prev.next.getReference()
+ continue
+ }
+
+ node.prev = newAtomicMarkableReference(prev, false)
+ node.next = newAtomicMarkableReference(next, false)
+
+ if prev.next.compareAndSet(next, node, false, false) {
+ break
+ }
+ }
+
+ pushCommon(node, next)
+
+ return node
+}
+
+// PushRight inserts a new element e with value v at the back of list l and returns e.
+func (l *List) PushRight(v interface{}) *Element {
+ node := &Element{Value: v}
+ next := l.tail
+ prev := next.prev.getReference()
+
+ for {
+ if !prev.next.compareAndSet(next, next, false, false) {
+ // concurrent push inserted -> get new prev
+ prev = helpInsert(prev, next, "concurrentPushRight")
+ continue
+ }
+
+ // 0 push step
+ node.prev = newAtomicMarkableReference(prev, false)
+ node.next = newAtomicMarkableReference(next, false)
+ // 1 push step
+ if prev.next.compareAndSet(next, node, false, false) {
+ break
+ }
+ }
+
+ // 2 push step
+ pushCommon(node, next)
+
+ return node
+}
+
+func pushCommon(node, next *Element) {
+ for {
+ link1 := next.prev
+ if link1.isMarked() || !node.next.compareAndSet(next, next, false, false) {
+ break
+ }
+
+ if next.prev.compareAndSet(link1.getReference(), node, false, false) {
+ if node.prev.isMarked() {
+ helpInsert(node, next, "pushCommon")
+ }
+ break
+ }
+ }
+}
+
+// Next returns the next list element or nil.
+func (l *List) Next(node *Element) *Element {
+ for node != l.tail {
+ if node == nil {
+ break
+ }
+
+ next := node.next.getReference()
+ if next == nil {
+ break
+ }
+
+ removed, nextNext := next.next.get()
+ if removed {
+ // The next pointer of the node behind me has the deleted mark set
+ removed2, nodeNext := node.next.get()
+ if !removed2 || nodeNext != next {
+ setMark(next.prev)
+ node.next.compareAndSet(next, nextNext, false, false) // next removed == false?
+ continue
+ }
+ }
+
+ node = next
+
+ if !removed {
+ return next
+ }
+ }
+
+ return nil
+}
+
+// Prev returns the previous list element or nil.
+func (l *List) Prev(node *Element) *Element {
+ for node != l.head {
+ if node == nil {
+ break
+ }
+
+ prev := node.prev.getReference()
+ if prev == nil {
+ break
+ }
+
+ prevNext := prev.next.getReference()
+ removed := node.next.isMarked()
+
+ if prevNext == node && !removed {
+ return prev
+ } else if removed {
+ node = l.Next(node)
+ } else {
+ prev = l.correctPrev(prev, node)
+ }
+ }
+
+ return nil
+}
+
+/**
+ * Correct node.prev to the closest previous node
+ * helpInsert is very weak - does not reset node.prev to the actual prev.next
+ * but just tries to set node.prev to the given suggestion of a prev node
+ * (for 2 push step, 4 pop step)
+ */
+func helpInsert(prev *Element, node *Element, method string) *Element {
+ // last = is the last node : last.next == prev and it is not marked as removed
+ var last, nodePrev *Element
+
+ for {
+ removed, prevNext := prev.next.get()
+
+ if removed {
+ if last != nil {
+ markPrev(prev)
+ next2 := prev.next.getReference()
+ last.next.compareAndSet(prev, next2, false, false)
+ prev = last
+ last = nil
+ } else {
+ prevNext = prev.prev.getReference()
+ prev = prevNext
+ }
+ continue
+ }
+
+ removed, nodePrev = node.prev.get()
+ if removed {
+ break
+ }
+
+ // prev is not the previous node of node
+ if prevNext != node {
+ last = prev
+ prev = prevNext
+ continue
+ }
+
+ if nodePrev == prev {
+ break
+ }
+
+ if prev.next.getReference() == node && node.prev.compareAndSet(nodePrev, prev, false, false) {
+ if prev.prev.isMarked() {
+ continue
+ }
+ break
+ }
+ }
+
+ return prev
+}
+
+// 2 and 3 pop steps
+func helpDelete(node *Element, place string) {
+ markPrev(node)
+
+ prev := node.prev.getReference()
+ next := node.next.getReference()
+ var last *Element
+
+ for {
+ if prev == next {
+ break
+ }
+
+ if next.next.isMarked() {
+ markPrev(next)
+ next = next.next.getReference()
+ continue
+ }
+
+ removed, prevNext := prev.next.get()
+ if removed {
+ if last != nil {
+ markPrev(prev)
+ next2 := prev.next.getReference()
+ last.next.compareAndSet(prev, next2, false, false)
+ prev = last
+ last = nil
+ } else {
+ prevNext = prev.prev.getReference()
+ prev = prevNext
+ // assert(prev != nil)
+ }
+ continue
+ }
+
+ if prevNext != node {
+ last = prev
+ prev = prevNext
+ continue
+ }
+
+ if prev.next.compareAndSet(node, next, false, false) {
+ break
+ }
+ }
+}
+
+func markPrev(node *Element) {
+ for {
+ link1 := node.prev
+ if link1.isMarked() ||
+ node.prev.compareAndSet(link1.getReference(), link1.getReference(), false, true) {
+ break
+ }
+ }
+}
diff --git a/vendor/github.com/andy2046/gopie/pkg/log/log.go b/vendor/github.com/andy2046/gopie/pkg/log/log.go
new file mode 100644
index 0000000..cbb3bc9
--- /dev/null
+++ b/vendor/github.com/andy2046/gopie/pkg/log/log.go
@@ -0,0 +1,178 @@
+// Package log implements a minimalistic Logger interface.
+package log
+
+import (
+ "io"
+ "log"
+ "os"
+ "sync"
+)
+
+type (
+ // Level defines Logging level.
+ Level int
+
+ // Logger is the Logging interface.
+ Logger interface {
+ Debug(v ...interface{})
+ Info(v ...interface{})
+ Warn(v ...interface{})
+ Error(v ...interface{})
+ Debugf(format string, v ...interface{})
+ Infof(format string, v ...interface{})
+ Warnf(format string, v ...interface{})
+ Errorf(format string, v ...interface{})
+ SetLevel(l Level)
+ LevelLogger(l Level) *log.Logger
+ }
+
+ // Config used to init Logger.
+ Config struct {
+ Level Level
+ Prefix string
+ Flag int
+ DebugHandler io.Writer
+ InfoHandler io.Writer
+ WarnHandler io.Writer
+ ErrorHandler io.Writer
+ }
+
+ // Option applies config to Logger Config.
+ Option = func(*Config) error
+
+ defaultLogger struct {
+ loggerz map[Level]*log.Logger
+ config *Config
+ sync.RWMutex
+ }
+)
+
+// Logging Levels.
+const (
+ DEBUG Level = iota
+ INFO
+ WARN
+ ERROR
+)
+
+var (
+ // DefaultConfig is the default Logger Config.
+ DefaultConfig = Config{
+ Level: INFO,
+ Prefix: "",
+ Flag: log.Ldate | log.Ltime,
+ DebugHandler: os.Stdout,
+ InfoHandler: os.Stdout,
+ WarnHandler: os.Stdout,
+ ErrorHandler: os.Stderr,
+ }
+
+ _ Logger = &defaultLogger{}
+)
+
+// NewLogger returns a new Logger.
+func NewLogger(options ...Option) Logger {
+ logConfig := DefaultConfig
+ setOption(&logConfig, options...)
+
+ return &defaultLogger{
+ config: &logConfig,
+ loggerz: setLoggerz(&logConfig),
+ }
+}
+
+// SetLevel sets the Logging level.
+func (dl *defaultLogger) SetLevel(l Level) {
+ dl.Lock()
+ dl.config.Level = l
+ dl.Unlock()
+}
+
+func (dl *defaultLogger) Debug(v ...interface{}) {
+ dl.log(DEBUG, v...)
+}
+
+func (dl *defaultLogger) Info(v ...interface{}) {
+ dl.log(INFO, v...)
+}
+
+func (dl *defaultLogger) Warn(v ...interface{}) {
+ dl.log(WARN, v...)
+}
+
+func (dl *defaultLogger) Error(v ...interface{}) {
+ dl.log(ERROR, v...)
+}
+
+func (dl *defaultLogger) Debugf(format string, v ...interface{}) {
+ dl.logf(DEBUG, format, v...)
+}
+
+func (dl *defaultLogger) Infof(format string, v ...interface{}) {
+ dl.logf(INFO, format, v...)
+}
+
+func (dl *defaultLogger) Warnf(format string, v ...interface{}) {
+ dl.logf(WARN, format, v...)
+}
+
+func (dl *defaultLogger) Errorf(format string, v ...interface{}) {
+ dl.logf(ERROR, format, v...)
+}
+
+func (dl *defaultLogger) LevelLogger(l Level) *log.Logger {
+ dl.RLock()
+ defer dl.RUnlock()
+ return dl.loggerz[l]
+}
+
+func (dl *defaultLogger) log(level Level, v ...interface{}) {
+ dl.RLock()
+ defer dl.RUnlock()
+ if dl.config.Level <= level {
+ dl.loggerz[level].Println(v...)
+ }
+}
+
+func (dl *defaultLogger) logf(level Level, format string, v ...interface{}) {
+ dl.RLock()
+ defer dl.RUnlock()
+ if dl.config.Level <= level {
+ dl.loggerz[level].Printf(format, v...)
+ }
+}
+
+func setOption(c *Config, options ...func(*Config) error) error {
+ for _, opt := range options {
+ if err := opt(c); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func setLoggerz(logConfig *Config) map[Level]*log.Logger {
+ loggerz := make(map[Level]*log.Logger)
+ nonErrorLogger := log.New(os.Stdout, logConfig.Prefix, logConfig.Flag)
+ errorLogger := log.New(os.Stderr, logConfig.Prefix, logConfig.Flag)
+
+ loggerz[DEBUG] = nonErrorLogger
+ loggerz[INFO] = nonErrorLogger
+ loggerz[WARN] = nonErrorLogger
+ loggerz[ERROR] = errorLogger
+
+ if logConfig.DebugHandler != os.Stdout {
+ loggerz[DEBUG] = log.New(logConfig.DebugHandler, logConfig.Prefix, logConfig.Flag)
+ }
+ if logConfig.InfoHandler != os.Stdout {
+ loggerz[INFO] = log.New(logConfig.InfoHandler, logConfig.Prefix, logConfig.Flag)
+ }
+ if logConfig.WarnHandler != os.Stdout {
+ loggerz[WARN] = log.New(logConfig.WarnHandler, logConfig.Prefix, logConfig.Flag)
+ }
+ if logConfig.ErrorHandler != os.Stderr {
+ loggerz[ERROR] = log.New(logConfig.ErrorHandler, logConfig.Prefix, logConfig.Flag)
+ }
+
+ return loggerz
+}
diff --git a/vendor/github.com/andy2046/maths/LICENSE b/vendor/github.com/andy2046/maths/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/vendor/github.com/andy2046/maths/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/andy2046/maths/Makefile b/vendor/github.com/andy2046/maths/Makefile
new file mode 100644
index 0000000..ed9a552
--- /dev/null
+++ b/vendor/github.com/andy2046/maths/Makefile
@@ -0,0 +1,12 @@
+.PHONY: all help test doc
+
+all: help
+
+help: ## Show this help
+ @scripts/help.sh
+
+test: ## Test potential bugs and race conditions
+ @scripts/test.sh
+
+doc: ## Generate docs
+ @scripts/doc.sh
diff --git a/vendor/github.com/andy2046/maths/README.md b/vendor/github.com/andy2046/maths/README.md
new file mode 100644
index 0000000..aafe901
--- /dev/null
+++ b/vendor/github.com/andy2046/maths/README.md
@@ -0,0 +1,22 @@
+# maths
+
+## makes `Max` `Min` easier
+Go `math` pkg provides `Max` `Min` only for `float64`, this lib adds on for other types.
+
+[Why does Go not have feature X?](https://golang.org/doc/faq#Why_doesnt_Go_have_feature_X)
+
+### Install
+
+```
+go get github.com/andy2046/maths
+```
+
+### Usage
+
+```go
+func main() {
+ iSlice := []int{1, 2, 3}
+ i := IntVar.Max(iSlice...) // 3
+ i = IntVar.Min(iSlice...) // 1
+}
+```
diff --git a/vendor/github.com/andy2046/maths/docs.md b/vendor/github.com/andy2046/maths/docs.md
new file mode 100644
index 0000000..f8b989e
--- /dev/null
+++ b/vendor/github.com/andy2046/maths/docs.md
@@ -0,0 +1,623 @@
+
+
+# maths
+`import "github.com/andy2046/maths"`
+
+* [Overview](#pkg-overview)
+* [Index](#pkg-index)
+
+## Overview
+
+
+
+## Index
+* [Variables](#pkg-variables)
+* [func Range(end int) []struct{}](#Range)
+* [func Ternary(expr bool, trueVal, falseVal interface{}) interface{}](#Ternary)
+* [type Byte](#Byte)
+ * [func (Byte) Max(numerics ...byte) byte](#Byte.Max)
+ * [func (Byte) Min(numerics ...byte) byte](#Byte.Min)
+* [type Float32](#Float32)
+ * [func (Float32) Max(numerics ...float32) float32](#Float32.Max)
+ * [func (Float32) Min(numerics ...float32) float32](#Float32.Min)
+* [type Float64](#Float64)
+ * [func (Float64) Max(numerics ...float64) float64](#Float64.Max)
+ * [func (Float64) Min(numerics ...float64) float64](#Float64.Min)
+* [type Int](#Int)
+ * [func (Int) Max(numerics ...int) int](#Int.Max)
+ * [func (Int) Min(numerics ...int) int](#Int.Min)
+* [type Int16](#Int16)
+ * [func (Int16) Max(numerics ...int16) int16](#Int16.Max)
+ * [func (Int16) Min(numerics ...int16) int16](#Int16.Min)
+* [type Int32](#Int32)
+ * [func (Int32) Max(numerics ...int32) int32](#Int32.Max)
+ * [func (Int32) Min(numerics ...int32) int32](#Int32.Min)
+* [type Int64](#Int64)
+ * [func (Int64) Max(numerics ...int64) int64](#Int64.Max)
+ * [func (Int64) Min(numerics ...int64) int64](#Int64.Min)
+* [type Int8](#Int8)
+ * [func (Int8) Max(numerics ...int8) int8](#Int8.Max)
+ * [func (Int8) Min(numerics ...int8) int8](#Int8.Min)
+* [type Rune](#Rune)
+ * [func (Rune) Max(numerics ...rune) rune](#Rune.Max)
+ * [func (Rune) Min(numerics ...rune) rune](#Rune.Min)
+* [type String](#String)
+ * [func (String) Max(numerics ...string) string](#String.Max)
+ * [func (String) Min(numerics ...string) string](#String.Min)
+* [type Uint](#Uint)
+ * [func (Uint) Max(numerics ...uint) uint](#Uint.Max)
+ * [func (Uint) Min(numerics ...uint) uint](#Uint.Min)
+* [type Uint16](#Uint16)
+ * [func (Uint16) Max(numerics ...uint16) uint16](#Uint16.Max)
+ * [func (Uint16) Min(numerics ...uint16) uint16](#Uint16.Min)
+* [type Uint32](#Uint32)
+ * [func (Uint32) Max(numerics ...uint32) uint32](#Uint32.Max)
+ * [func (Uint32) Min(numerics ...uint32) uint32](#Uint32.Min)
+* [type Uint64](#Uint64)
+ * [func (Uint64) Max(numerics ...uint64) uint64](#Uint64.Max)
+ * [func (Uint64) Min(numerics ...uint64) uint64](#Uint64.Min)
+* [type Uint8](#Uint8)
+ * [func (Uint8) Max(numerics ...uint8) uint8](#Uint8.Max)
+ * [func (Uint8) Min(numerics ...uint8) uint8](#Uint8.Min)
+
+
+#### Package files
+[maths.go](/src/github.com/andy2046/maths/maths.go)
+
+
+
+## Variables
+``` go
+var (
+ // StringVar represents instance of string.
+ StringVar = new(String)
+ // IntVar represents instance of int.
+ IntVar = new(Int)
+ // Int8Var represents instance of int8.
+ Int8Var = new(Int8)
+ // Int16Var represents instance of int16.
+ Int16Var = new(Int16)
+ // Int32Var represents instance of int32.
+ Int32Var = new(Int32)
+ // Int64Var represents instance of int64.
+ Int64Var = new(Int64)
+ // UintVar represents instance of uint.
+ UintVar = new(Uint)
+ // Uint8Var represents instance of uint8.
+ Uint8Var = new(Uint8)
+ // Uint16Var represents instance of uint16.
+ Uint16Var = new(Uint16)
+ // Uint32Var represents instance of uint32.
+ Uint32Var = new(Uint32)
+ // Uint64Var represents instance of uint64.
+ Uint64Var = new(Uint64)
+ // ByteVar represents instance of byte.
+ ByteVar = new(Byte)
+ // RuneVar represents instance of rune.
+ RuneVar = new(Rune)
+ // Float32Var represents instance of float32.
+ Float32Var = new(Float32)
+ // Float64Var represents instance of float64.
+ Float64Var = new(Float64)
+)
+```
+
+
+## func [Range](/src/target/maths.go?s=1827:1857#L74)
+``` go
+func Range(end int) []struct{}
+```
+Range creates a range progressing from zero up to, but not including end.
+
+
+
+## func [Ternary](/src/target/maths.go?s=8017:8083#L401)
+``` go
+func Ternary(expr bool, trueVal, falseVal interface{}) interface{}
+```
+Ternary for no ternary operation in Go.
+
+
+
+
+## type [Byte](/src/target/maths.go?s=580:589#L31)
+``` go
+type Byte byte
+```
+Byte represents type byte.
+
+
+
+
+
+
+
+
+
+
+### func (Byte) [Max](/src/target/maths.go?s=3160:3198#L137)
+``` go
+func (Byte) Max(numerics ...byte) byte
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Byte) [Min](/src/target/maths.go?s=3360:3398#L148)
+``` go
+func (Byte) Min(numerics ...byte) byte
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Float32](/src/target/maths.go?s=670:685#L35)
+``` go
+type Float32 float32
+```
+Float32 represents type float32.
+
+
+
+
+
+
+
+
+
+
+### func (Float32) [Max](/src/target/maths.go?s=1933:1980#L79)
+``` go
+func (Float32) Max(numerics ...float32) float32
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Float32) [Min](/src/target/maths.go?s=2154:2201#L88)
+``` go
+func (Float32) Min(numerics ...float32) float32
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Float64](/src/target/maths.go?s=724:739#L37)
+``` go
+type Float64 float64
+```
+Float64 represents type float64.
+
+
+
+
+
+
+
+
+
+
+### func (Float64) [Max](/src/target/maths.go?s=2374:2421#L97)
+``` go
+func (Float64) Max(numerics ...float64) float64
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Float64) [Min](/src/target/maths.go?s=2568:2615#L106)
+``` go
+func (Float64) Min(numerics ...float64) float64
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Int](/src/target/maths.go?s=122:129#L11)
+``` go
+type Int int
+```
+Int represents type int.
+
+
+
+
+
+
+
+
+
+
+### func (Int) [Max](/src/target/maths.go?s=7210:7245#L357)
+``` go
+func (Int) Max(numerics ...int) int
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Int) [Min](/src/target/maths.go?s=7407:7442#L368)
+``` go
+func (Int) Min(numerics ...int) int
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Int16](/src/target/maths.go?s=206:217#L15)
+``` go
+type Int16 int16
+```
+Int16 represents type int16.
+
+
+
+
+
+
+
+
+
+
+### func (Int16) [Max](/src/target/maths.go?s=6406:6447#L313)
+``` go
+func (Int16) Max(numerics ...int16) int16
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Int16) [Min](/src/target/maths.go?s=6609:6650#L324)
+``` go
+func (Int16) Min(numerics ...int16) int16
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Int32](/src/target/maths.go?s=252:263#L17)
+``` go
+type Int32 int32
+```
+Int32 represents type int32.
+
+
+
+
+
+
+
+
+
+
+### func (Int32) [Max](/src/target/maths.go?s=6001:6042#L291)
+``` go
+func (Int32) Max(numerics ...int32) int32
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Int32) [Min](/src/target/maths.go?s=6204:6245#L302)
+``` go
+func (Int32) Min(numerics ...int32) int32
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Int64](/src/target/maths.go?s=298:309#L19)
+``` go
+type Int64 int64
+```
+Int64 represents type int64.
+
+
+
+
+
+
+
+
+
+
+### func (Int64) [Max](/src/target/maths.go?s=5596:5637#L269)
+``` go
+func (Int64) Max(numerics ...int64) int64
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Int64) [Min](/src/target/maths.go?s=5799:5840#L280)
+``` go
+func (Int64) Min(numerics ...int64) int64
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Int8](/src/target/maths.go?s=162:171#L13)
+``` go
+type Int8 int8
+```
+Int8 represents type int8.
+
+
+
+
+
+
+
+
+
+
+### func (Int8) [Max](/src/target/maths.go?s=6811:6849#L335)
+``` go
+func (Int8) Max(numerics ...int8) int8
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Int8) [Min](/src/target/maths.go?s=7011:7049#L346)
+``` go
+func (Int8) Min(numerics ...int8) int8
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Rune](/src/target/maths.go?s=622:631#L33)
+``` go
+type Rune rune
+```
+Rune represents type rune.
+
+
+
+
+
+
+
+
+
+
+### func (Rune) [Max](/src/target/maths.go?s=2761:2799#L115)
+``` go
+func (Rune) Max(numerics ...rune) rune
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Rune) [Min](/src/target/maths.go?s=2961:2999#L126)
+``` go
+func (Rune) Min(numerics ...rune) rune
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [String](/src/target/maths.go?s=78:91#L9)
+``` go
+type String string
+```
+String represents type string.
+
+
+
+
+
+
+
+
+
+
+### func (String) [Max](/src/target/maths.go?s=7603:7647#L379)
+``` go
+func (String) Max(numerics ...string) string
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (String) [Min](/src/target/maths.go?s=7809:7853#L390)
+``` go
+func (String) Min(numerics ...string) string
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Uint](/src/target/maths.go?s=342:351#L21)
+``` go
+type Uint uint
+```
+Uint represents type uint.
+
+
+
+
+
+
+
+
+
+
+### func (Uint) [Max](/src/target/maths.go?s=5197:5235#L247)
+``` go
+func (Uint) Max(numerics ...uint) uint
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Uint) [Min](/src/target/maths.go?s=5397:5435#L258)
+``` go
+func (Uint) Min(numerics ...uint) uint
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Uint16](/src/target/maths.go?s=434:447#L25)
+``` go
+type Uint16 uint16
+```
+Uint16 represents type uint16.
+
+
+
+
+
+
+
+
+
+
+### func (Uint16) [Max](/src/target/maths.go?s=4381:4425#L203)
+``` go
+func (Uint16) Max(numerics ...uint16) uint16
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Uint16) [Min](/src/target/maths.go?s=4587:4631#L214)
+``` go
+func (Uint16) Min(numerics ...uint16) uint16
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Uint32](/src/target/maths.go?s=484:497#L27)
+``` go
+type Uint32 uint32
+```
+Uint32 represents type uint32.
+
+
+
+
+
+
+
+
+
+
+### func (Uint32) [Max](/src/target/maths.go?s=3970:4014#L181)
+``` go
+func (Uint32) Max(numerics ...uint32) uint32
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Uint32) [Min](/src/target/maths.go?s=4176:4220#L192)
+``` go
+func (Uint32) Min(numerics ...uint32) uint32
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Uint64](/src/target/maths.go?s=534:547#L29)
+``` go
+type Uint64 uint64
+```
+Uint64 represents type uint64.
+
+
+
+
+
+
+
+
+
+
+### func (Uint64) [Max](/src/target/maths.go?s=3559:3603#L159)
+``` go
+func (Uint64) Max(numerics ...uint64) uint64
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Uint64) [Min](/src/target/maths.go?s=3765:3809#L170)
+``` go
+func (Uint64) Min(numerics ...uint64) uint64
+```
+Min returns the smallest in numerics.
+
+
+
+
+## type [Uint8](/src/target/maths.go?s=386:397#L23)
+``` go
+type Uint8 uint8
+```
+Uint8 represents type uint8.
+
+
+
+
+
+
+
+
+
+
+### func (Uint8) [Max](/src/target/maths.go?s=4792:4833#L225)
+``` go
+func (Uint8) Max(numerics ...uint8) uint8
+```
+Max returns the largest in numerics.
+
+
+
+
+### func (Uint8) [Min](/src/target/maths.go?s=4995:5036#L236)
+``` go
+func (Uint8) Min(numerics ...uint8) uint8
+```
+Min returns the smallest in numerics.
+
+
+
+
+
+
+
+
+- - -
+Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
diff --git a/vendor/github.com/andy2046/maths/maths.go b/vendor/github.com/andy2046/maths/maths.go
new file mode 100644
index 0000000..d0b4579
--- /dev/null
+++ b/vendor/github.com/andy2046/maths/maths.go
@@ -0,0 +1,406 @@
+package maths
+
+import (
+ "math"
+)
+
+type (
+ // String represents type string.
+ String string
+ // Int represents type int.
+ Int int
+ // Int8 represents type int8.
+ Int8 int8
+ // Int16 represents type int16.
+ Int16 int16
+ // Int32 represents type int32.
+ Int32 int32
+ // Int64 represents type int64.
+ Int64 int64
+ // Uint represents type uint.
+ Uint uint
+ // Uint8 represents type uint8.
+ Uint8 uint8
+ // Uint16 represents type uint16.
+ Uint16 uint16
+ // Uint32 represents type uint32.
+ Uint32 uint32
+ // Uint64 represents type uint64.
+ Uint64 uint64
+ // Byte represents type byte.
+ Byte byte
+ // Rune represents type rune.
+ Rune rune
+ // Float32 represents type float32.
+ Float32 float32
+ // Float64 represents type float64.
+ Float64 float64
+)
+
+var (
+ // StringVar represents instance of string.
+ StringVar = new(String)
+ // IntVar represents instance of int.
+ IntVar = new(Int)
+ // Int8Var represents instance of int8.
+ Int8Var = new(Int8)
+ // Int16Var represents instance of int16.
+ Int16Var = new(Int16)
+ // Int32Var represents instance of int32.
+ Int32Var = new(Int32)
+ // Int64Var represents instance of int64.
+ Int64Var = new(Int64)
+ // UintVar represents instance of uint.
+ UintVar = new(Uint)
+ // Uint8Var represents instance of uint8.
+ Uint8Var = new(Uint8)
+ // Uint16Var represents instance of uint16.
+ Uint16Var = new(Uint16)
+ // Uint32Var represents instance of uint32.
+ Uint32Var = new(Uint32)
+ // Uint64Var represents instance of uint64.
+ Uint64Var = new(Uint64)
+ // ByteVar represents instance of byte.
+ ByteVar = new(Byte)
+ // RuneVar represents instance of rune.
+ RuneVar = new(Rune)
+ // Float32Var represents instance of float32.
+ Float32Var = new(Float32)
+ // Float64Var represents instance of float64.
+ Float64Var = new(Float64)
+)
+
+// Range creates a range progressing from zero up to, but not including end.
+func Range(end int) []struct{} {
+ return make([]struct{}, end)
+}
+
+// Max returns the largest in numerics.
+func (Float32) Max(numerics ...float32) float32 {
+ n := float64(numerics[0])
+ for i := 1; i < len(numerics); i++ {
+ n = math.Max(float64(numerics[i]), n)
+ }
+ return float32(n)
+}
+
+// Min returns the smallest in numerics.
+func (Float32) Min(numerics ...float32) float32 {
+ n := float64(numerics[0])
+ for i := 1; i < len(numerics); i++ {
+ n = math.Min(float64(numerics[i]), n)
+ }
+ return float32(n)
+}
+
+// Max returns the largest in numerics.
+func (Float64) Max(numerics ...float64) float64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ n = math.Max(numerics[i], n)
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Float64) Min(numerics ...float64) float64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ n = math.Min(numerics[i], n)
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Rune) Max(numerics ...rune) rune {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Rune) Min(numerics ...rune) rune {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Byte) Max(numerics ...byte) byte {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Byte) Min(numerics ...byte) byte {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Uint64) Max(numerics ...uint64) uint64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Uint64) Min(numerics ...uint64) uint64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Uint32) Max(numerics ...uint32) uint32 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Uint32) Min(numerics ...uint32) uint32 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Uint16) Max(numerics ...uint16) uint16 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Uint16) Min(numerics ...uint16) uint16 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Uint8) Max(numerics ...uint8) uint8 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Uint8) Min(numerics ...uint8) uint8 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Uint) Max(numerics ...uint) uint {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Uint) Min(numerics ...uint) uint {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Int64) Max(numerics ...int64) int64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Int64) Min(numerics ...int64) int64 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Int32) Max(numerics ...int32) int32 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Int32) Min(numerics ...int32) int32 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Int16) Max(numerics ...int16) int16 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Int16) Min(numerics ...int16) int16 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Int8) Max(numerics ...int8) int8 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Int8) Min(numerics ...int8) int8 {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (Int) Max(numerics ...int) int {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (Int) Min(numerics ...int) int {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Max returns the largest in numerics.
+func (String) Max(numerics ...string) string {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] > n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Min returns the smallest in numerics.
+func (String) Min(numerics ...string) string {
+ n := numerics[0]
+ for i := 1; i < len(numerics); i++ {
+ if numerics[i] < n {
+ n = numerics[i]
+ }
+ }
+ return n
+}
+
+// Ternary for no ternary operation in Go.
+func Ternary(expr bool, trueVal, falseVal interface{}) interface{} {
+ if expr {
+ return trueVal
+ }
+ return falseVal
+}
diff --git a/vendor/golang.org/x/sys/AUTHORS b/vendor/golang.org/x/sys/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/vendor/golang.org/x/sys/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/sys/CONTRIBUTORS b/vendor/golang.org/x/sys/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/vendor/golang.org/x/sys/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/sys/LICENSE b/vendor/golang.org/x/sys/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/sys/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/sys/PATENTS b/vendor/golang.org/x/sys/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/sys/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s b/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
new file mode 100644
index 0000000..06f84b8
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
@@ -0,0 +1,17 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
+//
+
+TEXT ·syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·syscall6(SB)
+
+TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
+ JMP syscall·rawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/cpu/byteorder.go b/vendor/golang.org/x/sys/cpu/byteorder.go
new file mode 100644
index 0000000..ed8da8d
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/byteorder.go
@@ -0,0 +1,60 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import (
+ "runtime"
+)
+
+// byteOrder is a subset of encoding/binary.ByteOrder.
+type byteOrder interface {
+ Uint32([]byte) uint32
+ Uint64([]byte) uint64
+}
+
+type littleEndian struct{}
+type bigEndian struct{}
+
+func (littleEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (littleEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (bigEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (bigEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
+
+// hostByteOrder returns binary.LittleEndian on little-endian machines and
+// binary.BigEndian on big-endian machines.
+func hostByteOrder() byteOrder {
+ switch runtime.GOARCH {
+ case "386", "amd64", "amd64p32",
+ "arm", "arm64",
+ "mipsle", "mips64le", "mips64p32le",
+ "ppc64le",
+ "riscv", "riscv64":
+ return littleEndian{}
+ case "armbe", "arm64be",
+ "mips", "mips64", "mips64p32",
+ "ppc", "ppc64",
+ "s390", "s390x",
+ "sparc", "sparc64":
+ return bigEndian{}
+ }
+ panic("unknown architecture")
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go
new file mode 100644
index 0000000..e44deb7
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu.go
@@ -0,0 +1,171 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cpu implements processor feature detection for
+// various CPU architectures.
+package cpu
+
+// Initialized reports whether the CPU features were initialized.
+//
+// For some GOOS/GOARCH combinations initialization of the CPU features depends
+// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
+// Initialized will report false if reading the file fails.
+var Initialized bool
+
+// CacheLinePad is used to pad structs to avoid false sharing.
+type CacheLinePad struct{ _ [cacheLineSize]byte }
+
+// X86 contains the supported CPU features of the
+// current X86/AMD64 platform. If the current platform
+// is not X86/AMD64 then all feature flags are false.
+//
+// X86 is padded to avoid false sharing. Further the HasAVX
+// and HasAVX2 are only set if the OS supports XMM and YMM
+// registers in addition to the CPUID feature bit being set.
+var X86 struct {
+ _ CacheLinePad
+ HasAES bool // AES hardware implementation (AES NI)
+ HasADX bool // Multi-precision add-carry instruction extensions
+ HasAVX bool // Advanced vector extension
+ HasAVX2 bool // Advanced vector extension 2
+ HasBMI1 bool // Bit manipulation instruction set 1
+ HasBMI2 bool // Bit manipulation instruction set 2
+ HasERMS bool // Enhanced REP for MOVSB and STOSB
+ HasFMA bool // Fused-multiply-add instructions
+ HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
+ HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
+ HasPOPCNT bool // Hamming weight instruction POPCNT.
+ HasRDRAND bool // RDRAND instruction (on-chip random number generator)
+ HasRDSEED bool // RDSEED instruction (on-chip random number generator)
+ HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
+ HasSSE3 bool // Streaming SIMD extension 3
+ HasSSSE3 bool // Supplemental streaming SIMD extension 3
+ HasSSE41 bool // Streaming SIMD extension 4 and 4.1
+ HasSSE42 bool // Streaming SIMD extension 4 and 4.2
+ _ CacheLinePad
+}
+
+// ARM64 contains the supported CPU features of the
+// current ARMv8(aarch64) platform. If the current platform
+// is not arm64 then all feature flags are false.
+var ARM64 struct {
+ _ CacheLinePad
+ HasFP bool // Floating-point instruction set (always available)
+ HasASIMD bool // Advanced SIMD (always available)
+ HasEVTSTRM bool // Event stream support
+ HasAES bool // AES hardware implementation
+ HasPMULL bool // Polynomial multiplication instruction set
+ HasSHA1 bool // SHA1 hardware implementation
+ HasSHA2 bool // SHA2 hardware implementation
+ HasCRC32 bool // CRC32 hardware implementation
+ HasATOMICS bool // Atomic memory operation instruction set
+ HasFPHP bool // Half precision floating-point instruction set
+ HasASIMDHP bool // Advanced SIMD half precision instruction set
+ HasCPUID bool // CPUID identification scheme registers
+ HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
+ HasJSCVT bool // Javascript conversion from floating-point to integer
+ HasFCMA bool // Floating-point multiplication and addition of complex numbers
+ HasLRCPC bool // Release Consistent processor consistent support
+ HasDCPOP bool // Persistent memory support
+ HasSHA3 bool // SHA3 hardware implementation
+ HasSM3 bool // SM3 hardware implementation
+ HasSM4 bool // SM4 hardware implementation
+ HasASIMDDP bool // Advanced SIMD double precision instruction set
+ HasSHA512 bool // SHA512 hardware implementation
+ HasSVE bool // Scalable Vector Extensions
+ HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
+ _ CacheLinePad
+}
+
+// ARM contains the supported CPU features of the current ARM (32-bit) platform.
+// All feature flags are false if:
+// 1. the current platform is not arm, or
+// 2. the current operating system is not Linux.
+var ARM struct {
+ _ CacheLinePad
+ HasSWP bool // SWP instruction support
+ HasHALF bool // Half-word load and store support
+ HasTHUMB bool // ARM Thumb instruction set
+ Has26BIT bool // Address space limited to 26-bits
+ HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support
+ HasFPA bool // Floating point arithmetic support
+ HasVFP bool // Vector floating point support
+ HasEDSP bool // DSP Extensions support
+ HasJAVA bool // Java instruction set
+ HasIWMMXT bool // Intel Wireless MMX technology support
+ HasCRUNCH bool // MaverickCrunch context switching and handling
+ HasTHUMBEE bool // Thumb EE instruction set
+ HasNEON bool // NEON instruction set
+ HasVFPv3 bool // Vector floating point version 3 support
+ HasVFPv3D16 bool // Vector floating point version 3 D8-D15
+ HasTLS bool // Thread local storage support
+ HasVFPv4 bool // Vector floating point version 4 support
+ HasIDIVA bool // Integer divide instruction support in ARM mode
+ HasIDIVT bool // Integer divide instruction support in Thumb mode
+ HasVFPD32 bool // Vector floating point version 3 D15-D31
+ HasLPAE bool // Large Physical Address Extensions
+ HasEVTSTRM bool // Event stream support
+ HasAES bool // AES hardware implementation
+ HasPMULL bool // Polynomial multiplication instruction set
+ HasSHA1 bool // SHA1 hardware implementation
+ HasSHA2 bool // SHA2 hardware implementation
+ HasCRC32 bool // CRC32 hardware implementation
+ _ CacheLinePad
+}
+
+// MIPS64X contains the supported CPU features of the current mips64/mips64le
+// platforms. If the current platform is not mips64/mips64le or the current
+// operating system is not Linux then all feature flags are false.
+var MIPS64X struct {
+ _ CacheLinePad
+ HasMSA bool // MIPS SIMD architecture
+ _ CacheLinePad
+}
+
+// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
+// If the current platform is not ppc64/ppc64le then all feature flags are false.
+//
+// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
+// since there are no optional categories. There are some exceptions that also
+// require kernel support to work (DARN, SCV), so there are feature bits for
+// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
+// The struct is padded to avoid false sharing.
+var PPC64 struct {
+ _ CacheLinePad
+ HasDARN bool // Hardware random number generator (requires kernel enablement)
+ HasSCV bool // Syscall vectored (requires kernel enablement)
+ IsPOWER8 bool // ISA v2.07 (POWER8)
+ IsPOWER9 bool // ISA v3.00 (POWER9)
+ _ CacheLinePad
+}
+
+// S390X contains the supported CPU features of the current IBM Z
+// (s390x) platform. If the current platform is not IBM Z then all
+// feature flags are false.
+//
+// S390X is padded to avoid false sharing. Further HasVX is only set
+// if the OS supports vector registers in addition to the STFLE
+// feature bit being set.
+var S390X struct {
+ _ CacheLinePad
+ HasZARCH bool // z/Architecture mode is active [mandatory]
+ HasSTFLE bool // store facility list extended
+ HasLDISP bool // long (20-bit) displacements
+ HasEIMM bool // 32-bit immediates
+ HasDFP bool // decimal floating point
+ HasETF3EH bool // ETF-3 enhanced
+ HasMSA bool // message security assist (CPACF)
+ HasAES bool // KM-AES{128,192,256} functions
+ HasAESCBC bool // KMC-AES{128,192,256} functions
+ HasAESCTR bool // KMCTR-AES{128,192,256} functions
+ HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
+ HasGHASH bool // KIMD-GHASH function
+ HasSHA1 bool // K{I,L}MD-SHA-1 functions
+ HasSHA256 bool // K{I,L}MD-SHA-256 functions
+ HasSHA512 bool // K{I,L}MD-SHA-512 functions
+ HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
+ HasVX bool // vector facility
+ HasVXE bool // vector-enhancements facility 1
+ _ CacheLinePad
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go b/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go
new file mode 100644
index 0000000..be60272
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go
@@ -0,0 +1,34 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build aix,ppc64
+
+package cpu
+
+const cacheLineSize = 128
+
+const (
+ // getsystemcfg constants
+ _SC_IMPL = 2
+ _IMPL_POWER8 = 0x10000
+ _IMPL_POWER9 = 0x20000
+)
+
+func init() {
+ impl := getsystemcfg(_SC_IMPL)
+ if impl&_IMPL_POWER8 != 0 {
+ PPC64.IsPOWER8 = true
+ }
+ if impl&_IMPL_POWER9 != 0 {
+ PPC64.IsPOWER9 = true
+ }
+
+ Initialized = true
+}
+
+func getsystemcfg(label int) (n uint64) {
+ r0, _ := callgetsystemcfg(label)
+ n = uint64(r0)
+ return
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm.go b/vendor/golang.org/x/sys/cpu/cpu_arm.go
new file mode 100644
index 0000000..981af68
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm.go
@@ -0,0 +1,40 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+const cacheLineSize = 32
+
+// HWCAP/HWCAP2 bits.
+// These are specific to Linux.
+const (
+ hwcap_SWP = 1 << 0
+ hwcap_HALF = 1 << 1
+ hwcap_THUMB = 1 << 2
+ hwcap_26BIT = 1 << 3
+ hwcap_FAST_MULT = 1 << 4
+ hwcap_FPA = 1 << 5
+ hwcap_VFP = 1 << 6
+ hwcap_EDSP = 1 << 7
+ hwcap_JAVA = 1 << 8
+ hwcap_IWMMXT = 1 << 9
+ hwcap_CRUNCH = 1 << 10
+ hwcap_THUMBEE = 1 << 11
+ hwcap_NEON = 1 << 12
+ hwcap_VFPv3 = 1 << 13
+ hwcap_VFPv3D16 = 1 << 14
+ hwcap_TLS = 1 << 15
+ hwcap_VFPv4 = 1 << 16
+ hwcap_IDIVA = 1 << 17
+ hwcap_IDIVT = 1 << 18
+ hwcap_VFPD32 = 1 << 19
+ hwcap_LPAE = 1 << 20
+ hwcap_EVTSTRM = 1 << 21
+
+ hwcap2_AES = 1 << 0
+ hwcap2_PMULL = 1 << 1
+ hwcap2_SHA1 = 1 << 2
+ hwcap2_SHA2 = 1 << 3
+ hwcap2_CRC32 = 1 << 4
+)
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
new file mode 100644
index 0000000..9c87677
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
@@ -0,0 +1,138 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import "runtime"
+
+const cacheLineSize = 64
+
+func init() {
+ switch runtime.GOOS {
+ case "android", "darwin":
+ // Android and iOS don't seem to allow reading these registers.
+ // Fake the minimal features expected by
+ // TestARM64minimalFeatures.
+ ARM64.HasASIMD = true
+ ARM64.HasFP = true
+ case "linux":
+ doinit()
+ default:
+ readARM64Registers()
+ }
+}
+
+func readARM64Registers() {
+ Initialized = true
+
+ // ID_AA64ISAR0_EL1
+ isar0 := getisar0()
+
+ switch extractBits(isar0, 4, 7) {
+ case 1:
+ ARM64.HasAES = true
+ case 2:
+ ARM64.HasAES = true
+ ARM64.HasPMULL = true
+ }
+
+ switch extractBits(isar0, 8, 11) {
+ case 1:
+ ARM64.HasSHA1 = true
+ }
+
+ switch extractBits(isar0, 12, 15) {
+ case 1:
+ ARM64.HasSHA2 = true
+ case 2:
+ ARM64.HasSHA2 = true
+ ARM64.HasSHA512 = true
+ }
+
+ switch extractBits(isar0, 16, 19) {
+ case 1:
+ ARM64.HasCRC32 = true
+ }
+
+ switch extractBits(isar0, 20, 23) {
+ case 2:
+ ARM64.HasATOMICS = true
+ }
+
+ switch extractBits(isar0, 28, 31) {
+ case 1:
+ ARM64.HasASIMDRDM = true
+ }
+
+ switch extractBits(isar0, 32, 35) {
+ case 1:
+ ARM64.HasSHA3 = true
+ }
+
+ switch extractBits(isar0, 36, 39) {
+ case 1:
+ ARM64.HasSM3 = true
+ }
+
+ switch extractBits(isar0, 40, 43) {
+ case 1:
+ ARM64.HasSM4 = true
+ }
+
+ switch extractBits(isar0, 44, 47) {
+ case 1:
+ ARM64.HasASIMDDP = true
+ }
+
+ // ID_AA64ISAR1_EL1
+ isar1 := getisar1()
+
+ switch extractBits(isar1, 0, 3) {
+ case 1:
+ ARM64.HasDCPOP = true
+ }
+
+ switch extractBits(isar1, 12, 15) {
+ case 1:
+ ARM64.HasJSCVT = true
+ }
+
+ switch extractBits(isar1, 16, 19) {
+ case 1:
+ ARM64.HasFCMA = true
+ }
+
+ switch extractBits(isar1, 20, 23) {
+ case 1:
+ ARM64.HasLRCPC = true
+ }
+
+ // ID_AA64PFR0_EL1
+ pfr0 := getpfr0()
+
+ switch extractBits(pfr0, 16, 19) {
+ case 0:
+ ARM64.HasFP = true
+ case 1:
+ ARM64.HasFP = true
+ ARM64.HasFPHP = true
+ }
+
+ switch extractBits(pfr0, 20, 23) {
+ case 0:
+ ARM64.HasASIMD = true
+ case 1:
+ ARM64.HasASIMD = true
+ ARM64.HasASIMDHP = true
+ }
+
+ switch extractBits(pfr0, 32, 35) {
+ case 1:
+ ARM64.HasSVE = true
+ }
+}
+
+func extractBits(data uint64, start, end uint) uint {
+ return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
new file mode 100644
index 0000000..a54436e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
@@ -0,0 +1,31 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+// func getisar0() uint64
+TEXT ·getisar0(SB),NOSPLIT,$0-8
+ // get Instruction Set Attributes 0 into x0
+ // mrs x0, ID_AA64ISAR0_EL1 = d5380600
+ WORD $0xd5380600
+ MOVD R0, ret+0(FP)
+ RET
+
+// func getisar1() uint64
+TEXT ·getisar1(SB),NOSPLIT,$0-8
+ // get Instruction Set Attributes 1 into x0
+ // mrs x0, ID_AA64ISAR1_EL1 = d5380620
+ WORD $0xd5380620
+ MOVD R0, ret+0(FP)
+ RET
+
+// func getpfr0() uint64
+TEXT ·getpfr0(SB),NOSPLIT,$0-8
+ // get Processor Feature Register 0 into x0
+ // mrs x0, ID_AA64PFR0_EL1 = d5380400
+ WORD $0xd5380400
+ MOVD R0, ret+0(FP)
+ RET
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
new file mode 100644
index 0000000..7b88e86
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
@@ -0,0 +1,11 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+package cpu
+
+func getisar0() uint64
+func getisar1() uint64
+func getpfr0() uint64
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
new file mode 100644
index 0000000..568bcd0
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
@@ -0,0 +1,21 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+package cpu
+
+// haveAsmFunctions reports whether the other functions in this file can
+// be safely called.
+func haveAsmFunctions() bool { return true }
+
+// The following feature detection functions are defined in cpu_s390x.s.
+// They are likely to be expensive to call so the results should be cached.
+func stfle() facilityList
+func kmQuery() queryResult
+func kmcQuery() queryResult
+func kmctrQuery() queryResult
+func kmaQuery() queryResult
+func kimdQuery() queryResult
+func klmdQuery() queryResult
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
new file mode 100644
index 0000000..f7cb469
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
@@ -0,0 +1,16 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 amd64 amd64p32
+// +build !gccgo
+
+package cpu
+
+// cpuid is implemented in cpu_x86.s for gc compiler
+// and in cpu_gccgo.c for gccgo.
+func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
+
+// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
+// and in cpu_gccgo.c for gccgo.
+func xgetbv() (eax, edx uint32)
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
new file mode 100644
index 0000000..53ca8d6
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
@@ -0,0 +1,11 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gccgo
+
+package cpu
+
+func getisar0() uint64 { return 0 }
+func getisar1() uint64 { return 0 }
+func getpfr0() uint64 { return 0 }
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
new file mode 100644
index 0000000..aa986f7
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
@@ -0,0 +1,22 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gccgo
+
+package cpu
+
+// haveAsmFunctions reports whether the other functions in this file can
+// be safely called.
+func haveAsmFunctions() bool { return false }
+
+// TODO(mundaym): the following feature detection functions are currently
+// stubs. See https://golang.org/cl/162887 for how to fix this.
+// They are likely to be expensive to call so the results should be cached.
+func stfle() facilityList { panic("not implemented for gccgo") }
+func kmQuery() queryResult { panic("not implemented for gccgo") }
+func kmcQuery() queryResult { panic("not implemented for gccgo") }
+func kmctrQuery() queryResult { panic("not implemented for gccgo") }
+func kmaQuery() queryResult { panic("not implemented for gccgo") }
+func kimdQuery() queryResult { panic("not implemented for gccgo") }
+func klmdQuery() queryResult { panic("not implemented for gccgo") }
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
new file mode 100644
index 0000000..e363c7d
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
@@ -0,0 +1,43 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 amd64 amd64p32
+// +build gccgo
+
+#include
+#include
+
+// Need to wrap __get_cpuid_count because it's declared as static.
+int
+gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
+}
+
+// xgetbv reads the contents of an XCR (Extended Control Register)
+// specified in the ECX register into registers EDX:EAX.
+// Currently, the only supported value for XCR is 0.
+//
+// TODO: Replace with a better alternative:
+//
+// #include
+//
+// #pragma GCC target("xsave")
+//
+// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
+// unsigned long long x = _xgetbv(0);
+// *eax = x & 0xffffffff;
+// *edx = (x >> 32) & 0xffffffff;
+// }
+//
+// Note that _xgetbv is defined starting with GCC 8.
+void
+gccgoXgetbv(uint32_t *eax, uint32_t *edx)
+{
+ __asm(" xorl %%ecx, %%ecx\n"
+ " xgetbv"
+ : "=a"(*eax), "=d"(*edx));
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
new file mode 100644
index 0000000..ba49b91
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
@@ -0,0 +1,26 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 amd64 amd64p32
+// +build gccgo
+
+package cpu
+
+//extern gccgoGetCpuidCount
+func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
+
+func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
+ var a, b, c, d uint32
+ gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
+ return a, b, c, d
+}
+
+//extern gccgoXgetbv
+func gccgoXgetbv(eax, edx *uint32)
+
+func xgetbv() (eax, edx uint32) {
+ var a, d uint32
+ gccgoXgetbv(&a, &d)
+ return a, d
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux.go b/vendor/golang.org/x/sys/cpu/cpu_linux.go
new file mode 100644
index 0000000..fe13918
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !386,!amd64,!amd64p32,!arm64
+
+package cpu
+
+func init() {
+ if err := readHWCAP(); err != nil {
+ return
+ }
+ doinit()
+ Initialized = true
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
new file mode 100644
index 0000000..2057006
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
@@ -0,0 +1,39 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+func doinit() {
+ ARM.HasSWP = isSet(hwCap, hwcap_SWP)
+ ARM.HasHALF = isSet(hwCap, hwcap_HALF)
+ ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB)
+ ARM.Has26BIT = isSet(hwCap, hwcap_26BIT)
+ ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT)
+ ARM.HasFPA = isSet(hwCap, hwcap_FPA)
+ ARM.HasVFP = isSet(hwCap, hwcap_VFP)
+ ARM.HasEDSP = isSet(hwCap, hwcap_EDSP)
+ ARM.HasJAVA = isSet(hwCap, hwcap_JAVA)
+ ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT)
+ ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH)
+ ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE)
+ ARM.HasNEON = isSet(hwCap, hwcap_NEON)
+ ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3)
+ ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16)
+ ARM.HasTLS = isSet(hwCap, hwcap_TLS)
+ ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4)
+ ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA)
+ ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT)
+ ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32)
+ ARM.HasLPAE = isSet(hwCap, hwcap_LPAE)
+ ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
+ ARM.HasAES = isSet(hwCap2, hwcap2_AES)
+ ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL)
+ ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1)
+ ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2)
+ ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
new file mode 100644
index 0000000..79a38a0
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
@@ -0,0 +1,71 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+// HWCAP/HWCAP2 bits. These are exposed by Linux.
+const (
+ hwcap_FP = 1 << 0
+ hwcap_ASIMD = 1 << 1
+ hwcap_EVTSTRM = 1 << 2
+ hwcap_AES = 1 << 3
+ hwcap_PMULL = 1 << 4
+ hwcap_SHA1 = 1 << 5
+ hwcap_SHA2 = 1 << 6
+ hwcap_CRC32 = 1 << 7
+ hwcap_ATOMICS = 1 << 8
+ hwcap_FPHP = 1 << 9
+ hwcap_ASIMDHP = 1 << 10
+ hwcap_CPUID = 1 << 11
+ hwcap_ASIMDRDM = 1 << 12
+ hwcap_JSCVT = 1 << 13
+ hwcap_FCMA = 1 << 14
+ hwcap_LRCPC = 1 << 15
+ hwcap_DCPOP = 1 << 16
+ hwcap_SHA3 = 1 << 17
+ hwcap_SM3 = 1 << 18
+ hwcap_SM4 = 1 << 19
+ hwcap_ASIMDDP = 1 << 20
+ hwcap_SHA512 = 1 << 21
+ hwcap_SVE = 1 << 22
+ hwcap_ASIMDFHM = 1 << 23
+)
+
+func doinit() {
+ if err := readHWCAP(); err != nil {
+ // failed to read /proc/self/auxv, try reading registers directly
+ readARM64Registers()
+ return
+ }
+
+ // HWCAP feature bits
+ ARM64.HasFP = isSet(hwCap, hwcap_FP)
+ ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
+ ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
+ ARM64.HasAES = isSet(hwCap, hwcap_AES)
+ ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
+ ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
+ ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
+ ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
+ ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
+ ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
+ ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
+ ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
+ ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
+ ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
+ ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
+ ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
+ ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
+ ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
+ ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
+ ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
+ ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
+ ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
+ ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
+ ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
new file mode 100644
index 0000000..eb24e50
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build mips64 mips64le
+
+package cpu
+
+// HWCAP bits. These are exposed by the Linux kernel 5.4.
+const (
+ // CPU features
+ hwcap_MIPS_MSA = 1 << 1
+)
+
+func doinit() {
+ // HWCAP feature bits
+ MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
new file mode 100644
index 0000000..42b5d33
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
@@ -0,0 +1,9 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le,!s390x
+
+package cpu
+
+func doinit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
new file mode 100644
index 0000000..6c8d975
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
@@ -0,0 +1,33 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build ppc64 ppc64le
+
+package cpu
+
+const cacheLineSize = 128
+
+// HWCAP/HWCAP2 bits. These are exposed by the kernel.
+const (
+ // ISA Level
+ _PPC_FEATURE2_ARCH_2_07 = 0x80000000
+ _PPC_FEATURE2_ARCH_3_00 = 0x00800000
+
+ // CPU features
+ _PPC_FEATURE2_DARN = 0x00200000
+ _PPC_FEATURE2_SCV = 0x00100000
+)
+
+func doinit() {
+ // HWCAP2 feature bits
+ PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
+ PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
+ PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
+ PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
new file mode 100644
index 0000000..d579eae
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
@@ -0,0 +1,161 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+const cacheLineSize = 256
+
+const (
+ // bit mask values from /usr/include/bits/hwcap.h
+ hwcap_ZARCH = 2
+ hwcap_STFLE = 4
+ hwcap_MSA = 8
+ hwcap_LDISP = 16
+ hwcap_EIMM = 32
+ hwcap_DFP = 64
+ hwcap_ETF3EH = 256
+ hwcap_VX = 2048
+ hwcap_VXE = 8192
+)
+
+// bitIsSet reports whether the bit at index is set. The bit index
+// is in big endian order, so bit index 0 is the leftmost bit.
+func bitIsSet(bits []uint64, index uint) bool {
+ return bits[index/64]&((1<<63)>>(index%64)) != 0
+}
+
+// function is the code for the named cryptographic function.
+type function uint8
+
+const (
+ // KM{,A,C,CTR} function codes
+ aes128 function = 18 // AES-128
+ aes192 function = 19 // AES-192
+ aes256 function = 20 // AES-256
+
+ // K{I,L}MD function codes
+ sha1 function = 1 // SHA-1
+ sha256 function = 2 // SHA-256
+ sha512 function = 3 // SHA-512
+ sha3_224 function = 32 // SHA3-224
+ sha3_256 function = 33 // SHA3-256
+ sha3_384 function = 34 // SHA3-384
+ sha3_512 function = 35 // SHA3-512
+ shake128 function = 36 // SHAKE-128
+ shake256 function = 37 // SHAKE-256
+
+ // KLMD function codes
+ ghash function = 65 // GHASH
+)
+
+// queryResult contains the result of a Query function
+// call. Bits are numbered in big endian order so the
+// leftmost bit (the MSB) is at index 0.
+type queryResult struct {
+ bits [2]uint64
+}
+
+// Has reports whether the given functions are present.
+func (q *queryResult) Has(fns ...function) bool {
+ if len(fns) == 0 {
+ panic("no function codes provided")
+ }
+ for _, f := range fns {
+ if !bitIsSet(q.bits[:], uint(f)) {
+ return false
+ }
+ }
+ return true
+}
+
+// facility is a bit index for the named facility.
+type facility uint8
+
+const (
+ // cryptography facilities
+ msa4 facility = 77 // message-security-assist extension 4
+ msa8 facility = 146 // message-security-assist extension 8
+)
+
+// facilityList contains the result of an STFLE call.
+// Bits are numbered in big endian order so the
+// leftmost bit (the MSB) is at index 0.
+type facilityList struct {
+ bits [4]uint64
+}
+
+// Has reports whether the given facilities are present.
+func (s *facilityList) Has(fs ...facility) bool {
+ if len(fs) == 0 {
+ panic("no facility bits provided")
+ }
+ for _, f := range fs {
+ if !bitIsSet(s.bits[:], uint(f)) {
+ return false
+ }
+ }
+ return true
+}
+
+func doinit() {
+ // test HWCAP bit vector
+ has := func(featureMask uint) bool {
+ return hwCap&featureMask == featureMask
+ }
+
+ // mandatory
+ S390X.HasZARCH = has(hwcap_ZARCH)
+
+ // optional
+ S390X.HasSTFLE = has(hwcap_STFLE)
+ S390X.HasLDISP = has(hwcap_LDISP)
+ S390X.HasEIMM = has(hwcap_EIMM)
+ S390X.HasETF3EH = has(hwcap_ETF3EH)
+ S390X.HasDFP = has(hwcap_DFP)
+ S390X.HasMSA = has(hwcap_MSA)
+ S390X.HasVX = has(hwcap_VX)
+ if S390X.HasVX {
+ S390X.HasVXE = has(hwcap_VXE)
+ }
+
+ // We need implementations of stfle, km and so on
+ // to detect cryptographic features.
+ if !haveAsmFunctions() {
+ return
+ }
+
+ // optional cryptographic functions
+ if S390X.HasMSA {
+ aes := []function{aes128, aes192, aes256}
+
+ // cipher message
+ km, kmc := kmQuery(), kmcQuery()
+ S390X.HasAES = km.Has(aes...)
+ S390X.HasAESCBC = kmc.Has(aes...)
+ if S390X.HasSTFLE {
+ facilities := stfle()
+ if facilities.Has(msa4) {
+ kmctr := kmctrQuery()
+ S390X.HasAESCTR = kmctr.Has(aes...)
+ }
+ if facilities.Has(msa8) {
+ kma := kmaQuery()
+ S390X.HasAESGCM = kma.Has(aes...)
+ }
+ }
+
+ // compute message digest
+ kimd := kimdQuery() // intermediate (no padding)
+ klmd := klmdQuery() // last (padding)
+ S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
+ S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
+ S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
+ S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
+ sha3 := []function{
+ sha3_224, sha3_256, sha3_384, sha3_512,
+ shake128, shake256,
+ }
+ S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
+ }
+}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_mips64x.go b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
new file mode 100644
index 0000000..6165f12
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_mips64x.go
@@ -0,0 +1,9 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build mips64 mips64le
+
+package cpu
+
+const cacheLineSize = 32
diff --git a/vendor/golang.org/x/sys/cpu/cpu_mipsx.go b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
new file mode 100644
index 0000000..1269eee
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_mipsx.go
@@ -0,0 +1,9 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build mips mipsle
+
+package cpu
+
+const cacheLineSize = 32
diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
new file mode 100644
index 0000000..3ffc4af
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
@@ -0,0 +1,9 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !linux,arm64
+
+package cpu
+
+func doinit() {}
diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
new file mode 100644
index 0000000..efe2b7a
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
@@ -0,0 +1,9 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build riscv64
+
+package cpu
+
+const cacheLineSize = 32
diff --git a/vendor/golang.org/x/sys/cpu/cpu_s390x.s b/vendor/golang.org/x/sys/cpu/cpu_s390x.s
new file mode 100644
index 0000000..e5037d9
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_s390x.s
@@ -0,0 +1,57 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+// func stfle() facilityList
+TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32
+ MOVD $ret+0(FP), R1
+ MOVD $3, R0 // last doubleword index to store
+ XC $32, (R1), (R1) // clear 4 doublewords (32 bytes)
+ WORD $0xb2b01000 // store facility list extended (STFLE)
+ RET
+
+// func kmQuery() queryResult
+TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KM-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92E0024 // cipher message (KM)
+ RET
+
+// func kmcQuery() queryResult
+TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMC-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92F0024 // cipher message with chaining (KMC)
+ RET
+
+// func kmctrQuery() queryResult
+TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMCTR-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB92D4024 // cipher message with counter (KMCTR)
+ RET
+
+// func kmaQuery() queryResult
+TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KMA-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xb9296024 // cipher message with authentication (KMA)
+ RET
+
+// func kimdQuery() queryResult
+TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KIMD-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB93E0024 // compute intermediate message digest (KIMD)
+ RET
+
+// func klmdQuery() queryResult
+TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16
+ MOVD $0, R0 // set function code to 0 (KLMD-Query)
+ MOVD $ret+0(FP), R1 // address of 16-byte return value
+ WORD $0xB93F0024 // compute last message digest (KLMD)
+ RET
diff --git a/vendor/golang.org/x/sys/cpu/cpu_wasm.go b/vendor/golang.org/x/sys/cpu/cpu_wasm.go
new file mode 100644
index 0000000..8681e87
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_wasm.go
@@ -0,0 +1,13 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build wasm
+
+package cpu
+
+// We're compiling the cpu package for an unknown (software-abstracted) CPU.
+// Make CacheLinePad an empty struct and hope that the usual struct alignment
+// rules are good enough.
+
+const cacheLineSize = 0
diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go
new file mode 100644
index 0000000..d70d317
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go
@@ -0,0 +1,59 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build 386 amd64 amd64p32
+
+package cpu
+
+const cacheLineSize = 64
+
+func init() {
+ Initialized = true
+
+ maxID, _, _, _ := cpuid(0, 0)
+
+ if maxID < 1 {
+ return
+ }
+
+ _, _, ecx1, edx1 := cpuid(1, 0)
+ X86.HasSSE2 = isSet(26, edx1)
+
+ X86.HasSSE3 = isSet(0, ecx1)
+ X86.HasPCLMULQDQ = isSet(1, ecx1)
+ X86.HasSSSE3 = isSet(9, ecx1)
+ X86.HasFMA = isSet(12, ecx1)
+ X86.HasSSE41 = isSet(19, ecx1)
+ X86.HasSSE42 = isSet(20, ecx1)
+ X86.HasPOPCNT = isSet(23, ecx1)
+ X86.HasAES = isSet(25, ecx1)
+ X86.HasOSXSAVE = isSet(27, ecx1)
+ X86.HasRDRAND = isSet(30, ecx1)
+
+ osSupportsAVX := false
+ // For XGETBV, OSXSAVE bit is required and sufficient.
+ if X86.HasOSXSAVE {
+ eax, _ := xgetbv()
+ // Check if XMM and YMM registers have OS support.
+ osSupportsAVX = isSet(1, eax) && isSet(2, eax)
+ }
+
+ X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
+
+ if maxID < 7 {
+ return
+ }
+
+ _, ebx7, _, _ := cpuid(7, 0)
+ X86.HasBMI1 = isSet(3, ebx7)
+ X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
+ X86.HasBMI2 = isSet(8, ebx7)
+ X86.HasERMS = isSet(9, ebx7)
+ X86.HasRDSEED = isSet(18, ebx7)
+ X86.HasADX = isSet(19, ebx7)
+}
+
+func isSet(bitpos uint, value uint32) bool {
+ return value&(1<> 63))
+)
+
+// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
+// These are initialized in cpu_$GOARCH.go
+// and should not be changed after they are initialized.
+var hwCap uint
+var hwCap2 uint
+
+func readHWCAP() error {
+ buf, err := ioutil.ReadFile(procAuxv)
+ if err != nil {
+ // e.g. on android /proc/self/auxv is not accessible, so silently
+ // ignore the error and leave Initialized = false. On some
+ // architectures (e.g. arm64) doinit() implements a fallback
+ // readout and will set Initialized = true again.
+ return err
+ }
+ bo := hostByteOrder()
+ for len(buf) >= 2*(uintSize/8) {
+ var tag, val uint
+ switch uintSize {
+ case 32:
+ tag = uint(bo.Uint32(buf[0:]))
+ val = uint(bo.Uint32(buf[4:]))
+ buf = buf[8:]
+ case 64:
+ tag = uint(bo.Uint64(buf[0:]))
+ val = uint(bo.Uint64(buf[8:]))
+ buf = buf[16:]
+ }
+ switch tag {
+ case _AT_HWCAP:
+ hwCap = val
+ case _AT_HWCAP2:
+ hwCap2 = val
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
new file mode 100644
index 0000000..78fe25e
--- /dev/null
+++ b/vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go
@@ -0,0 +1,36 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Minimal copy of x/sys/unix so the cpu package can make a
+// system call on AIX without depending on x/sys/unix.
+// (See golang.org/issue/32102)
+
+// +build aix,ppc64
+// +build !gccgo
+
+package cpu
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o"
+
+//go:linkname libc_getsystemcfg libc_getsystemcfg
+
+type syscallFunc uintptr
+
+var libc_getsystemcfg syscallFunc
+
+type errno = syscall.Errno
+
+// Implemented in runtime/syscall_aix.go.
+func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
+func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
+
+func callgetsystemcfg(label int) (r1 uintptr, e1 errno) {
+ r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0)
+ return
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
new file mode 100644
index 0000000..5c6efbf
--- /dev/null
+++ b/vendor/modules.txt
@@ -0,0 +1,7 @@
+# github.com/andy2046/gopie v0.7.0
+github.com/andy2046/gopie/pkg/dll
+github.com/andy2046/gopie/pkg/log
+# github.com/andy2046/maths v0.1.0
+github.com/andy2046/maths
+# golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f
+golang.org/x/sys/cpu