9fans.net/go@v0.0.7/cmd/acme/internal/util/util.go (about) 1 // #include <u.h> 2 // #include <libc.h> 3 // #include <draw.h> 4 // #include <thread.h> 5 // #include <cursor.h> 6 // #include <mouse.h> 7 // #include <keyboard.h> 8 // #include <frame.h> 9 // #include <fcall.h> 10 // #include <plumb.h> 11 // #include <libsec.h> 12 // #include "dat.h" 13 // #include "fns.h" 14 15 package util 16 17 import ( 18 "log" 19 "sync" 20 "sync/atomic" 21 ) 22 23 func Min(a int, b int) int { 24 if a < b { 25 return a 26 } 27 return b 28 } 29 30 func Max(a int, b int) int { 31 if a > b { 32 return a 33 } 34 return b 35 } 36 37 func Fatal(s string) { 38 log.Fatalf("acme: %s\n", s) 39 } 40 41 var locks struct { 42 mu sync.Mutex 43 cond sync.Cond 44 } 45 46 func init() { 47 locks.cond.L = &locks.mu 48 } 49 50 type QLock struct { 51 held uint32 52 } 53 54 func (l *QLock) TryLock() bool { 55 return atomic.CompareAndSwapUint32(&l.held, 0, 1) 56 } 57 58 func (l *QLock) Unlock() { 59 v := atomic.SwapUint32(&l.held, 0) 60 if v == 0 { 61 panic("Unlock of unlocked lock") 62 } 63 if v > 1 { 64 locks.cond.Broadcast() 65 } 66 } 67 68 func (l *QLock) Lock() { 69 if atomic.AddUint32(&l.held, 1) == 1 { 70 return 71 } 72 locks.mu.Lock() 73 defer locks.mu.Unlock() 74 75 for atomic.AddUint32(&l.held, 1) != 1 { 76 locks.cond.Wait() 77 } 78 } 79 80 func Incref(p *uint32) { atomic.AddUint32(p, 1) } 81 82 func Decref(p *uint32) uint32 { 83 return atomic.AddUint32(p, ^uint32(0)) 84 }