Commit 8dbd955e authored by Kirill Smelkov's avatar Kirill Smelkov

X API for tracepoints is more or less ready

parent 55cea17a
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
//"../../zodb" //"../../zodb"
"../../zodb/storage/fs1" "../../zodb/storage/fs1"
"../../xcommon/tracing"
"../../xcommon/xnet" "../../xcommon/xnet"
"../../xcommon/xnet/pipenet" "../../xcommon/xnet/pipenet"
"../../xcommon/xsync" "../../xcommon/xsync"
...@@ -128,17 +129,23 @@ func TestMasterStorage(t *testing.T) { ...@@ -128,17 +129,23 @@ func TestMasterStorage(t *testing.T) {
net := pipenet.New("testnet") // test network net := pipenet.New("testnet") // test network
tg := &tracing.Group{}
defer tg.Done()
tracing.Lock() tracing.Lock()
neo_traceConnRecv_Attach(tracer.traceNeoConnRecv) neo_traceConnRecv_Attach(tg, tracer.traceNeoConnRecv)
neo_traceConnSend_Attach(tracer.traceNeoConnSend) neo_traceConnSend_Attach(tg, tracer.traceNeoConnSend)
tracing.Unlock() tracing.Unlock()
/*
defer func() { defer func() {
tracing.Lock() tracing.Lock()
defer tracing.Unlock() defer tracing.Unlock()
tctx.Done() tctx.Done()
}() }()
*/
// shortcut for addresses // shortcut for addresses
xaddr := func(addr string) *pipenet.Addr { xaddr := func(addr string) *pipenet.Addr {
......
...@@ -20,6 +20,8 @@ package server ...@@ -20,6 +20,8 @@ package server
import ( import (
"../../neo" "../../neo"
"../../xcommon/tracing"
_ "unsafe" _ "unsafe"
) )
...@@ -27,7 +29,7 @@ import ( ...@@ -27,7 +29,7 @@ import (
// + check consistency (e.g. by hash in neo.trace and here must be the same) // + check consistency (e.g. by hash in neo.trace and here must be the same)
//go:linkname neo_traceConnRecv_Attach _/home/kirr/src/wendelin/neo/neoppod-t/go/neo.traceConnRecv_Attach //go:linkname neo_traceConnRecv_Attach _/home/kirr/src/wendelin/neo/neoppod-t/go/neo.traceConnRecv_Attach
func neo_traceConnRecv_Attach(func(*neo.Conn, neo.Msg)) func neo_traceConnRecv_Attach(*tracing.Group, func(*neo.Conn, neo.Msg)) *tracing.Probe
//go:linkname neo_traceConnSend_Attach _/home/kirr/src/wendelin/neo/neoppod-t/go/neo.traceConnSend_Attach //go:linkname neo_traceConnSend_Attach _/home/kirr/src/wendelin/neo/neoppod-t/go/neo.traceConnSend_Attach
func neo_traceConnSend_Attach(func(*neo.Conn, neo.Msg)) func neo_traceConnSend_Attach(*tracing.Group, func(*neo.Conn, neo.Msg)) *tracing.Probe
...@@ -69,14 +69,15 @@ func traceConnSend(c *Conn, msg Msg) { ...@@ -69,14 +69,15 @@ func traceConnSend(c *Conn, msg Msg) {
_traceConnSend_runprobev(c, msg) _traceConnSend_runprobev(c, msg)
} }
} }
func _traceConnSend_runprobev(c *Conn, msg Msg) { func _traceConnSend_runprobev(c *Conn, msg Msg) {
for p := _traceConnSend; p != nil; p = (*_t_traceConnSend)(unsafe.Pointer(p.Next())) { for p := _traceConnSend; p != nil; p = (*_t_traceConnSend)(unsafe.Pointer(p.Next())) {
p.probefunc(c, msg) p.probefunc(c, msg)
} }
} }
func traceConnSend_Attach(probe func(*Conn, Msg)) *tracing.Probe { func traceConnSend_Attach(tg *tracing.Group, probe func(*Conn, Msg)) *tracing.Probe {
p := _t_traceConnSend{probefunc: probe} p := _t_traceConnSend{probefunc: probe}
tracing.AttachProbe((**tracing.Probe)(unsafe.Pointer(&_traceConnSend)), &p.Probe) tracing.AttachProbe(tg, (**tracing.Probe)(unsafe.Pointer(&_traceConnSend)), &p.Probe)
return &p.Probe return &p.Probe
} }
...@@ -65,29 +65,44 @@ func verifyLocked() { ...@@ -65,29 +65,44 @@ func verifyLocked() {
} }
} }
// verifyUnlocked makes sure tracing is not locked and panics otherwise
func verifyUnlocked() {
if atomic.LoadInt32(&traceLocked) != 0 {
panic("tracing must be unlocked")
}
}
// Probe describes one probe attached to a tracepoint XXX // Probe describes one probe attached to a tracepoint
type Probe struct { type Probe struct {
prev, next *Probe prev, next *Probe
// probefunc interface{} // func(some arguments)
// implicitly:
// probefunc func(some arguments)
} }
// Next return next probe attached to the same tracepoint // Next return next probe attached to the same tracepoint
// It is safe to iterate Next under any conditions.
func (p *Probe) Next() *Probe { func (p *Probe) Next() *Probe {
return p.next return p.next
} }
// AttachProbe attaches Probe to the end of a probe list // AttachProbe attaches newly created Probe to the end of a probe list
// Must be called under Lock // If group is non-nil the probe is also added to the group.
func AttachProbe(listp **Probe, probe *Probe) { // Must be called under Lock.
// Probe must be newly created.
func AttachProbe(g *Group, listp **Probe, probe *Probe) {
verifyLocked() verifyLocked()
if !(probe.prev == nil || probe.next == nil) {
panic("attach probe: probe is not newly created")
}
var last *Probe var last *Probe
for p := *listp; p != nil; p = p.next { for p := *listp; p != nil; p = p.next {
last = p last = p
} }
// p := &Probe{prev: last, next: nil, probefunc: probefunc}
if last != nil { if last != nil {
last.next = probe last.next = probe
probe.prev = last probe.prev = last
...@@ -95,7 +110,9 @@ func AttachProbe(listp **Probe, probe *Probe) { ...@@ -95,7 +110,9 @@ func AttachProbe(listp **Probe, probe *Probe) {
*listp = probe *listp = probe
} }
// return p if g != nil {
g.Add(probe)
}
} }
// Detach detaches probe from a tracepoint // Detach detaches probe from a tracepoint
...@@ -127,3 +144,28 @@ func (p *Probe) Detach() { ...@@ -127,3 +144,28 @@ func (p *Probe) Detach() {
// time it does not do harm // time it does not do harm
p.prev = p p.prev = p
} }
// Group is a group of probes attached to tracepoints
type Group struct {
probev []*Probe
}
// Add adds a probe to the group
// Must be called under Lock
func (g *Group) Add(p *Probe) {
verifyLocked()
g.probev = append(g.probev)
}
// Done detaches all probes registered in the group
// Must be called under normal conditions, not under Lock
func (g *Group) Done() {
verifyUnlocked()
Lock()
defer Unlock()
for _, p := range g.probev {
p.Detach()
}
g.probev = nil
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment