// 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 := tidExists(subTID)
		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("/tmp"); 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")
}
