package part
import (
- "sync"
- "unsafe"
+ "container/list"
"runtime"
+ "sync"
"sync/atomic"
- "container/list"
+ "unsafe"
+
idpool "github.com/qydysky/part/idpool"
)
-type SkipFunc struct{//新的跳过
+type SkipFunc struct { //新的跳过
c unsafe.Pointer
}
atomic.CompareAndSwapPointer(&t.c, atomic.LoadPointer(&t.c), nil)
}
-type FlashFunc struct{//新的替换旧的
- b *list.List
+type FlashFunc struct { //新的替换旧的
+ b *list.List
pool *idpool.Idpool
}
func (t *FlashFunc) Flash() (current uintptr) {
- if t.pool == nil {t.pool = idpool.New()}
- if t.b == nil {t.b = list.New()}
+ if t.pool == nil {
+ t.pool = idpool.New()
+ }
+ if t.b == nil {
+ t.b = list.New()
+ }
e := t.pool.Get()
current = e.Id
t.b.PushFront(e)
-
+
return
}
t.b.Remove(t.b.Back())
}
-func (t *FlashFunc) NeedExit(current uintptr) (bool) {
+func (t *FlashFunc) NeedExit(current uintptr) bool {
return current != t.b.Front().Value.(*idpool.Id).Id
}
-type BlockFunc struct{//新的等待旧的
+type BlockFunc struct { //新的等待旧的
sync.Mutex
}
t.Unlock()
}
-type BlockFuncN struct{//新的等待旧的 个数
- n int64
- Max int64
+type BlockFuncN struct { //新的等待旧的 个数
+ started int64
+ n int64
+ Max int64
}
func (t *BlockFuncN) Block() {
for {
now := atomic.LoadInt64(&t.n)
- if now < t.Max && now >= 0 {break}
+ if now < t.Max && now >= 0 {
+ break
+ }
runtime.Gosched()
}
atomic.AddInt64(&t.n, 1)
+ atomic.StoreInt64(&t.started, 1)
}
func (t *BlockFuncN) UnBlock() {
for {
now := atomic.LoadInt64(&t.n)
- if now > 0 {break}
+ if now > 0 {
+ break
+ }
runtime.Gosched()
}
atomic.AddInt64(&t.n, -1)
}
func (t *BlockFuncN) None() {
+ for !atomic.CompareAndSwapInt64(&t.started, 1, 0) {
+ runtime.Gosched()
+ }
for !atomic.CompareAndSwapInt64(&t.n, 0, -1) {
runtime.Gosched()
}
for !atomic.CompareAndSwapInt64(&t.n, -1, 0) {
runtime.Gosched()
}
-}
\ No newline at end of file
+}
func Test_SkipFunc(t *testing.T) {
var b SkipFunc
- var a = func(i int){
- if b.NeedSkip() {return}
+ var a = func(i int) {
+ if b.NeedSkip() {
+ return
+ }
defer b.UnSet()
- t.Log(i,`.`)
+ t.Log(i, `.`)
time.Sleep(time.Second)
- t.Log(i,`..`)
+ t.Log(i, `..`)
}
t.Log(`just show 1 or 2 twice`)
go a(1)
go a(2)
- time.Sleep(5*time.Second)
+ time.Sleep(5 * time.Second)
}
func Test_FlashFunc(t *testing.T) {
var b FlashFunc
- var a = func(i int){
+ var a = func(i int) {
id := b.Flash()
defer b.UnFlash()
-
- t.Log(i,`.`)
+
+ t.Log(i, `.`)
time.Sleep(time.Second)
- if b.NeedExit(id) {return}
- t.Log(i,`.`)
+ if b.NeedExit(id) {
+ return
+ }
+ t.Log(i, `.`)
}
t.Log(`show 1 or 2, then show the other twice`)
go a(1)
go a(2)
- time.Sleep(5*time.Second)
+ time.Sleep(5 * time.Second)
}
func Test_BlockFunc(t *testing.T) {
var b BlockFunc
- var a = func(i int){
+ var a = func(i int) {
b.Block()
defer b.UnBlock()
- t.Log(i,`.`)
+ t.Log(i, `.`)
time.Sleep(time.Second)
- t.Log(i,`.`)
+ t.Log(i, `.`)
}
t.Log(`show 1 and 2 twice`)
go a(1)
go a(2)
- time.Sleep(5*time.Second)
+ time.Sleep(5 * time.Second)
}
func Test_BlockFuncN(t *testing.T) {
- var b = BlockFuncN{
- Max:2,
+ var b = &BlockFuncN{
+ Max: 2,
}
- var a = func(i int){
- b.Block()
+ var a = func(i int) {
defer b.UnBlock()
- t.Log(i,`.`)
+ b.Block()
+ t.Log(i, `.`)
time.Sleep(time.Second)
- t.Log(i,`.`)
+ t.Log(i, `.`)
}
t.Log(`show two . at one time`)
+ go a(0)
go a(1)
go a(2)
go a(3)
- time.Sleep(5*time.Second)
-}
\ No newline at end of file
+ b.None()
+ b.UnNone()
+ t.Log(`fin`)
+}