From d909e8fd047be13c13b24b8e16eab2a0ff35a7cf Mon Sep 17 00:00:00 2001 From: andy2046 Date: Sat, 4 Jul 2020 18:04:08 +0800 Subject: [PATCH] ... --- .gitignore | 1 + LICENSE | 29 + Makefile | 12 + README.md | 14 + bit.go | 29 + doc.md | 309 +++++++++ go.mod | 9 + go.sum | 30 + scripts/doc.sh | 6 + scripts/help.sh | 8 + scripts/test.sh | 9 + ticker.go | 456 +++++++++++++ ticker_test.go | 228 +++++++ timeout.go | 61 ++ timer.go | 76 +++ vendor/github.com/andy2046/gopie/LICENSE | 201 ++++++ .../github.com/andy2046/gopie/pkg/dll/amr.go | 74 +++ .../github.com/andy2046/gopie/pkg/dll/dll.go | 426 ++++++++++++ .../github.com/andy2046/gopie/pkg/log/log.go | 178 +++++ vendor/github.com/andy2046/maths/LICENSE | 201 ++++++ vendor/github.com/andy2046/maths/Makefile | 12 + vendor/github.com/andy2046/maths/README.md | 22 + vendor/github.com/andy2046/maths/docs.md | 623 ++++++++++++++++++ vendor/github.com/andy2046/maths/maths.go | 406 ++++++++++++ vendor/golang.org/x/sys/AUTHORS | 3 + vendor/golang.org/x/sys/CONTRIBUTORS | 3 + vendor/golang.org/x/sys/LICENSE | 27 + vendor/golang.org/x/sys/PATENTS | 22 + vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s | 17 + vendor/golang.org/x/sys/cpu/byteorder.go | 60 ++ vendor/golang.org/x/sys/cpu/cpu.go | 171 +++++ vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go | 34 + vendor/golang.org/x/sys/cpu/cpu_arm.go | 40 ++ vendor/golang.org/x/sys/cpu/cpu_arm64.go | 138 ++++ vendor/golang.org/x/sys/cpu/cpu_arm64.s | 31 + vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 11 + vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go | 21 + vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 16 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 11 + .../golang.org/x/sys/cpu/cpu_gccgo_s390x.go | 22 + vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c | 43 ++ vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go | 26 + vendor/golang.org/x/sys/cpu/cpu_linux.go | 15 + vendor/golang.org/x/sys/cpu/cpu_linux_arm.go | 39 ++ .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 71 ++ .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 22 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 9 + .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 33 + .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 161 +++++ vendor/golang.org/x/sys/cpu/cpu_mips64x.go | 9 + vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 9 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 9 + vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 9 + vendor/golang.org/x/sys/cpu/cpu_s390x.s | 57 ++ vendor/golang.org/x/sys/cpu/cpu_wasm.go | 13 + vendor/golang.org/x/sys/cpu/cpu_x86.go | 59 ++ vendor/golang.org/x/sys/cpu/cpu_x86.s | 27 + vendor/golang.org/x/sys/cpu/hwcap_linux.go | 56 ++ .../x/sys/cpu/syscall_aix_ppc64_gc.go | 36 + vendor/modules.txt | 7 + 60 files changed, 4757 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 bit.go create mode 100644 doc.md create mode 100644 go.mod create mode 100644 go.sum create mode 100755 scripts/doc.sh create mode 100755 scripts/help.sh create mode 100755 scripts/test.sh create mode 100644 ticker.go create mode 100644 ticker_test.go create mode 100644 timeout.go create mode 100644 timer.go create mode 100644 vendor/github.com/andy2046/gopie/LICENSE create mode 100644 vendor/github.com/andy2046/gopie/pkg/dll/amr.go create mode 100644 vendor/github.com/andy2046/gopie/pkg/dll/dll.go create mode 100644 vendor/github.com/andy2046/gopie/pkg/log/log.go create mode 100644 vendor/github.com/andy2046/maths/LICENSE create mode 100644 vendor/github.com/andy2046/maths/Makefile create mode 100644 vendor/github.com/andy2046/maths/README.md create mode 100644 vendor/github.com/andy2046/maths/docs.md create mode 100644 vendor/github.com/andy2046/maths/maths.go create mode 100644 vendor/golang.org/x/sys/AUTHORS create mode 100644 vendor/golang.org/x/sys/CONTRIBUTORS create mode 100644 vendor/golang.org/x/sys/LICENSE create mode 100644 vendor/golang.org/x/sys/PATENTS create mode 100644 vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s create mode 100644 vendor/golang.org/x/sys/cpu/byteorder.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_aix_ppc64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mipsx.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_wasm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.s create mode 100644 vendor/golang.org/x/sys/cpu/hwcap_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go create mode 100644 vendor/modules.txt 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