Commit 1353f54a authored by Kirill Smelkov's avatar Kirill Smelkov

X tracing: Review a bit

parent 8dbd955e
...@@ -129,12 +129,12 @@ func TestMasterStorage(t *testing.T) { ...@@ -129,12 +129,12 @@ func TestMasterStorage(t *testing.T) {
net := pipenet.New("testnet") // test network net := pipenet.New("testnet") // test network
tg := &tracing.Group{} pg := &tracing.ProbeGroup{}
defer tg.Done() defer pg.Done()
tracing.Lock() tracing.Lock()
neo_traceConnRecv_Attach(tg, tracer.traceNeoConnRecv) neo_traceConnRecv_Attach(pg, tracer.traceNeoConnRecv)
neo_traceConnSend_Attach(tg, tracer.traceNeoConnSend) neo_traceConnSend_Attach(pg, tracer.traceNeoConnSend)
tracing.Unlock() tracing.Unlock()
......
// Copyright (C) 2016-2017 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Open Source Initiative approved licenses and Convey
// the resulting work. Corresponding source of such a combination shall include
// the source code for all other software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
package tracing
// stop-the-world that should probably be in xruntime, but I'm (yet) hesitating
// to expose the API to public.
import _ "unsafe"
//go:linkname runtime_stopTheWorld runtime.stopTheWorld
//go:linkname runtime_startTheWorld runtime.startTheWorld
// runtime_stopTheWorld returns with the world stopped
// Current goroutine remains the only one who is running, with others
// goroutines stopped at safe GC points.
// It requires careful programming as many things that normally work lead to
// fatal errors when the world is stoppped - for example using timers would be
// invalid, but adjusting plain values in memory is ok.
func runtime_stopTheWorld(reason string)
// StartTheWorld restarts the world after it was stopped by runtime_stopTheWorld
func runtime_startTheWorld()
package tracing
// TODO tests for stop/start the world.
...@@ -16,24 +16,19 @@ ...@@ -16,24 +16,19 @@
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// Package tracing provides runtime support for Go tracing facilities // Package tracing provides runtime support for Go tracing facilities
// XXX ^^^ += "and usage" ?
// TODO describe how to define tracepoints // TODO describe how to define tracepoints
// TODO doc:
// - tracepoints
// - probes
// - probes can be attached/detached to/from tracepoints
package tracing package tracing
import ( import (
"sync" "sync"
"sync/atomic" "sync/atomic"
_ "unsafe"
) )
// XXX move StopTheWorld to xruntime ?
//go:linkname runtime_stopTheWorld runtime.stopTheWorld
func runtime_stopTheWorld(string)
//go:linkname runtime_startTheWorld runtime.startTheWorld
func runtime_startTheWorld()
// big tracing lock // big tracing lock
var traceMu sync.Mutex var traceMu sync.Mutex
var traceLocked int32 // for cheap protective checks whether Lock is held var traceLocked int32 // for cheap protective checks whether Lock is held
...@@ -81,7 +76,7 @@ type Probe struct { ...@@ -81,7 +76,7 @@ type Probe struct {
// probefunc func(some arguments) // probefunc func(some arguments)
} }
// Next return next probe attached to the same tracepoint // Next returns next probe attached to the same tracepoint
// It is safe to iterate Next under any conditions. // 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
...@@ -91,7 +86,7 @@ func (p *Probe) Next() *Probe { ...@@ -91,7 +86,7 @@ func (p *Probe) Next() *Probe {
// If group is non-nil the probe is also added to the group. // If group is non-nil the probe is also added to the group.
// Must be called under Lock. // Must be called under Lock.
// Probe must be newly created. // Probe must be newly created.
func AttachProbe(g *Group, listp **Probe, probe *Probe) { func AttachProbe(pg *ProbeGroup, listp **Probe, probe *Probe) {
verifyLocked() verifyLocked()
if !(probe.prev == nil || probe.next == nil) { if !(probe.prev == nil || probe.next == nil) {
...@@ -110,8 +105,8 @@ func AttachProbe(g *Group, listp **Probe, probe *Probe) { ...@@ -110,8 +105,8 @@ func AttachProbe(g *Group, listp **Probe, probe *Probe) {
*listp = probe *listp = probe
} }
if g != nil { if pg != nil {
g.Add(probe) pg.Add(probe)
} }
} }
...@@ -145,27 +140,27 @@ func (p *Probe) Detach() { ...@@ -145,27 +140,27 @@ func (p *Probe) Detach() {
p.prev = p p.prev = p
} }
// Group is a group of probes attached to tracepoints // ProbeGroup is a group of probes attached to tracepoints
type Group struct { type ProbeGroup struct {
probev []*Probe probev []*Probe
} }
// Add adds a probe to the group // Add adds a probe to the group
// Must be called under Lock // Must be called under Lock
func (g *Group) Add(p *Probe) { func (pg *ProbeGroup) Add(p *Probe) {
verifyLocked() verifyLocked()
g.probev = append(g.probev) pg.probev = append(pg.probev, p)
} }
// Done detaches all probes registered in the group // Done detaches all probes registered in the group
// Must be called under normal conditions, not under Lock // Must be called under normal conditions, not under Lock
func (g *Group) Done() { func (pg *ProbeGroup) Done() {
verifyUnlocked() verifyUnlocked()
Lock() Lock()
defer Unlock() defer Unlock()
for _, p := range g.probev { for _, p := range pg.probev {
p.Detach() p.Detach()
} }
g.probev = nil pg.probev = nil
} }
// empty .s so `go build` does not use -complete // empty .s so `go build` does not use -complete for go:linkname to work
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