Skip to content

Instantly share code, notes, and snippets.

@donovanhide
Last active November 5, 2022 02:14
Show Gist options
  • Save donovanhide/4656676 to your computer and use it in GitHub Desktop.
Save donovanhide/4656676 to your computer and use it in GitHub Desktop.
// func GetCpuForThread() uint64
TEXT ·GetCpuForThread(SB),7,$0
MOVQ $0xB,AX
XORQ CX,CX
CPUID
MOVQ DX,ret+0(FP)
RET
package mutex
import (
"bytes"
"fmt"
"sync"
)
func GetCpuForThread() uint64
type InstrumentedMutex struct {
sync.Mutex
counts map[uint64]int
}
func (m *InstrumentedMutex) Lock() {
m.Mutex.Lock()
if m.counts == nil {
m.counts = make(map[uint64]int)
}
m.counts[GetCpuForThread()]++
}
func (m *InstrumentedMutex) UnLock() {
if m.counts == nil {
m.counts = make(map[uint64]int)
}
m.counts[GetCpuForThread()]++
m.Mutex.Unlock()
}
func (m *InstrumentedMutex) String() string {
var buf bytes.Buffer
for k, v := range m.counts {
buf.WriteString(fmt.Sprintf("%2d: %d", k, v))
}
return buf.String()
}
package mutex
import (
"runtime"
"sync"
"testing"
)
type counter struct {
InstrumentedMutex
count int
}
func (c *counter) Increment() {
c.InstrumentedMutex.Lock()
c.count++
c.InstrumentedMutex.Unlock()
}
func work(c *counter, wg *sync.WaitGroup) {
for i := 0; i < 100; i++ {
c.Increment()
}
wg.Done()
}
func Test_Counter(t *testing.T) {
runtime.GOMAXPROCS(runtime.NumCPU())
var wg sync.WaitGroup
var c counter
for i := 0; i < 50; i++ {
wg.Add(1)
go work(&c, &wg)
}
wg.Wait()
t.Log(c.String())
}
$ go test -v
=== RUN Test_Counter
--- PASS: Test_Counter (0.00 seconds)
mutex_test.go:36: 0: 764 7: 194 3: 544 6: 821 2: 703 5: 494 1: 705 4: 775
PASS
ok _/Users/donovanhide/Desktop/4656676 0.024s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment