当前位置: 首页>>代码示例>>Golang>>正文


Golang atomic.CompareAndSwapUint64函数代码示例

本文整理汇总了Golang中sync/atomic.CompareAndSwapUint64函数的典型用法代码示例。如果您正苦于以下问题:Golang CompareAndSwapUint64函数的具体用法?Golang CompareAndSwapUint64怎么用?Golang CompareAndSwapUint64使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了CompareAndSwapUint64函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: TestCommandParallelismConstraint

// Ensure that command parallelism constraints are respected
func TestCommandParallelismConstraint(t *testing.T) {
	assert := assert.New(t)
	sConfig, cConfig := getConfigs()
	cConfig.MaxConcurrentCommands = 1
	service := NewService(sConfig)

	counter := uint64(0)

	wg := &sync.WaitGroup{}
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go func() {
			for j := 0; j < 10; j++ {
				err := service.Run(testCommand, func() (error, error) {
					if !atomic.CompareAndSwapUint64(&counter, 0, 1) {
						t.FailNow()
					}

					time.Sleep(time.Millisecond)

					if !atomic.CompareAndSwapUint64(&counter, 1, 0) {
						t.FailNow()
					}

					return nil, nil
				}, nil)
				assert.Nil(err)
			}
			wg.Done()
		}()
	}
	wg.Wait()
}
开发者ID:Workiva,项目名称:go-hystrimp,代码行数:34,代码来源:service_test.go

示例2: TestNoRaceAtomicCASCASUInt64

func TestNoRaceAtomicCASCASUInt64(t *testing.T) {
	var x int64
	var s uint64
	go func() {
		x = 2
		if !atomic.CompareAndSwapUint64(&s, 0, 1) {
			panic("")
		}
	}()
	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
		runtime.Gosched()
	}
	x = 1
}
开发者ID:Xiahl1990,项目名称:go,代码行数:14,代码来源:atomic_test.go

示例3: TestPageCache

func TestPageCache(t *testing.T) {
	c1 := newPageCache()

	changeFirst := func(p Pages) {
		p[0].Description = "changed"
	}

	var o1 uint64 = 0
	var o2 uint64 = 0

	var wg sync.WaitGroup

	var l1 sync.Mutex
	var l2 sync.Mutex

	var testPageSets []Pages

	for j := 0; j < 50; j++ {
		testPageSets = append(testPageSets, createSortTestPages(j+1))
	}

	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for j, pages := range testPageSets {
				msg := fmt.Sprintf("Go %d %d %d %d", i, j, o1, o2)
				l1.Lock()
				p, c := c1.get("k1", pages, nil)
				assert.Equal(t, !atomic.CompareAndSwapUint64(&o1, uint64(j), uint64(j+1)), c, "c1: "+msg)
				l1.Unlock()
				p2, c2 := c1.get("k1", p, nil)
				assert.True(t, c2)
				assert.True(t, probablyEqualPages(p, p2))
				assert.True(t, probablyEqualPages(p, pages))
				assert.NotNil(t, p, msg)

				l2.Lock()
				p3, c3 := c1.get("k2", pages, changeFirst)
				assert.Equal(t, !atomic.CompareAndSwapUint64(&o2, uint64(j), uint64(j+1)), c3, "c3: "+msg)
				l2.Unlock()
				assert.NotNil(t, p3, msg)
				assert.Equal(t, p3[0].Description, "changed", msg)
			}
		}()
	}

	wg.Wait()

}
开发者ID:bramp,项目名称:hugo,代码行数:50,代码来源:pageCache_test.go

示例4: ObserveHist

// ObserveHist adds an observation to the given histogram. The id parameter is a handle
// returned by the AddHistogram method. Using numbers not returned by AddHistogram is
// undefined behavior and may cause a panic.
func ObserveHist(id uint32, value uint64) {
	h := &hists[id]

	// We lock here to ensure that the min and max values are true to this time
	// period, meaning extractAndReset won't pull the data out from under us
	// while the current observation is being compared. Otherwise, min and max
	// could come from the previous period on the next read. Same with average.
	h.lock.RLock()

	// Keep a running total for average
	atomic.AddUint64(&h.dat.total, value)

	// Set max and min (if needed) in an atomic fashion
	for {
		max := atomic.LoadUint64(&h.dat.max)
		if value < max || atomic.CompareAndSwapUint64(&h.dat.max, max, value) {
			break
		}
	}
	for {
		min := atomic.LoadUint64(&h.dat.min)
		if value > min || atomic.CompareAndSwapUint64(&h.dat.min, min, value) {
			break
		}
	}

	// Record the bucketized histograms
	bucket := getBucket(value)
	atomic.AddUint64(&bhists[id].buckets[bucket], 1)

	// Count and possibly return for sampling
	c := atomic.AddUint64(&h.dat.count, 1)
	if hSampled[id] {
		// Sample, keep every 4th observation
		if (c & 0x3) > 0 {
			h.lock.RUnlock()
			return
		}
	}

	// Get the current index as the count % buflen
	idx := atomic.AddUint64(&h.dat.kept, 1) & buflen

	// Add observation
	h.dat.buf[idx] = value

	// No longer "reading"
	h.lock.RUnlock()
}
开发者ID:Netflix,项目名称:rend,代码行数:52,代码来源:histograms.go

示例5: NewScampDebugger

func NewScampDebugger(conn *tls.Conn, clientType string) (handle *ScampDebugger, err error) {
	var worked bool = false
	var thisDebuggerId uint64 = 0
	for i := 0; i < 10; i++ {
		loadedVal := atomic.LoadUint64(&scampDebuggerId)
		thisDebuggerId = loadedVal + 1
		worked = atomic.CompareAndSwapUint64(&scampDebuggerId, loadedVal, thisDebuggerId)
		if worked {
			break
		}
	}
	if !worked {
		panic("never should happen...")
	}

	handle = new(ScampDebugger)

	var path = fmt.Sprintf("%s.%s.%s.%d", writeTeeTargetPath, randomDebuggerString, clientType, thisDebuggerId)

	handle.file, err = os.Create(path)
	if err != nil {
		return
	}

	return
}
开发者ID:gudTECH,项目名称:scamp-go,代码行数:26,代码来源:scamp_debugger.go

示例6: Put

// Put adds the provided item to the queue.  If the queue is full, this
// call will block until an item is added to the queue or Dispose is called
// on the queue.  An error will be returned if the queue is disposed.
func (rb *RingBuffer) Put(item interface{}) error {
	var n *node
	pos := atomic.LoadUint64(&rb.queue)
	i := 0
L:
	for {
		if atomic.LoadUint64(&rb.disposed) == 1 {
			return disposedError
		}

		n = rb.nodes[pos&rb.mask]
		seq := atomic.LoadUint64(&n.position)
		switch dif := seq - pos; {
		case dif == 0:
			if atomic.CompareAndSwapUint64(&rb.queue, pos, pos+1) {
				break L
			}
		case dif < 0:
			panic(`Ring buffer in a compromised state during a put operation.`)
		default:
			pos = atomic.LoadUint64(&rb.queue)
		}

		if i == 10000 {
			runtime.Gosched() // free up the cpu before the next iteration
			i = 0
		} else {
			i++
		}
	}

	n.data = item
	atomic.StoreUint64(&n.position, pos+1)
	return nil
}
开发者ID:brianshannan-wf,项目名称:go-datastructures,代码行数:38,代码来源:ring.go

示例7: getOrInsert

func (c *container) getOrInsert(k uint64, v unsafe.Pointer) unsafe.Pointer {
	bi := k & (c.sz - 1)
	b := c.list[bi]
	for i := range b.elems {
		e := &b.elems[i]
		// Once allocated a valid key, it would never change. So, first check if
		// it's allocated. If not, then allocate it. If can't, or not allocated,
		// then check if it's k. If it is, then replace value. Otherwise continue.
		// This sequence could be problematic, if this happens:
		// Main thread runs Step 1. Check
		if atomic.CompareAndSwapUint64(&e.k, 0, k) { // Step 1.
			atomic.AddUint32(&c.numElems, 1)
			if atomic.CompareAndSwapPointer(&e.v, nil, v) {
				return v
			}
			return atomic.LoadPointer(&e.v)
		}

		if atomic.LoadUint64(&e.k) == k {
			// Swap if previous pointer is nil.
			if atomic.CompareAndSwapPointer(&e.v, nil, v) {
				return v
			}
			return atomic.LoadPointer(&e.v)
		}
	}
	return nil
}
开发者ID:dgraph-io,项目名称:experiments,代码行数:28,代码来源:map.go

示例8: Enqueue

// Enqueue adds a new element to the tail of the ring buffer
// It returns true if the operation is successful, false otherwise
// It blocks on a full queue
func (rb *RingBuffer) Enqueue(data interface{}) bool {
	var cell *ring_cell
	pos := atomic.LoadUint64(&rb.enqueue_pos_)
	i := 0
Loop:
	for {
		cell = rb.buffer_[pos&rb.buffer_mask_]
		seq := atomic.LoadUint64(&cell.sequence_)
		switch dif := seq - pos; {
		case dif == 0:
			if atomic.CompareAndSwapUint64(&rb.enqueue_pos_, pos, pos+1) {
				break Loop
			}
		case dif < 0:
			return false
		default:
			pos = atomic.LoadUint64(&rb.enqueue_pos_)
		}
		// freeup the cpu
		if i >= freeup_threshold {
			runtime.Gosched()
			i = 0
		} else {
			i++
		}
	}

	cell.data_ = data
	atomic.StoreUint64(&cell.sequence_, pos+1)
	return true
}
开发者ID:archfiery,项目名称:literate-disco,代码行数:34,代码来源:ring_buffer.go

示例9: rwunlock

// unlock removes a reference from mu and unlocks mu.
// It reports whether there is no remaining reference.
func (mu *fdMutex) rwunlock(read bool) bool {
	var mutexBit, mutexWait, mutexMask uint64
	var mutexSema *uint32
	if read {
		mutexBit = mutexRLock
		mutexWait = mutexRWait
		mutexMask = mutexRMask
		mutexSema = &mu.rsema
	} else {
		mutexBit = mutexWLock
		mutexWait = mutexWWait
		mutexMask = mutexWMask
		mutexSema = &mu.wsema
	}
	for {
		old := atomic.LoadUint64(&mu.state)
		if old&mutexBit == 0 || old&mutexRefMask == 0 {
			panic("net: inconsistent fdMutex")
		}
		// Drop lock, drop reference and wake read waiter if present.
		new := (old &^ mutexBit) - mutexRef
		if old&mutexMask != 0 {
			new -= mutexWait
		}
		if atomic.CompareAndSwapUint64(&mu.state, old, new) {
			if old&mutexMask != 0 {
				runtime_Semrelease(mutexSema)
			}
			return new&(mutexClosed|mutexRefMask) == mutexClosed
		}
	}
}
开发者ID:2thetop,项目名称:go,代码行数:34,代码来源:fd_mutex.go

示例10: Get

// Get will return the next item in the queue.  This call will block
// if the queue is empty.  This call will unblock when an item is added
// to the queue or Dispose is called on the queue.  An error will be returned
// if the queue is disposed.
func (rb *RingBuffer) Get() (interface{}, error) {
	var n *node
	pos := atomic.LoadUint64(&rb.dequeue)
	i := 0
L:
	for {
		if atomic.LoadUint64(&rb.disposed) == 1 {
			return nil, ErrDisposed
		}

		n = rb.nodes[pos&rb.mask]
		seq := atomic.LoadUint64(&n.position)
		switch dif := seq - (pos + 1); {
		case dif == 0:
			if atomic.CompareAndSwapUint64(&rb.dequeue, pos, pos+1) {
				break L
			}
		case dif < 0:
			panic(`Ring buffer in compromised state during a get operation.`)
		default:
			pos = atomic.LoadUint64(&rb.dequeue)
		}

		if i == 10000 {
			runtime.Gosched() // free up the cpu before the next iteration
			i = 0
		} else {
			i++
		}
	}
	data := n.data
	n.data = nil
	atomic.StoreUint64(&n.position, pos+rb.mask+1)
	return data, nil
}
开发者ID:amareshp,项目名称:go-datastructures,代码行数:39,代码来源:ring.go

示例11: Dequeue

// Dequeue removes and returns the `oldest` element from the ring buffer
// It also returns true if the operation is successful, false otherwise
// It blocks on an empty queue
func (rb *RingBuffer) Dequeue() (data interface{}, b bool) {
	var cell *ring_cell
	pos := atomic.LoadUint64(&rb.dequeue_pos_)
	i := 0
Loop:
	for {
		cell = rb.buffer_[pos&rb.buffer_mask_]
		seq := atomic.LoadUint64(&cell.sequence_)
		switch dif := seq - pos - 1; {
		case dif == 0:
			if atomic.CompareAndSwapUint64(&rb.dequeue_pos_, pos, pos+1) {
				break Loop
			}
		case dif < 0:
			return nil, false
		default:
			pos = atomic.LoadUint64(&rb.dequeue_pos_)
		}
		// freeup the cpu
		if i >= freeup_threshold {
			runtime.Gosched()
			i = 0
		} else {
			i++
		}
	}
	data = cell.data_
	atomic.StoreUint64(&cell.sequence_, pos+rb.buffer_mask_+1)
	b = true
	return data, b
}
开发者ID:archfiery,项目名称:literate-disco,代码行数:34,代码来源:ring_buffer.go

示例12: incrementAndGet

// atomically adds incr to val, returns new val
func incrementAndGet(val *uint64, incr uint64) uint64 {
	currVal := atomic.LoadUint64(val)
	for !atomic.CompareAndSwapUint64(val, currVal, currVal+incr) {
		currVal = atomic.LoadUint64(val)
	}
	return currVal + incr
}
开发者ID:jonpugh,项目名称:maggiefs,代码行数:8,代码来源:leaseserver.go

示例13: increfAndClose

// increfAndClose sets the state of mu to closed.
// It reports whether there is no remaining reference.
func (mu *fdMutex) increfAndClose() bool {
	for {
		old := atomic.LoadUint64(&mu.state)
		if old&mutexClosed != 0 {
			return false
		}
		// Mark as closed and acquire a reference.
		new := (old | mutexClosed) + mutexRef
		if new&mutexRefMask == 0 {
			panic("net: inconsistent fdMutex")
		}
		// Remove all read and write waiters.
		new &^= mutexRMask | mutexWMask
		if atomic.CompareAndSwapUint64(&mu.state, old, new) {
			// Wake all read and write waiters,
			// they will observe closed flag after wakeup.
			for old&mutexRMask != 0 {
				old -= mutexRWait
				runtime_Semrelease(&mu.rsema)
			}
			for old&mutexWMask != 0 {
				old -= mutexWWait
				runtime_Semrelease(&mu.wsema)
			}
			return true
		}
	}
}
开发者ID:2thetop,项目名称:go,代码行数:30,代码来源:fd_mutex.go

示例14: GetStream

func (s *IDGenerator) GetStream() (int, bool) {
	// based closely on the java-driver stream ID generator
	// avoid false sharing subsequent requests.
	offset := atomic.LoadUint32(&s.offset)
	for !atomic.CompareAndSwapUint32(&s.offset, offset, (offset+1)%s.numBuckets) {
		offset = atomic.LoadUint32(&s.offset)
	}
	offset = (offset + 1) % s.numBuckets

	for i := uint32(0); i < s.numBuckets; i++ {
		pos := int((i + offset) % s.numBuckets)

		bucket := atomic.LoadUint64(&s.streams[pos])
		if bucket == math.MaxUint64 {
			// all streams in use
			continue
		}

		for j := 0; j < bucketBits; j++ {
			mask := uint64(1 << streamOffset(j))
			if bucket&mask == 0 {
				if atomic.CompareAndSwapUint64(&s.streams[pos], bucket, bucket|mask) {
					atomic.AddInt32(&s.inuseStreams, 1)
					return streamFromBucket(int(pos), j), true
				}
				bucket = atomic.LoadUint64(&s.streams[offset])
			}
		}
	}

	return 0, false
}
开发者ID:vincentaubert,项目名称:vault,代码行数:32,代码来源:streams.go

示例15: Clear

func (s *IDGenerator) Clear(stream int) (inuse bool) {
	offset := bucketOffset(stream)
	bucket := atomic.LoadUint64(&s.streams[offset])

	mask := uint64(1) << streamOffset(stream)
	if bucket&mask != mask {
		// already cleared
		return false
	}

	for !atomic.CompareAndSwapUint64(&s.streams[offset], bucket, bucket & ^mask) {
		bucket = atomic.LoadUint64(&s.streams[offset])
		if bucket&mask != mask {
			// already cleared
			return false
		}
	}

	// TODO: make this account for 0 stream being reserved
	if atomic.AddInt32(&s.inuseStreams, -1) < 0 {
		// TODO(zariel): remove this
		panic("negative streams inuse")
	}

	return true
}
开发者ID:vincentaubert,项目名称:vault,代码行数:26,代码来源:streams.go


注:本文中的sync/atomic.CompareAndSwapUint64函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。