mirror of https://github.com/poanetwork/quorum.git
fixgo11
This commit is contained in:
parent
d77cb778ca
commit
0b849799ab
|
@ -8,7 +8,7 @@ matrix:
|
|||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
go: 1.9.x
|
||||
go: 1.11.x
|
||||
script:
|
||||
- sudo modprobe fuse
|
||||
- sudo chmod 666 /dev/fuse
|
||||
|
@ -18,7 +18,7 @@ matrix:
|
|||
|
||||
- os: osx
|
||||
osx_image: xcode9.2 # so we don't have to deal with Kernel Extension Consent UI which is never possible in CI
|
||||
go: 1.9.x
|
||||
go: 1.11.x
|
||||
sudo: required
|
||||
script:
|
||||
- brew update
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Build Geth in a stock Go builder container
|
||||
FROM golang:1.10-alpine as builder
|
||||
FROM golang:1.11-alpine as builder
|
||||
|
||||
RUN apk add --no-cache make gcc musl-dev linux-headers git
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Build Geth in a stock Go builder container
|
||||
FROM golang:1.10-alpine as builder
|
||||
FROM golang:1.11-alpine as builder
|
||||
|
||||
RUN apk add --no-cache make gcc musl-dev linux-headers
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ TEXT ·gfpMul(SB),0,$160-24
|
|||
MOVQ b+16(FP), SI
|
||||
|
||||
// Jump to a slightly different implementation if MULX isn't supported.
|
||||
CMPB runtime·support_bmi2(SB), $0
|
||||
CMPB ·hasBMI2(SB), $0
|
||||
JE nobmi2Mul
|
||||
|
||||
mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI))
|
||||
|
|
|
@ -4,6 +4,12 @@ package bn256
|
|||
|
||||
// This file contains forward declarations for the architecture-specific
|
||||
// assembly implementations of these functions, provided that they exist.
|
||||
import (
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
//nolint:varcheck
|
||||
var hasBMI2 = cpu.X86.HasBMI2
|
||||
|
||||
// go:noescape
|
||||
func gfpNeg(c, a *gfP)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package bn256 implements a particular bilinear group at the 128-bit security level.
|
||||
// Package bn256 implements a particular bilinear group.
|
||||
//
|
||||
// Bilinear groups are the basis of many of the new cryptographic protocols
|
||||
// that have been proposed over the past decade. They consist of a triplet of
|
||||
|
@ -14,6 +14,10 @@
|
|||
// Barreto-Naehrig curve as described in
|
||||
// http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible
|
||||
// with the implementation described in that paper.
|
||||
//
|
||||
// (This package previously claimed to operate at a 128-bit security level.
|
||||
// However, recent improvements in attacks mean that is no longer true. See
|
||||
// https://moderncrypto.org/mail-archive/curves/2016/000740.html.)
|
||||
package bn256
|
||||
|
||||
import (
|
||||
|
@ -50,8 +54,8 @@ func RandomG1(r io.Reader) (*big.Int, *G1, error) {
|
|||
return k, new(G1).ScalarBaseMult(k), nil
|
||||
}
|
||||
|
||||
func (g *G1) String() string {
|
||||
return "bn256.G1" + g.p.String()
|
||||
func (e *G1) String() string {
|
||||
return "bn256.G1" + e.p.String()
|
||||
}
|
||||
|
||||
// CurvePoints returns p's curve points in big integer
|
||||
|
@ -98,15 +102,19 @@ func (e *G1) Neg(a *G1) *G1 {
|
|||
}
|
||||
|
||||
// Marshal converts n to a byte slice.
|
||||
func (n *G1) Marshal() []byte {
|
||||
n.p.MakeAffine(nil)
|
||||
|
||||
xBytes := new(big.Int).Mod(n.p.x, P).Bytes()
|
||||
yBytes := new(big.Int).Mod(n.p.y, P).Bytes()
|
||||
|
||||
func (e *G1) Marshal() []byte {
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
if e.p.IsInfinity() {
|
||||
return make([]byte, numBytes*2)
|
||||
}
|
||||
|
||||
e.p.MakeAffine(nil)
|
||||
|
||||
xBytes := new(big.Int).Mod(e.p.x, P).Bytes()
|
||||
yBytes := new(big.Int).Mod(e.p.y, P).Bytes()
|
||||
|
||||
ret := make([]byte, numBytes*2)
|
||||
copy(ret[1*numBytes-len(xBytes):], xBytes)
|
||||
copy(ret[2*numBytes-len(yBytes):], yBytes)
|
||||
|
@ -175,8 +183,8 @@ func RandomG2(r io.Reader) (*big.Int, *G2, error) {
|
|||
return k, new(G2).ScalarBaseMult(k), nil
|
||||
}
|
||||
|
||||
func (g *G2) String() string {
|
||||
return "bn256.G2" + g.p.String()
|
||||
func (e *G2) String() string {
|
||||
return "bn256.G2" + e.p.String()
|
||||
}
|
||||
|
||||
// CurvePoints returns the curve points of p which includes the real
|
||||
|
@ -216,6 +224,13 @@ func (e *G2) Add(a, b *G2) *G2 {
|
|||
|
||||
// Marshal converts n into a byte slice.
|
||||
func (n *G2) Marshal() []byte {
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
if n.p.IsInfinity() {
|
||||
return make([]byte, numBytes*4)
|
||||
}
|
||||
|
||||
n.p.MakeAffine(nil)
|
||||
|
||||
xxBytes := new(big.Int).Mod(n.p.x.x, P).Bytes()
|
||||
|
@ -223,9 +238,6 @@ func (n *G2) Marshal() []byte {
|
|||
yxBytes := new(big.Int).Mod(n.p.y.x, P).Bytes()
|
||||
yyBytes := new(big.Int).Mod(n.p.y.y, P).Bytes()
|
||||
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
ret := make([]byte, numBytes*4)
|
||||
copy(ret[1*numBytes-len(xxBytes):], xxBytes)
|
||||
copy(ret[2*numBytes-len(xyBytes):], xyBytes)
|
||||
|
|
|
@ -245,11 +245,19 @@ func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoi
|
|||
return c
|
||||
}
|
||||
|
||||
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
|
||||
// c to 0 : 1 : 0.
|
||||
func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint {
|
||||
if words := c.z.Bits(); len(words) == 1 && words[0] == 1 {
|
||||
return c
|
||||
}
|
||||
|
||||
if c.IsInfinity() {
|
||||
c.x.SetInt64(0)
|
||||
c.y.SetInt64(1)
|
||||
c.z.SetInt64(0)
|
||||
c.t.SetInt64(0)
|
||||
return c
|
||||
}
|
||||
zInv := pool.Get().ModInverse(c.z, P)
|
||||
t := pool.Get().Mul(c.y, zInv)
|
||||
t.Mod(t, P)
|
||||
|
|
|
@ -225,11 +225,19 @@ func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoi
|
|||
return c
|
||||
}
|
||||
|
||||
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
|
||||
// c to 0 : 1 : 0.
|
||||
func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
|
||||
if c.z.IsOne() {
|
||||
return c
|
||||
}
|
||||
|
||||
if c.IsInfinity() {
|
||||
c.x.SetZero()
|
||||
c.y.SetOne()
|
||||
c.z.SetZero()
|
||||
c.t.SetZero()
|
||||
return c
|
||||
}
|
||||
zInv := newGFp2(pool).Invert(c.z, pool)
|
||||
t := newGFp2(pool).Mul(c.y, zInv, pool)
|
||||
zInv2 := newGFp2(pool).Square(zInv, pool)
|
||||
|
|
|
@ -19,3 +19,4 @@ Filesystem event notification library on steroids. (under active development)
|
|||
- [github.com/cortesi/devd](https://github.com/cortesi/devd)
|
||||
- [github.com/cortesi/modd](https://github.com/cortesi/modd)
|
||||
- [github.com/syncthing/syncthing-inotify](https://github.com/syncthing/syncthing-inotify)
|
||||
- [github.com/OrlovEvgeny/TinyJPG](https://github.com/OrlovEvgeny/TinyJPG)
|
||||
|
|
|
@ -7,16 +7,20 @@ clone_folder: c:\projects\src\github.com\rjeczalik\notify
|
|||
environment:
|
||||
PATH: c:\projects\bin;%PATH%
|
||||
GOPATH: c:\projects
|
||||
NOTIFY_TIMEOUT: 5s
|
||||
NOTIFY_TIMEOUT: 10s
|
||||
GOVERSION: 1.10.3
|
||||
|
||||
install:
|
||||
- rmdir c:\go /s /q
|
||||
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.zip
|
||||
- 7z x go%GOVERSION%.windows-amd64.zip -y -oC:\ > NUL
|
||||
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- go version
|
||||
- go get -v -t ./...
|
||||
|
||||
build_script:
|
||||
- go tool vet -all .
|
||||
- go build ./...
|
||||
- go test -v -timeout 60s -race ./...
|
||||
- go test -v -timeout 120s -race ./...
|
||||
|
||||
test: off
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
|
||||
// Copyright (c) 2014-2018 The Notify Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
@ -6,4 +6,4 @@
|
|||
|
||||
package notify
|
||||
|
||||
var debugTag bool = true
|
||||
var debugTag = true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
|
||||
// Copyright (c) 2014-2018 The Notify Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
@ -6,4 +6,4 @@
|
|||
|
||||
package notify
|
||||
|
||||
var debugTag bool = false
|
||||
var debugTag = false
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module github.com/rjeczalik/notify
|
||||
|
||||
require golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7
|
|
@ -48,7 +48,7 @@ var wg sync.WaitGroup // used to wait until the runloop starts
|
|||
// started and is ready via the wg. It also serves purpose of a dummy source,
|
||||
// thanks to it the runloop does not return as it also has at least one source
|
||||
// registered.
|
||||
var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{
|
||||
var source = C.CFRunLoopSourceCreate(C.kCFAllocatorDefault, 0, &C.CFRunLoopSourceContext{
|
||||
perform: (C.CFRunLoopPerformCallBack)(C.gosource),
|
||||
})
|
||||
|
||||
|
@ -90,6 +90,10 @@ func gostream(_, info uintptr, n C.size_t, paths, flags, ids uintptr) {
|
|||
if n == 0 {
|
||||
return
|
||||
}
|
||||
fn := streamFuncs.get(info)
|
||||
if fn == nil {
|
||||
return
|
||||
}
|
||||
ev := make([]FSEvent, 0, int(n))
|
||||
for i := uintptr(0); i < uintptr(n); i++ {
|
||||
switch flags := *(*uint32)(unsafe.Pointer((flags + i*offflag))); {
|
||||
|
@ -104,7 +108,7 @@ func gostream(_, info uintptr, n C.size_t, paths, flags, ids uintptr) {
|
|||
}
|
||||
|
||||
}
|
||||
streamFuncs.get(info)(ev)
|
||||
fn(ev)
|
||||
}
|
||||
|
||||
// StreamFunc is a callback called when stream receives file events.
|
||||
|
@ -162,8 +166,8 @@ func (s *stream) Start() error {
|
|||
return nil
|
||||
}
|
||||
wg.Wait()
|
||||
p := C.CFStringCreateWithCStringNoCopy(nil, C.CString(s.path), C.kCFStringEncodingUTF8, nil)
|
||||
path := C.CFArrayCreate(nil, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
|
||||
p := C.CFStringCreateWithCStringNoCopy(C.kCFAllocatorDefault, C.CString(s.path), C.kCFStringEncodingUTF8, C.kCFAllocatorDefault)
|
||||
path := C.CFArrayCreate(C.kCFAllocatorDefault, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
|
||||
ctx := C.FSEventStreamContext{}
|
||||
ref := C.EventStreamCreate(&ctx, C.uintptr_t(s.info), path, C.FSEventStreamEventId(atomic.LoadUint64(&since)), latency, flags)
|
||||
if ref == nilstream {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2014-2018 The Notify Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// +build !darwin,!linux,!freebsd,!dragonfly,!netbsd,!openbsd,!windows
|
||||
// +build !kqueue,!solaris
|
||||
|
||||
package notify
|
||||
|
||||
import "errors"
|
||||
|
||||
// newWatcher stub.
|
||||
func newWatcher(chan<- EventInfo) watcher {
|
||||
return watcherStub{errors.New("notify: not implemented")}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
|
||||
// Copyright (c) 2014-2018 The Notify Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
@ -22,7 +22,7 @@ import (
|
|||
const readBufferSize = 4096
|
||||
|
||||
// Since all operations which go through the Windows completion routine are done
|
||||
// asynchronously, filter may set one of the constants belor. They were defined
|
||||
// asynchronously, filter may set one of the constants below. They were defined
|
||||
// in order to distinguish whether current folder should be re-registered in
|
||||
// ReadDirectoryChangesW function or some control operations need to be executed.
|
||||
const (
|
||||
|
@ -109,8 +109,13 @@ func (g *grip) register(cph syscall.Handle) (err error) {
|
|||
// buffer. Directory changes that occur between calls to this function are added
|
||||
// to the buffer and then, returned with the next call.
|
||||
func (g *grip) readDirChanges() error {
|
||||
handle := syscall.Handle(atomic.LoadUintptr((*uintptr)(&g.handle)))
|
||||
if handle == syscall.InvalidHandle {
|
||||
return nil // Handle was closed.
|
||||
}
|
||||
|
||||
return syscall.ReadDirectoryChanges(
|
||||
g.handle,
|
||||
handle,
|
||||
&g.buffer[0],
|
||||
uint32(unsafe.Sizeof(g.buffer)),
|
||||
g.recursive,
|
||||
|
@ -220,12 +225,27 @@ func (wd *watched) updateGrip(idx int, cph syscall.Handle, reset bool,
|
|||
// returned from the operating system kernel.
|
||||
func (wd *watched) closeHandle() (err error) {
|
||||
for _, g := range wd.digrip {
|
||||
if g != nil && g.handle != syscall.InvalidHandle {
|
||||
switch suberr := syscall.CloseHandle(g.handle); {
|
||||
case suberr == nil:
|
||||
g.handle = syscall.InvalidHandle
|
||||
case err == nil:
|
||||
err = suberr
|
||||
if g == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for {
|
||||
handle := syscall.Handle(atomic.LoadUintptr((*uintptr)(&g.handle)))
|
||||
if handle == syscall.InvalidHandle {
|
||||
break // Already closed.
|
||||
}
|
||||
|
||||
e := syscall.CloseHandle(handle)
|
||||
if e != nil && err == nil {
|
||||
err = e
|
||||
}
|
||||
|
||||
// Set invalid handle even when CloseHandle fails. This will leak
|
||||
// the handle but, since we can't close it anyway, there won't be
|
||||
// any difference.
|
||||
if atomic.CompareAndSwapUintptr((*uintptr)(&g.handle),
|
||||
(uintptr)(handle), (uintptr)(syscall.InvalidHandle)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,50 +292,49 @@ func (r *readdcw) RecursiveWatch(path string, event Event) error {
|
|||
// watch inserts a directory to the group of watched folders. If watched folder
|
||||
// already exists, function tries to rewatch it with new filters(NOT VALID). Moreover,
|
||||
// watch starts the main event loop goroutine when called for the first time.
|
||||
func (r *readdcw) watch(path string, event Event, recursive bool) (err error) {
|
||||
func (r *readdcw) watch(path string, event Event, recursive bool) error {
|
||||
if event&^(All|fileNotifyChangeAll) != 0 {
|
||||
return errors.New("notify: unknown event")
|
||||
}
|
||||
|
||||
r.Lock()
|
||||
wd, ok := r.m[path]
|
||||
r.Unlock()
|
||||
if !ok {
|
||||
if err = r.lazyinit(); err != nil {
|
||||
return
|
||||
}
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if wd, ok = r.m[path]; ok {
|
||||
dbgprint("watch: exists already")
|
||||
return
|
||||
}
|
||||
if wd, err = newWatched(r.cph, uint32(event), recursive, path); err != nil {
|
||||
return
|
||||
}
|
||||
r.m[path] = wd
|
||||
dbgprint("watch: new watch added")
|
||||
} else {
|
||||
dbgprint("watch: exists already")
|
||||
defer r.Unlock()
|
||||
|
||||
if wd, ok := r.m[path]; ok {
|
||||
dbgprint("watch: already exists")
|
||||
wd.filter &^= stateUnwatch
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := r.lazyinit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wd, err := newWatched(r.cph, uint32(event), recursive, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.m[path] = wd
|
||||
dbgprint("watch: new watch added")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// lazyinit creates an I/O completion port and starts the main event processing
|
||||
// loop. This method uses Double-Checked Locking optimization.
|
||||
// lazyinit creates an I/O completion port and starts the main event loop.
|
||||
func (r *readdcw) lazyinit() (err error) {
|
||||
invalid := uintptr(syscall.InvalidHandle)
|
||||
|
||||
if atomic.LoadUintptr((*uintptr)(&r.cph)) == invalid {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if atomic.LoadUintptr((*uintptr)(&r.cph)) == invalid {
|
||||
cph := syscall.InvalidHandle
|
||||
if cph, err = syscall.CreateIoCompletionPort(cph, 0, 0, 0); err != nil {
|
||||
return
|
||||
}
|
||||
r.cph, r.start = cph, true
|
||||
go r.loop()
|
||||
cph := syscall.InvalidHandle
|
||||
if cph, err = syscall.CreateIoCompletionPort(cph, 0, 0, 0); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.cph, r.start = cph, true
|
||||
go r.loop()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -341,9 +360,9 @@ func (r *readdcw) loop() {
|
|||
overEx := (*overlappedEx)(unsafe.Pointer(overlapped))
|
||||
if n != 0 {
|
||||
r.loopevent(n, overEx)
|
||||
if err = overEx.parent.readDirChanges(); err != nil {
|
||||
// TODO: error handling
|
||||
}
|
||||
}
|
||||
if err = overEx.parent.readDirChanges(); err != nil {
|
||||
// TODO: error handling
|
||||
}
|
||||
r.loopstate(overEx)
|
||||
}
|
||||
|
@ -364,6 +383,7 @@ func (r *readdcw) loopstate(overEx *overlappedEx) {
|
|||
overEx.parent.parent.recreate(r.cph)
|
||||
case stateUnwatch:
|
||||
dbgprint("loopstate unwatch")
|
||||
overEx.parent.parent.closeHandle()
|
||||
delete(r.m, syscall.UTF16ToString(overEx.parent.pathw))
|
||||
case stateCPClose:
|
||||
default:
|
||||
|
@ -495,27 +515,30 @@ func (r *readdcw) RecursiveUnwatch(path string) error {
|
|||
// TODO : pknap
|
||||
func (r *readdcw) unwatch(path string) (err error) {
|
||||
var wd *watched
|
||||
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if wd, err = r.nonStateWatchedLocked(path); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
wd.filter |= stateUnwatch
|
||||
if err = wd.closeHandle(); err != nil {
|
||||
wd.filter &^= stateUnwatch
|
||||
return
|
||||
}
|
||||
dbgprint("unwatch: set unwatch state")
|
||||
|
||||
if _, attrErr := syscall.GetFileAttributes(&wd.pathw[0]); attrErr != nil {
|
||||
for _, g := range wd.digrip {
|
||||
if g != nil {
|
||||
dbgprint("unwatch: posting")
|
||||
if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil {
|
||||
wd.filter &^= stateUnwatch
|
||||
return
|
||||
}
|
||||
if g == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
dbgprint("unwatch: posting")
|
||||
if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil {
|
||||
wd.filter &^= stateUnwatch
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,13 @@
|
|||
// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
|
||||
// Copyright (c) 2014-2018 The Notify Authors. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// +build !darwin,!linux,!freebsd,!dragonfly,!netbsd,!openbsd,!windows
|
||||
// +build !kqueue,!solaris
|
||||
|
||||
package notify
|
||||
|
||||
import "errors"
|
||||
|
||||
type stub struct{ error }
|
||||
|
||||
// newWatcher stub.
|
||||
func newWatcher(chan<- EventInfo) watcher {
|
||||
return stub{errors.New("notify: not implemented")}
|
||||
}
|
||||
type watcherStub struct{ error }
|
||||
|
||||
// Following methods implement notify.watcher interface.
|
||||
func (s stub) Watch(string, Event) error { return s }
|
||||
func (s stub) Rewatch(string, Event, Event) error { return s }
|
||||
func (s stub) Unwatch(string) (err error) { return s }
|
||||
func (s stub) Close() error { return s }
|
||||
func (s watcherStub) Watch(string, Event) error { return s }
|
||||
func (s watcherStub) Rewatch(string, Event, Event) error { return s }
|
||||
func (s watcherStub) Unwatch(string) (err error) { return s }
|
||||
func (s watcherStub) Close() error { return s }
|
||||
|
|
|
@ -106,7 +106,8 @@ func newWatcher(c chan<- EventInfo) watcher {
|
|||
}
|
||||
t.t = newTrigger(t.pthLkp)
|
||||
if err := t.t.Init(); err != nil {
|
||||
panic(err)
|
||||
t.Close()
|
||||
return watcherStub{fmt.Errorf("failed setting up watcher: %v", err)}
|
||||
}
|
||||
go t.monitor()
|
||||
return t
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// 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
|
||||
|
||||
// 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.
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -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.
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 32
|
||||
|
||||
func doinit() {}
|
|
@ -0,0 +1,67 @@
|
|||
// 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 = 64
|
||||
|
||||
// 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() {
|
||||
// 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
|
||||
}
|
|
@ -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)
|
|
@ -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 <cpuid.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 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 <xsaveintrin.h>
|
||||
//
|
||||
// #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));
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// 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 !amd64,!amd64p32,!386
|
||||
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
_AT_HWCAP = 16
|
||||
_AT_HWCAP2 = 26
|
||||
|
||||
procAuxv = "/proc/self/auxv"
|
||||
|
||||
uintSize uint = 32 << (^uint(0) >> 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 init() {
|
||||
buf, err := ioutil.ReadFile(procAuxv)
|
||||
if err != nil {
|
||||
panic("read proc auxv failed: " + err.Error())
|
||||
}
|
||||
|
||||
pb := int(uintSize / 8)
|
||||
|
||||
for i := 0; i < len(buf)-pb*2; i += pb * 2 {
|
||||
var tag, val uint
|
||||
switch uintSize {
|
||||
case 32:
|
||||
tag = uint(binary.LittleEndian.Uint32(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint32(buf[i+pb:]))
|
||||
case 64:
|
||||
if runtime.GOARCH == "ppc64" {
|
||||
tag = uint(binary.BigEndian.Uint64(buf[i:]))
|
||||
val = uint(binary.BigEndian.Uint64(buf[i+pb:]))
|
||||
} else {
|
||||
tag = uint(binary.LittleEndian.Uint64(buf[i:]))
|
||||
val = uint(binary.LittleEndian.Uint64(buf[i+pb:]))
|
||||
}
|
||||
}
|
||||
switch tag {
|
||||
case _AT_HWCAP:
|
||||
HWCap = val
|
||||
case _AT_HWCAP2:
|
||||
HWCap2 = val
|
||||
}
|
||||
}
|
||||
doinit()
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// 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
|
||||
|
||||
func doinit() {}
|
|
@ -0,0 +1,11 @@
|
|||
// 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
|
||||
|
||||
func doinit() {}
|
|
@ -0,0 +1,32 @@
|
|||
// 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 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
|
||||
}
|
|
@ -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.
|
||||
|
||||
package cpu
|
||||
|
||||
const cacheLineSize = 256
|
||||
|
||||
func doinit() {}
|
|
@ -0,0 +1,55 @@
|
|||
// 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() {
|
||||
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)
|
||||
|
||||
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.HasADX = isSet(19, ebx7)
|
||||
}
|
||||
|
||||
func isSet(bitpos uint, value uint32) bool {
|
||||
return value&(1<<bitpos) != 0
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// 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 "textflag.h"
|
||||
|
||||
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
TEXT ·cpuid(SB), NOSPLIT, $0-24
|
||||
MOVL eaxArg+0(FP), AX
|
||||
MOVL ecxArg+4(FP), CX
|
||||
CPUID
|
||||
MOVL AX, eax+8(FP)
|
||||
MOVL BX, ebx+12(FP)
|
||||
MOVL CX, ecx+16(FP)
|
||||
MOVL DX, edx+20(FP)
|
||||
RET
|
||||
|
||||
// func xgetbv() (eax, edx uint32)
|
||||
TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
||||
MOVL $0, CX
|
||||
XGETBV
|
||||
MOVL AX, eax+0(FP)
|
||||
MOVL DX, edx+4(FP)
|
||||
RET
|
|
@ -346,10 +346,10 @@
|
|||
"revisionTime": "2017-08-14T17:01:13Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "28UVHMmHx0iqO0XiJsjx+fwILyI=",
|
||||
"checksumSHA1": "HbX4qEQzpXgMgb3iwoJK4IE/96A=",
|
||||
"path": "github.com/rjeczalik/notify",
|
||||
"revision": "c31e5f2cb22b3e4ef3f882f413847669bf2652b9",
|
||||
"revisionTime": "2018-02-03T14:01:15Z"
|
||||
"revision": "629144ba06a1c6af28c1e42c228e3d42594ce081",
|
||||
"revisionTime": "2018-11-26T18:32:43Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "5uqO4ITTDMklKi3uNaE/D9LQ5nM=",
|
||||
|
@ -621,6 +621,12 @@
|
|||
"revision": "f52d1811a62927559de87708c8913c1650ce4f26",
|
||||
"revisionTime": "2017-05-17T20:25:26Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "FaM+wRnCKV3kavPGO6kxCPz5x/Q=",
|
||||
"path": "golang.org/x/sys/cpu",
|
||||
"revision": "48ac38b7c8cbedd50b1613c0fccacfc7d88dfcdf",
|
||||
"revisionTime": "2019-01-09T08:27:30Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "r1jWq0V3AI5DLN0aCnXXMH/is9Q=",
|
||||
"path": "golang.org/x/sys/unix",
|
||||
|
|
Loading…
Reference in New Issue