Skip to content

Instantly share code, notes, and snippets.

@cheshir
Last active July 23, 2021 14:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cheshir/3486b56f98045946083938c854c5a00e to your computer and use it in GitHub Desktop.
Save cheshir/3486b56f98045946083938c854c5a00e to your computer and use it in GitHub Desktop.
Handmade mutex in go
package main
import (
"sync"
"testing"
)
func BenchmarkLock(b *testing.B) {
var mu Lock
for i := 0; i < b.N; i++ {
mu.Lock()
mu.Unlock()
}
}
func BenchmarkMutex(b *testing.B) {
var mu sync.Mutex
for i := 0; i < b.N; i++ {
mu.Lock()
mu.Unlock()
}
}
func BenchmarkWMutex(b *testing.B) {
var mu sync.RWMutex
for i := 0; i < b.N; i++ {
mu.Lock()
mu.Unlock()
}
}
func BenchmarkRMutex(b *testing.B) {
var mu sync.RWMutex
for i := 0; i < b.N; i++ {
mu.RLock()
mu.RUnlock()
}
}
package main
import (
"runtime"
"sync/atomic"
)
const (
unlocked int32 = iota
locked
)
type Lock struct {
state int32
}
func (l *Lock) Lock() {
for !atomic.CompareAndSwapInt32(&l.state, unlocked, locked) {
runtime.Gosched()
}
}
func (l *Lock) Unlock() {
atomic.StoreInt32(&l.state, unlocked)
}
package main
import (
"testing"
"time"
)
func TestLock(t *testing.T) {
mx := &Lock{}
resource := make(map[int]int)
done := make(chan struct{})
go func() {
for i := 0; i < 10; i++ {
mx.Lock()
resource[i] = i
time.Sleep(time.Millisecond)
mx.Unlock()
}
done <- struct{}{}
}()
for i := 0; i < 10; i++ {
mx.Lock()
_ = resource[i]
time.Sleep(time.Millisecond)
mx.Unlock()
}
<-done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment