// Copyright 2020 The gVisor Authors.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build checklocks

package sync

import (
	"fmt"
	"strings"
	"sync"
	"unsafe"

	"gvisor.dev/gvisor/pkg/goid"
)

// gLocks contains metadata about the locks held by a goroutine.
type gLocks struct {
	locksHeld []unsafe.Pointer
}

// map[goid int]*gLocks
//
// Each key may only be written by the G with the goid it refers to.
//
// Note that entries are not evicted when a G exit, causing unbounded growth
// with new G creation / destruction. If this proves problematic, entries could
// be evicted when no locks are held at the expense of more allocations when
// taking top-level locks.
var locksHeld sync.Map

func getGLocks() *gLocks {
	id := goid.Get()

	var locks *gLocks
	if l, ok := locksHeld.Load(id); ok {
		locks = l.(*gLocks)
	} else {
		locks = &gLocks{
			// Initialize space for a few locks.
			locksHeld: make([]unsafe.Pointer, 0, 8),
		}
		locksHeld.Store(id, locks)
	}

	return locks
}

func noteLock(l unsafe.Pointer) {
	locks := getGLocks()

	for _, lock := range locks.locksHeld {
		if lock == l {
			panic(fmt.Sprintf("Deadlock on goroutine %d! Double lock of %p: %+v", goid.Get(), l, locks))
		}
	}

	// Commit only after checking for panic conditions so that this lock
	// isn't on the list if the above panic is recovered.
	locks.locksHeld = append(locks.locksHeld, l)
}

func noteUnlock(l unsafe.Pointer) {
	locks := getGLocks()

	if len(locks.locksHeld) == 0 {
		panic(fmt.Sprintf("Unlock of %p on goroutine %d without any locks held! All locks:\n%s", l, goid.Get(), dumpLocks()))
	}

	// Search backwards since callers are most likely to unlock in LIFO order.
	length := len(locks.locksHeld)
	for i := length - 1; i >= 0; i-- {
		if l == locks.locksHeld[i] {
			copy(locks.locksHeld[i:length-1], locks.locksHeld[i+1:length])
			// Clear last entry to ensure addr can be GC'd.
			locks.locksHeld[length-1] = nil
			locks.locksHeld = locks.locksHeld[:length-1]
			return
		}
	}

	panic(fmt.Sprintf("Unlock of %p on goroutine %d without matching lock! All locks:\n%s", l, goid.Get(), dumpLocks()))
}

func dumpLocks() string {
	var s strings.Builder
	locksHeld.Range(func(key, value interface{}) bool {
		goid := key.(int64)
		locks := value.(*gLocks)

		// N.B. accessing gLocks of another G is fundamentally racy.

		fmt.Fprintf(&s, "goroutine %d:\n", goid)
		if len(locks.locksHeld) == 0 {
			fmt.Fprintf(&s, "\t<none>\n")
		}
		for _, lock := range locks.locksHeld {
			fmt.Fprintf(&s, "\t%p\n", lock)
		}
		fmt.Fprintf(&s, "\n")

		return true
	})

	return s.String()
}
