Misusing sync.WaitGroup
sync.WaitGroup is a mechanism to wait for n operations to complete.
Mistake
This is a data race, there is no guarantee that another goroutine will be started before the wg.Done() method is called causing the wg.Wait() to stop blocking.
wg := sync.WaitGroup{}
var v uint64
for i := 0; i < 3; i++ {
  go func(){
    wg.Add(1)
    atomic.AddUint64(&v, 1)
    wg.Done() // this is a data race
  }()
}
wg.Wait()
Fix
We can move the wg.Add(1) outside of the goroutine or alternatively we could
call wg.Add(3) outside of the for loop.
wg := sync.WaitGroup{}
var v uint64
for i := 0; i < 3; i++ {
  wg.Add(1)
  go func(){
    atomic.AddUint64(&v, 1)
    wg.Done() // this is a data race
  }()
}
wg.Wait()