github.com/haraldrudell/parl@v0.4.176/g0/thread-data.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package g0 7 8 import ( 9 "strings" 10 11 "github.com/haraldrudell/parl" 12 "github.com/haraldrudell/parl/pruntime" 13 ) 14 15 const ( 16 ThreadDataEmpty = "[empty]" 17 ThreadDataNil = "threadData:nil" 18 ) 19 20 // ThreadData contains identifiable information about a running thread. 21 // - ThreadData does not have initialization 22 type ThreadData struct { 23 // threadID is the ID of the running thread 24 // - a small integer with 1 for main thread, displayed by debug.Stack 25 threadID parl.ThreadID 26 // createLocation is the code line of the go-statement function-call 27 // invocation launching the thread 28 createLocation pruntime.CodeLocation 29 // funcLocation is the code line of the function of the running thread. 30 funcLocation pruntime.CodeLocation 31 // optional thread-name assigned by consumer 32 label string 33 } 34 35 var _ parl.ThreadData = &ThreadData{} 36 37 // Update populates this object from a stack trace. 38 func (t *ThreadData) Update( 39 threadID parl.ThreadID, 40 createInvocation, goFunction *pruntime.CodeLocation, 41 label string) { 42 if !t.threadID.IsValid() && threadID.IsValid() { 43 t.threadID = threadID 44 } 45 if createInvocation != nil && !t.createLocation.IsSet() && createInvocation.IsSet() { 46 t.createLocation = *createInvocation 47 } 48 if goFunction != nil && !t.funcLocation.IsSet() && goFunction.IsSet() { 49 t.funcLocation = *goFunction 50 } 51 if t.label == "" && label != "" { 52 t.label = label 53 } 54 } 55 56 // SetCreator gets preliminary Go identifier: the line invoking Go() 57 func (t *ThreadData) SetCreator(cl *pruntime.CodeLocation) { 58 t.createLocation = *cl 59 } 60 61 // threadID is the ID of the running thread 62 func (t *ThreadData) ThreadID() (threadID parl.ThreadID) { 63 return t.threadID 64 } 65 66 func (t *ThreadData) Create() (createLocation *pruntime.CodeLocation) { 67 return &t.createLocation 68 } 69 70 func (t *ThreadData) Func() (funcLocation *pruntime.CodeLocation) { 71 return &t.funcLocation 72 } 73 74 func (t *ThreadData) Name() (label string) { 75 return t.label 76 } 77 78 func (t *ThreadData) Get() (threadID parl.ThreadID, createLocation pruntime.CodeLocation, 79 funcLocation pruntime.CodeLocation, label string) { 80 threadID = t.threadID 81 createLocation = t.createLocation 82 funcLocation = t.funcLocation 83 label = t.label 84 return 85 } 86 87 // "myThreadName:4" 88 func (t *ThreadData) Short() (s string) { 89 90 // handle nil case 91 if t == nil { 92 return ThreadDataNil // "threadData:nil" 93 } 94 95 // "[label]:[threadID]" 96 if t.label != "" { 97 s = t.label 98 } 99 if t.threadID.IsValid() { 100 if s != "" { 101 s += ":" + t.threadID.String() 102 } else { 103 s = t.threadID.String() 104 } 105 } 106 if s != "" { 107 return 108 } 109 110 // zero-value case 111 return t.String() 112 } 113 114 func (t *ThreadData) LabeledString() (s string) { 115 var sL []string 116 if t.label != "" { 117 sL = append(sL, "label: "+t.label) 118 } 119 if t.threadID.IsValid() { 120 sL = append(sL, "threadID: "+t.threadID.String()) 121 } 122 if t.funcLocation.IsSet() { 123 sL = append(sL, "go-function: "+t.funcLocation.Short()) 124 } 125 if t.createLocation.IsSet() { 126 sL = append(sL, "go-statement: "+t.createLocation.Short()) 127 } 128 if len(sL) > 0 { 129 s = strings.Join(sL, "\x20") 130 } else { 131 s = "[no data]" 132 } 133 return 134 } 135 136 // "myThreadName:4_func:testing.tRunner()-testing.go:1446_cre:testing.(*T).Run()-testing.go:1493" 137 func (t *ThreadData) String() (s string) { 138 var sList []string 139 var s1 string 140 if t.label != "" { 141 s1 = t.label 142 } 143 if t.threadID.IsValid() { 144 if s1 != "" { 145 s1 += ":" + t.threadID.String() 146 } else { 147 s1 = t.threadID.String() 148 } 149 } 150 if s1 != "" { 151 sList = append(sList, s1) 152 } 153 if t.funcLocation.IsSet() { 154 sList = append(sList, "func:"+t.funcLocation.Short()) 155 } 156 if t.createLocation.IsSet() { 157 sList = append(sList, "cre:"+t.createLocation.Short()) 158 } 159 if s = strings.Join(sList, "_"); s == "" { 160 s = ThreadDataEmpty 161 } 162 return 163 }