1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // A Goroutine represents a goroutine in a remote process.
15 type Goroutine
struct {
21 func (t
*Goroutine
) String() string {
23 return "<dead thread>"
25 // TODO(austin) Give threads friendly ID's, possibly including
26 // the name of the entry function.
27 return fmt
.Sprintf("thread %#x", t
.g
.addr().base
)
30 // isG0 returns true if this thread if the internal idle thread
31 func (t
*Goroutine
) isG0() bool { return t
.g
.addr().base
== t
.g
.r
.p
.sys
.g0
.addr().base
}
33 func (t
*Goroutine
) resetFrame() (err os
.Error
) {
34 // TODO(austin) Reuse any live part of the current frame stack
35 // so existing references to Frame's keep working.
36 t
.frame
, err
= newFrame(t
.g
)
40 // Out selects the caller frame of the current frame.
41 func (t
*Goroutine
) Out() os
.Error
{
42 f
, err
:= t
.frame
.Outer()
49 // In selects the frame called by the current frame.
50 func (t
*Goroutine
) In() os
.Error
{
58 func readylockedBP(ev Event
) (EventAction
, os
.Error
) {
62 // The new g is the only argument to this function, so the
63 // stack will have the return address, then the G*.
64 regs
, err
:= b
.osThread
.Regs()
69 addr
:= sp
+ proc
.Word(p
.PtrSize())
70 arg
:= remotePtr
{remote
{addr
, p
}, p
.runtime
.G
}
72 err
= try(func(a aborter
) { gp
= arg
.aGet(a
) })
77 return EAStop
, UnknownGoroutine
{b
.osThread
, 0}
79 gs
:= gp
.(remoteStruct
)
80 g
:= &Goroutine
{gs
, nil, false}
81 p
.goroutines
[gs
.addr().base
] = g
83 // Enqueue goroutine creation event
84 parent
:= b
.Goroutine()
88 p
.postEvent(&GoroutineCreate
{commonEvent
{p
, g
}, parent
})
90 // If we don't have any thread selected, select this one
91 if p
.curGoroutine
== nil {
98 func goexitBP(ev Event
) (EventAction
, os
.Error
) {
105 addr
:= g
.g
.addr().base
106 p
.goroutines
[addr
] = nil, false
108 // Enqueue thread exit event
109 p
.postEvent(&GoroutineExit
{commonEvent
{p
, g
}})
111 // If we just exited our selected goroutine, selected another
112 if p
.curGoroutine
== g
{
113 p
.selectSomeGoroutine()
116 return EADefault
, nil