// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"os"
	"runtime"
	"sync"
	"time"
)

var mainTID int

func init() {
	registerInit("LockOSThreadMain", func() {
		// init is guaranteed to run on the main thread.
		mainTID = gettid()
	})
	register("LockOSThreadMain", LockOSThreadMain)

	registerInit("LockOSThreadAlt", func() {
		// Lock the OS thread now so main runs on the main thread.
		runtime.LockOSThread()
	})
	register("LockOSThreadAlt", LockOSThreadAlt)

	registerInit("LockOSThreadAvoidsStatePropagation", func() {
		// Lock the OS thread now so main runs on the main thread.
		runtime.LockOSThread()
	})
	register("LockOSThreadAvoidsStatePropagation", LockOSThreadAvoidsStatePropagation)
	register("LockOSThreadTemplateThreadRace", LockOSThreadTemplateThreadRace)
}

func LockOSThreadMain() {
	// gettid only works on Linux, so on other platforms this just
	// checks that the runtime doesn't do anything terrible.

	// This requires GOMAXPROCS=1 from the beginning to reliably
	// start a goroutine on the main thread.
	if runtime.GOMAXPROCS(-1) != 1 {
		println("requires GOMAXPROCS=1")
		os.Exit(1)
	}

	ready := make(chan bool, 1)
	go func() {
		// Because GOMAXPROCS=1, this *should* be on the main
		// thread. Stay there.
		runtime.LockOSThread()
		if mainTID != 0 && gettid() != mainTID {
			println("failed to start goroutine on main thread")
			os.Exit(1)
		}
		// Exit with the thread locked, which should exit the
		// main thread.
		ready <- true
	}()
	<-ready
	time.Sleep(1 * time.Millisecond)
	// Check that this goroutine is still running on a different
	// thread.
	if mainTID != 0 && gettid() == mainTID {
		println("goroutine migrated to locked thread")
		os.Exit(1)
	}
	println("OK")
}

func LockOSThreadAlt() {
	// This is running locked to the main OS thread.

	var subTID int
	ready := make(chan bool, 1)
	go func() {
		// This goroutine must be running on a new thread.
		runtime.LockOSThread()
		subTID = gettid()
		ready <- true
		// Exit with the thread locked.
	}()
	<-ready
	runtime.UnlockOSThread()
	for i := 0; i < 100; i++ {
		time.Sleep(1 * time.Millisecond)
		// Check that this goroutine is running on a different thread.
		if subTID != 0 && gettid() == subTID {
			println("locked thread reused")
			os.Exit(1)
		}
		exists, supported, err := tidExists(subTID)
		if err != nil {
			println("error:", err.Error())
			return
		}
		if !supported || !exists {
			goto ok
		}
	}
	println("sub thread", subTID, "still running")
	return
ok:
	println("OK")
}

func LockOSThreadAvoidsStatePropagation() {
	// This test is similar to LockOSThreadAlt in that it will detect if a thread
	// which should have died is still running. However, rather than do this with
	// thread IDs, it does this by unsharing state on that thread. This way, it
	// also detects whether new threads were cloned from the dead thread, and not
	// from a clean thread. Cloning from a locked thread is undesirable since
	// cloned threads will inherit potentially unwanted OS state.
	//
	// unshareFs, getcwd, and chdir("/tmp") are only guaranteed to work on
	// Linux, so on other platforms this just checks that the runtime doesn't
	// do anything terrible.
	//
	// This is running locked to the main OS thread.

	// GOMAXPROCS=1 makes this fail much more reliably if a tainted thread is
	// cloned from.
	if runtime.GOMAXPROCS(-1) != 1 {
		println("requires GOMAXPROCS=1")
		os.Exit(1)
	}

	if err := chdir("/"); err != nil {
		println("failed to chdir:", err.Error())
		os.Exit(1)
	}
	// On systems other than Linux, cwd == "".
	cwd, err := getcwd()
	if err != nil {
		println("failed to get cwd:", err.Error())
		os.Exit(1)
	}
	if cwd != "" && cwd != "/" {
		println("unexpected cwd", cwd, " wanted /")
		os.Exit(1)
	}

	ready := make(chan bool, 1)
	go func() {
		// This goroutine must be running on a new thread.
		runtime.LockOSThread()

		// Unshare details about the FS, like the CWD, with
		// the rest of the process on this thread.
		// On systems other than Linux, this is a no-op.
		if err := unshareFs(); err != nil {
			if err == errNotPermitted {
				println("unshare not permitted")
				os.Exit(0)
			}
			println("failed to unshare fs:", err.Error())
			os.Exit(1)
		}
		// Chdir to somewhere else on this thread.
		// On systems other than Linux, this is a no-op.
		if err := chdir(os.TempDir()); err != nil {
			println("failed to chdir:", err.Error())
			os.Exit(1)
		}

		// The state on this thread is now considered "tainted", but it
		// should no longer be observable in any other context.

		ready <- true
		// Exit with the thread locked.
	}()
	<-ready

	// Spawn yet another goroutine and lock it. Since GOMAXPROCS=1, if
	// for some reason state from the (hopefully dead) locked thread above
	// propagated into a newly created thread (via clone), or that thread
	// is actually being re-used, then we should get scheduled on such a
	// thread with high likelihood.
	done := make(chan bool)
	go func() {
		runtime.LockOSThread()

		// Get the CWD and check if this is the same as the main thread's
		// CWD. Every thread should share the same CWD.
		// On systems other than Linux, wd == "".
		wd, err := getcwd()
		if err != nil {
			println("failed to get cwd:", err.Error())
			os.Exit(1)
		}
		if wd != cwd {
			println("bad state from old thread propagated after it should have died")
			os.Exit(1)
		}
		<-done

		runtime.UnlockOSThread()
	}()
	done <- true
	runtime.UnlockOSThread()
	println("OK")
}

func LockOSThreadTemplateThreadRace() {
	// This test attempts to reproduce the race described in
	// golang.org/issue/38931. To do so, we must have a stop-the-world
	// (achieved via ReadMemStats) racing with two LockOSThread calls.
	//
	// While this test attempts to line up the timing, it is only expected
	// to fail (and thus hang) around 2% of the time if the race is
	// present.

	// Ensure enough Ps to actually run everything in parallel. Though on
	// <4 core machines, we are still at the whim of the kernel scheduler.
	runtime.GOMAXPROCS(4)

	go func() {
		// Stop the world; race with LockOSThread below.
		var m runtime.MemStats
		for {
			runtime.ReadMemStats(&m)
		}
	}()

	// Try to synchronize both LockOSThreads.
	start := time.Now().Add(10 * time.Millisecond)

	var wg sync.WaitGroup
	wg.Add(2)

	for i := 0; i < 2; i++ {
		go func() {
			for time.Now().Before(start) {
			}

			// Add work to the local runq to trigger early startm
			// in handoffp.
			go func() {}()

			runtime.LockOSThread()
			runtime.Gosched() // add a preemption point.
			wg.Done()
		}()
	}

	wg.Wait()
	// If both LockOSThreads completed then we did not hit the race.
	println("OK")
}
