Add //pkg/sync:generic_atomicptr.
PiperOrigin-RevId: 215620949 Change-Id: I519da4b44386d950443e5784fb8c48ff9a36c5d3
This commit is contained in:
parent
7a6412cb0b
commit
8e729e0e1f
|
@ -7,6 +7,14 @@ package(
|
|||
|
||||
load("//tools/go_generics:defs.bzl", "go_template")
|
||||
|
||||
go_template(
|
||||
name = "generic_atomicptr",
|
||||
srcs = ["atomicptr_unsafe.go"],
|
||||
types = [
|
||||
"Value",
|
||||
],
|
||||
)
|
||||
|
||||
go_template(
|
||||
name = "generic_seqatomic",
|
||||
srcs = ["seqatomic_unsafe.go"],
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2018 Google Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// Package template doesn't exist. This file must be instantiated using the
|
||||
// go_template_instance rule in tools/go_generics/defs.bzl.
|
||||
package template
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Value is a required type parameter.
|
||||
type Value struct{}
|
||||
|
||||
// An AtomicPtr is a pointer to a value of type Value that can be atomically
|
||||
// loaded and stored. The zero value of an AtomicPtr represents nil.
|
||||
//
|
||||
// Note that copying AtomicPtr by value performs a non-atomic read of the
|
||||
// stored pointer, which is unsafe if Store() can be called concurrently; in
|
||||
// this case, do `dst.Store(src.Load())` instead.
|
||||
type AtomicPtr struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
// Load returns the value set by the most recent Store. It returns nil if there
|
||||
// has been no previous call to Store.
|
||||
func (p *AtomicPtr) Load() *Value {
|
||||
return (*Value)(atomic.LoadPointer(&p.ptr))
|
||||
}
|
||||
|
||||
// Store sets the value returned by Load to x.
|
||||
func (p *AtomicPtr) Store(x *Value) {
|
||||
atomic.StorePointer(&p.ptr, (unsafe.Pointer)(x))
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package(licenses = ["notice"]) # Apache 2.0
|
||||
|
||||
load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
|
||||
load("//tools/go_generics:defs.bzl", "go_template_instance")
|
||||
|
||||
go_template_instance(
|
||||
name = "atomicptr_int",
|
||||
out = "atomicptr_int.go",
|
||||
package = "atomicptr",
|
||||
suffix = "Int",
|
||||
template = "//pkg/sync:generic_atomicptr",
|
||||
types = {
|
||||
"Value": "int",
|
||||
},
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "atomicptr",
|
||||
srcs = ["atomicptr_int.go"],
|
||||
importpath = "gvisor.googlesource.com/gvisor/pkg/sync/atomicptr",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "atomicptr_test",
|
||||
size = "small",
|
||||
srcs = ["atomicptr_test.go"],
|
||||
embed = [":atomicptr"],
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2018 Google Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package atomicptr
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func newInt(val int) *int {
|
||||
return &val
|
||||
}
|
||||
|
||||
func TestAtomicPtr(t *testing.T) {
|
||||
var p AtomicPtrInt
|
||||
if got := p.Load(); got != nil {
|
||||
t.Errorf("initial value is %p (%v), wanted nil", got, got)
|
||||
}
|
||||
want := newInt(42)
|
||||
p.Store(want)
|
||||
if got := p.Load(); got != want {
|
||||
t.Errorf("wrong value: got %p (%v), wanted %p (%v)", got, got, want, want)
|
||||
}
|
||||
want = newInt(100)
|
||||
p.Store(want)
|
||||
if got := p.Load(); got != want {
|
||||
t.Errorf("wrong value: got %p (%v), wanted %p (%v)", got, got, want, want)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue