-
Notifications
You must be signed in to change notification settings - Fork 26
/
readside.go
78 lines (67 loc) · 1.67 KB
/
readside.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Package urcu is a thin wrapper of Userspace RCU library.
package urcu
/*
#include "../../csrc/core/urcu.h"
*/
import "C"
import (
"runtime"
"github.com/usnistgov/ndn-dpdk/core/logging"
)
var logger = logging.New("urcu")
// ReadSide represents an RCU read-side thread.
// Fields are exported so that they can be updated to reflect what C code did.
type ReadSide struct {
IsOnline bool
NLocks int
}
// Close unregisters current thread as an RCU read-side thread.
// If the thread is unregistered in C code, do not call this function.
func (*ReadSide) Close() error {
C.rcu_unregister_thread()
runtime.UnlockOSThread()
return nil
}
// Offline marks current thread offline.
func (rs *ReadSide) Offline() {
if rs.NLocks > 0 {
logger.Panic("cannot go offline when locked")
}
rs.IsOnline = false
C.rcu_thread_offline()
}
// Online marks current thread online.
func (rs *ReadSide) Online() {
C.rcu_thread_online()
rs.IsOnline = true
}
// Quiescent indicates current thread is quiescent.
func (rs *ReadSide) Quiescent() {
if rs.NLocks > 0 {
logger.Panic("cannot go quiescent when locked")
}
C.rcu_quiescent_state()
}
// Lock obtains read-side lock.
func (rs *ReadSide) Lock() {
if !rs.IsOnline {
logger.Panic("cannot lock when offline")
}
rs.NLocks++
C.rcu_read_lock()
}
// Unlock releases read-side lock.
func (rs *ReadSide) Unlock() {
if rs.NLocks <= 0 {
return
}
C.rcu_read_unlock()
rs.NLocks--
}
// NewReadSide registers current thread as an RCU read-side thread.
// If the thread is registered in C code, do not call this function, use a zero ReadSide instead.
func NewReadSide() *ReadSide {
runtime.LockOSThread()
C.rcu_register_thread()
return &ReadSide{true, 0}
}