1. 29 Dec, 2020 2 commits
    • Kirill Smelkov's avatar
      xnet/virtnet: SubNetwork += AutoClose · 3070cec4
      Kirill Smelkov authored
      When a virtnet network - e.g. lonet - is explicitly used in tests, the
      open and close sequence is easy to implement:
      
          network = lonet.Join(...)
          defer network.Close()
      
          hostα = network.NewHost("α")
          defer hostα.Close()
          hostβ = network.NewHost("β")
          defer hostβ.Close()
          ...
      
      However in other scenarios - for example when the code wants to call
      xnet.Networker factory that creates a networker out of several potential
      choices according to given parameters, only interface for network
      access-point (e.g. Host in lonet/virtnet case) is returned. The network
      itself (virtnet.SubNetwork) is not returned to the user. As it is this
      makes it impossible to close the network and release its resources.
      
      Instead of adding complexity to such "create-networker" functions to
      e.g. change Close of returned networker to also close subnetwork, or
      return both networker and a separate close func, let's teach virtnet to
      close SubNetwork automatically when last host of this subnetwork is
      closed. Make it opt-in since this behaviour is not universally wanted.
      
      This way a factory that is asked to connect to network as e.g. a node on
      lonet, could do the following:
      
          func neonet.Join(...) xnet.Networker {
              ...
              // join lonet "<net>" as host "<node>"
              network = lonet.Join("<net>")
              host = network.NewHost("<node>")
              network.AutoClose() // host.Close will close network
              return host
          }
      
      and network will be closed on host.Close() call.
      
      -> Add SubNetwork.AutoClose to schedule Close to be called after last host on the subnetwork is closed.
      -> Mirror this change in virtnet part of lonet.py
      3070cec4
    • Kirill Smelkov's avatar
      xnet: Networker += Close · 01a77bb9
      Kirill Smelkov authored
      Even though there is no need to manually release resources for NetPlain
      and NetTLS, for other networkers - for example lonet - releasing
      resources is needed. In general programs cannot always use lonet
      explicitly, as there might be a factory function that creates a
      Networker according to given parameters.
      
      -> Adjust Networker interface to include general Close.
      -> Adjust NetPlain to follow added "interrupt-on-close" semantic for uniformity.
      01a77bb9
  2. 17 Dec, 2020 3 commits
    • Kirill Smelkov's avatar
      xnet: Provide way to convert xnet.Listener <-> net.Listener · b03d65ff
      Kirill Smelkov authored
      Similarly to what we do in package xio (see 7ad867a3 "xio: Add
      Reader/Writer/... interfaces - io analogs that add support for
      contexts"), add utilities to bind xnet.Listener to context (giving
      net.Listener), and, on the other hand, adapt uncontextified net.Listener
      to xnet.Listener that handles cancellation.
      
      This utilities are needed because a lot of third-party code wants to
      work with net.Listener interface only.
      
      Contrary to xio, we can make it working reliably in both ways (because
      Accept already buffers accepting connections starting at OS level).
      b03d65ff
    • Kirill Smelkov's avatar
      *: Adapt code to xnet.Networker changes for Listen/Accept to handle cancellation · b50ecee2
      Kirill Smelkov authored
      In the previous patch xnet.Networker was changed: Listen now accepts ctx
      and returns xnet.Listener instead of net.Listener.
      
      -> Adapt the code all around to that.
      b50ecee2
    • Kirill Smelkov's avatar
      xnet: Adjust Networker.Listen to return listener that can handle cancellation in Accept · 3354b401
      Kirill Smelkov authored
      We already handle cancellation in Dial, but Accepting was out of luck
      until now. This makes it more difficult for clients to implement and
      wrap acceptors where they need to handle cancellations. This also makes
      it possible for a test or program to get stuck in Accept loop if it is
      not careful enough to manually handle ctx cancel around Accept calls.
      
      -> Fix it in one place - here, in xnet - so that users are offloaded
      from all this and can just call Accept(ctx) and rely on underlying
      implementation to handle ctx cancel.
      
      This patch:
      
      - introduces xnet.Listener interface, which is like net.Listener, but
        Accept goes with ctx argument.
      - changes Networker.Listen signature to return xnet.Listener instead of
        net.Listener. While we are here - changing it - also add ctx argument
        to Listen call itself.
      - Adds listenerCtx - which, given net.Listener, provides xnet.Listener
        by wrapping some logic around original.
      - Adapts NetPlain, NetTLS and NetTrace to provide updated interface.
      
      We'll fix up everything in other packages to match/use updated interface
      in the next patch.
      3354b401
  3. 01 Dec, 2020 1 commit
  4. 18 Oct, 2020 1 commit
  5. 16 Sep, 2020 1 commit
    • Kirill Smelkov's avatar
      exc: Contextf · 31661766
      Kirill Smelkov authored
      A shorthand for when exception context is just formatted string.
      Simplifies
      
      	func doSomething(path string) {
      		defer exc.Context(func() interface{} {
      			return fmt.Sprintf("doing something %s", path)
      		})()
      		...
      
      to
      
      	func doSomething(path string) {
      		defer exc.Contextf("doing something %s", path)
      		...
      31661766
  6. 15 Sep, 2020 1 commit
  7. 27 May, 2020 4 commits
  8. 03 Apr, 2020 1 commit
  9. 16 Jan, 2020 1 commit
  10. 13 Jan, 2020 1 commit
  11. 26 Dec, 2019 6 commits
  12. 20 Dec, 2019 1 commit
    • Kirill Smelkov's avatar
      tracing/runtime: Add support for Go1.14 (preliminary) · 5f6ae15b
      Kirill Smelkov authored
      Generate g for ~ Go 1.14beta1 (go1.14beta1-10-g5c6f42773c)
      Compared to Go1.13 there are several changed to g, _defer and timer
      related to:
      
      - non-cooperative preemption (https://golang.org/issue/10958, https://golang.org/issue/24543);
      - inlined defers (https://golang.org/issue/14939, https://golang.org/issue/34481);
      - timers rework to be integrated with network poller (https://golang.org/issue/6239, https://golang.org/issue/27707):
      
      Regenerated files stay without changes for Go1.13 and previous releases.
      
      ---- 8< ----
      diff --git a/zruntime_g_go1.13.go b/zruntime_g_go1.14.go
      index 76851fd..19cebae 100644
      --- a/zruntime_g_go1.13.go
      +++ b/zruntime_g_go1.14.go
      @@ -1,6 +1,6 @@
       // Code generated by g_typedef; DO NOT EDIT.
      
      -// +build go1.13,!go1.14
      +// +build go1.14,!go1.15
      
       package xruntime
      
      @@ -32,12 +32,25 @@ type g struct {
       	schedlink    guintptr
       	waitsince    int64      // approx time when the g become blocked
       	waitreason   waitReason // if status==Gwaiting
      +
       	preempt       bool // preemption signal, duplicates stackguard0 = stackpreempt
      +	preemptStop   bool // transition to _Gpreempted on preemption; otherwise, just deschedule
      +	preemptShrink bool // shrink stack at synchronous safe point
      +
      +	// asyncSafePoint is set if g is stopped at an asynchronous
      +	// safe point. This means there are frames on the stack
      +	// without precise pointer information.
      +	asyncSafePoint bool
      +
       	paniconfault bool // panic (instead of crash) on unexpected fault address
      -	preemptscan    bool       // preempted g does scan for gc
       	gcscandone   bool // g has scanned stack; protected by _Gscan bit in status
      -	gcscanvalid    bool       // false at start of gc cycle, true if G has not run since last scan; TODO: remove?
       	throwsplit   bool // must not split stack
      +	// activeStackChans indicates that there are unlocked channels
      +	// pointing into this goroutine's stack. If true, stack
      +	// copying needs to acquire channel locks to protect these
      +	// areas of the stack.
      +	activeStackChans bool
      +
       	raceignore     int8     // ignore race detection events
       	sysblocktraced bool     // StartTrace has emitted EvGoInSyscall about this goroutine
       	sysexitticks   int64    // cputicks when syscall has returned (for tracing)
      @@ -76,18 +89,37 @@ type _panic struct {
       	argp      unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
       	arg       interface{}    // argument to panic
       	link      *_panic        // link to earlier panic
      +	pc        uintptr        // where to return to in runtime if this panic is bypassed
      +	sp        unsafe.Pointer // where to return to in runtime if this panic is bypassed
       	recovered bool           // whether this panic is over
       	aborted   bool           // the panic was aborted
      +	goexit    bool
       }
       type _defer struct {
       	siz     int32 // includes both arguments and results
       	started bool
       	heap    bool
      +	// openDefer indicates that this _defer is for a frame with open-coded
      +	// defers. We have only one defer record for the entire frame (which may
      +	// currently have 0, 1, or more defers active).
      +	openDefer bool
       	sp        uintptr  // sp at time of defer
      -	pc      uintptr
      -	fn      *funcval
      +	pc        uintptr  // pc at time of defer
      +	fn        *funcval // can be nil for open-coded defers
       	_panic    *_panic  // panic that is running defer
       	link      *_defer
      +
      +	// If openDefer is true, the fields below record values about the stack
      +	// frame and associated function that has the open-coded defer(s). sp
      +	// above will be the sp for the frame, and pc will be address of the
      +	// deferreturn call in the function.
      +	fd   unsafe.Pointer // funcdata for the function associated with the frame
      +	varp uintptr        // value of varp for the stack frame
      +	// framepc is the current pc associated with the stack frame. Together,
      +	// with sp above (which is the sp associated with the stack frame),
      +	// framepc/sp can be used as pc/sp pair to continue a stack trace via
      +	// gentraceback().
      +	framepc uintptr
       }
       type gobuf struct {
       	// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
      @@ -114,8 +146,10 @@ type funcval struct {
       	fn uintptr
       }
       type timer struct {
      -	tb *timersBucket // the bucket the timer lives in
      -	i  int           // heap index
      +	// If this timer is on a heap, which P's heap it is on.
      +	// puintptr rather than *p to match uintptr in the versions
      +	// of this struct defined in other packages.
      +	pp puintptr
      
       	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
       	// each time calling f(arg, now) in the timer goroutine, so f must be
      @@ -125,6 +159,12 @@ type timer struct {
       	f      func(interface{}, uintptr)
       	arg    interface{}
       	seq    uintptr
      +
      +	// What to set the when field to in timerModifiedXX status.
      +	nextwhen int64
      +
      +	// The status field holds one of the values below.
      +	status uint32
       }
       type guintptr uintptr
       type puintptr uintptr
      5f6ae15b
  13. 28 Jul, 2019 1 commit
  14. 19 May, 2019 2 commits
  15. 16 Apr, 2019 1 commit
    • Kirill Smelkov's avatar
      tracing: call/return overhead related to using trace functions is gone · 79711643
      Kirill Smelkov authored
      As of Go1.12 the check for whether particular trace event is enabled or
      not is inlined into caller. For example:
      
      	---- 8< ---- (connection.go)
      	//trace:event traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg)
      
      	func (link *NodeLink) sendMsg(connId uint32, msg proto.Msg) error {
      		traceMsgSendPre(link, connId, msg)
      
      		buf := msgPack(connId, msg)
      		return link.sendPkt(buf)
      	}
      
      	---- 8< ---- (ztrace.go)
      	// traceevent: traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg)
      
      	type _t_traceMsgSendPre struct {
      	        tracing.Probe
      	        probefunc     func(l *NodeLink, connId uint32, msg proto.Msg)
      	}
      
      	var _traceMsgSendPre *_t_traceMsgSendPre
      
      	func traceMsgSendPre(l *NodeLink, connId uint32, msg proto.Msg) {
      	        if _traceMsgSendPre != nil {
      	                _traceMsgSendPre_run(l, connId, msg)
      	        }
      	}
      
      	func _traceMsgSendPre_run(l *NodeLink, connId uint32, msg proto.Msg) {
      	        for p := _traceMsgSendPre; p != nil; p = (*_t_traceMsgSendPre)(unsafe.Pointer(p.Next())) {
      	                p.probefunc(l, connId, msg)
      	        }
      	}
      
      	---- 8< ---- (connection.o)
      	TEXT lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·(*NodeLink).sendMsg(SB), ABIInternal, $40-48 // connection.go:1368
      	        // MOVQ    (TLS), CX (stack growth prologue)
      	        // CMPQ    SP, 16(CX)
      	        // JLS     177
      	        // SUBQ    $40, SP
      	        // MOVQ    BP, 32(SP) (BP save)
      	        // LEAQ    32(SP), BP (BP init)
      	        // FUNCDATA $0, gclocals·dbae954985b577993f0eafab1347dd21(SB) (args)
      	        FUNCDATA   $1, gclocals·f6bd6b3389b872033d462029172c8612(SB) (locals)
      	        FUNCDATA   $3, gclocals·47f0f3578d0f16ef296c57af2564832c(SB)
      	        PCDATA     $2, $0             // connection.go:1369
      	        PCDATA     $0, $0
      	        XCHGL      AX, AX
      	        CMPQ       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·_traceMsgSendPre(SB), $0	<-- inlined traceMsgSendPre
      	        JNE        pc130              // ztrace.go:50					<--
      	pc44:
      	        MOVL       connId+56(SP), AX  // connection.go:1371				<-- normal path
      	        MOVL       AX, (SP)
      	        MOVQ       msg+64(SP), AX
      	        MOVQ       AX, 8(SP)
      	        PCDATA     $2, $1
      	        PCDATA     $0, $1
      	        MOVQ       msg+72(SP), AX
      	        PCDATA     $2, $0
      	        MOVQ       AX, 16(SP)
      	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·msgPack(SB)
      	        PCDATA     $2, $1
      	        MOVQ       24(SP), AX
      	        PCDATA     $2, $2             // connection.go:1372
      	        PCDATA     $0, $2
      	        MOVQ       link+48(SP), CX
      	        PCDATA     $2, $1
      	        MOVQ       CX, (SP)
      	        PCDATA     $2, $0
      	        MOVQ       AX, 8(SP)
      	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·(*NodeLink).sendPkt(SB)
      	        PCDATA     $2, $1
      	        MOVQ       24(SP), AX
      	        MOVQ       16(SP), CX
      	        PCDATA     $0, $3
      	        MOVQ       CX, _r2+80(SP)
      	        PCDATA     $2, $0
      	        MOVQ       AX, _r2+88(SP)
      	        // MOVQ    32(SP), BP (BP restore)
      	        // ADDQ    $40, SP (SP restore)
      	        RET
      	pc130:											<-- slow path (tracepoint attached)
      	        PCDATA     $2, $1             // ztrace.go:51
      	        PCDATA     $0, $0
      	        MOVQ       link+48(SP), AX
      	        PCDATA     $2, $0
      	        MOVQ       AX, (SP)
      	        MOVL       connId+56(SP), CX
      	        MOVL       CX, 8(SP)
      	        MOVQ       msg+64(SP), DX
      	        MOVQ       DX, 16(SP)
      	        PCDATA     $2, $3
      	        MOVQ       msg+72(SP), BX
      	        PCDATA     $2, $0
      	        MOVQ       BX, 24(SP)
      	        CALL       lab·nexedi·com∕kirr∕neo∕go∕neo∕neonet·_traceMsgSendPre_run(SB)
      	        JMP        pc44
      	        // NOP (stack growth)
      	        // PCDATA  $0, $-1            // connection.go:1368
      	        // PCDATA  $2, $-1
      	        // CALL    runtime.morestack_noctxt(SB)
      	        // JMP     0
      79711643
  16. 12 Apr, 2019 1 commit
  17. 11 Apr, 2019 2 commits
  18. 24 Jan, 2019 1 commit
  19. 17 Jan, 2019 1 commit
  20. 16 Jan, 2019 1 commit
  21. 19 Nov, 2018 1 commit
  22. 06 Jul, 2018 1 commit
  23. 03 Jul, 2018 1 commit
    • Kirill Smelkov's avatar
      tracing/pyruntraced: New tool to run Python code with tracepoints activated (draft) · 7a476082
      Kirill Smelkov authored
      We will hopefully need it in the future to test external python code
      similarly to when testing in-process go code with the help of
      tracepoints. See module description for details (tracetest is not yet
      done).
      
      There is no yet Go client API for interacting with such-traced python
      program. For the record: manually inspecting traced python process could
      be done via e.g.
      
      	socat EXEC:"./pyruntraced 3 neo.trace.py -- ../../../t/backup-play/N1-writer",fdin=3,fdout=3 TCP:localhost:8888
      
      and telnetting to localhost:8888 from another xterm.
      7a476082
  24. 20 Jun, 2018 1 commit
  25. 19 Jun, 2018 3 commits