codeberg.org/gruf/go-mutexes@v1.5.0/cond.go (about)

     1  package mutexes
     2  
     3  import (
     4  	"sync"
     5  	"unsafe"
     6  )
     7  
     8  // Cond is similar to a sync.Cond{}, but
     9  // it encompasses the Mutex{} within itself.
    10  type Cond struct {
    11  	notify notifyList
    12  	sync.Mutex
    13  }
    14  
    15  // See: sync.Cond{}.Wait().
    16  func (c *Cond) Wait() {
    17  	t := runtime_notifyListAdd(&c.notify)
    18  	c.Mutex.Unlock()
    19  	runtime_notifyListWait(&c.notify, t)
    20  	c.Mutex.Lock()
    21  }
    22  
    23  // See: sync.Cond{}.Signal().
    24  func (c *Cond) Signal() { runtime_notifyListNotifyOne(&c.notify) }
    25  
    26  // See: sync.Cond{}.Broadcast().
    27  func (c *Cond) Broadcast() { runtime_notifyListNotifyAll(&c.notify) }
    28  
    29  // RWCond is similar to a sync.Cond{}, but
    30  // it encompasses the RWMutex{} within itself.
    31  type RWCond struct {
    32  	notify notifyList
    33  	sync.RWMutex
    34  }
    35  
    36  // See: sync.Cond{}.Wait().
    37  func (c *RWCond) Wait() {
    38  	t := runtime_notifyListAdd(&c.notify)
    39  	c.RWMutex.Unlock()
    40  	runtime_notifyListWait(&c.notify, t)
    41  	c.RWMutex.Lock()
    42  }
    43  
    44  // See: sync.Cond{}.Signal().
    45  func (c *RWCond) Signal() { runtime_notifyListNotifyOne(&c.notify) }
    46  
    47  // See: sync.Cond{}.Broadcast().
    48  func (c *RWCond) Broadcast() { runtime_notifyListNotifyAll(&c.notify) }
    49  
    50  // unused fields left
    51  // un-named for safety.
    52  type notifyList struct {
    53  	_      uint32         // wait   uint32
    54  	notify uint32         // notify uint32
    55  	_      uintptr        // lock   mutex
    56  	_      unsafe.Pointer // head   *sudog
    57  	_      unsafe.Pointer // tail   *sudog
    58  }
    59  
    60  // See runtime/sema.go for documentation.
    61  //
    62  //go:linkname runtime_notifyListAdd sync.runtime_notifyListAdd
    63  func runtime_notifyListAdd(l *notifyList) uint32
    64  
    65  // See runtime/sema.go for documentation.
    66  //
    67  //go:linkname runtime_notifyListWait sync.runtime_notifyListWait
    68  func runtime_notifyListWait(l *notifyList, t uint32)
    69  
    70  // See runtime/sema.go for documentation.
    71  //
    72  //go:linkname runtime_notifyListNotifyOne sync.runtime_notifyListNotifyOne
    73  func runtime_notifyListNotifyOne(l *notifyList)
    74  
    75  // See runtime/sema.go for documentation.
    76  //
    77  //go:linkname runtime_notifyListNotifyAll sync.runtime_notifyListNotifyAll
    78  func runtime_notifyListNotifyAll(l *notifyList)
    79  
    80  // Ensure that sync and runtime agree on size of notifyList.
    81  //
    82  //go:linkname runtime_notifyListCheck sync.runtime_notifyListCheck
    83  func runtime_notifyListCheck(size uintptr)
    84  func init() {
    85  	var n notifyList
    86  	runtime_notifyListCheck(unsafe.Sizeof(n))
    87  }