// Copyright 2015 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 (
	"fmt"
	"os"
	"runtime"
	"runtime/debug"
	"sync/atomic"
	"time"
)

func init() {
	register("GCFairness", GCFairness)
	register("GCFairness2", GCFairness2)
	register("GCSys", GCSys)
	register("GCPhys", GCPhys)
	register("DeferLiveness", DeferLiveness)
}

func GCSys() {
	runtime.GOMAXPROCS(1)
	memstats := new(runtime.MemStats)
	runtime.GC()
	runtime.ReadMemStats(memstats)
	sys := memstats.Sys

	runtime.MemProfileRate = 0 // disable profiler

	itercount := 100000
	for i := 0; i < itercount; i++ {
		workthegc()
	}

	// Should only be using a few MB.
	// We allocated 100 MB or (if not short) 1 GB.
	runtime.ReadMemStats(memstats)
	if sys > memstats.Sys {
		sys = 0
	} else {
		sys = memstats.Sys - sys
	}
	if sys > 16<<20 {
		fmt.Printf("using too much memory: %d bytes\n", sys)
		return
	}
	fmt.Printf("OK\n")
}

var sink []byte

func workthegc() []byte {
	sink = make([]byte, 1029)
	return sink
}

func GCFairness() {
	runtime.GOMAXPROCS(1)
	f, err := os.Open("/dev/null")
	if os.IsNotExist(err) {
		// This test tests what it is intended to test only if writes are fast.
		// If there is no /dev/null, we just don't execute the test.
		fmt.Println("OK")
		return
	}
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for i := 0; i < 2; i++ {
		go func() {
			for {
				f.Write([]byte("."))
			}
		}()
	}
	time.Sleep(10 * time.Millisecond)
	fmt.Println("OK")
}

func GCFairness2() {
	// Make sure user code can't exploit the GC's high priority
	// scheduling to make scheduling of user code unfair. See
	// issue #15706.
	runtime.GOMAXPROCS(1)
	debug.SetGCPercent(1)
	var count [3]int64
	var sink [3]interface{}
	for i := range count {
		go func(i int) {
			for {
				sink[i] = make([]byte, 1024)
				atomic.AddInt64(&count[i], 1)
			}
		}(i)
	}
	// Note: If the unfairness is really bad, it may not even get
	// past the sleep.
	//
	// If the scheduling rules change, this may not be enough time
	// to let all goroutines run, but for now we cycle through
	// them rapidly.
	//
	// OpenBSD's scheduler makes every usleep() take at least
	// 20ms, so we need a long time to ensure all goroutines have
	// run. If they haven't run after 30ms, give it another 1000ms
	// and check again.
	time.Sleep(30 * time.Millisecond)
	var fail bool
	for i := range count {
		if atomic.LoadInt64(&count[i]) == 0 {
			fail = true
		}
	}
	if fail {
		time.Sleep(1 * time.Second)
		for i := range count {
			if atomic.LoadInt64(&count[i]) == 0 {
				fmt.Printf("goroutine %d did not run\n", i)
				return
			}
		}
	}
	fmt.Println("OK")
}

var maybeSaved []byte

func GCPhys() {
	// In this test, we construct a very specific scenario. We first
	// allocate N objects and drop half of their pointers on the floor,
	// effectively creating N/2 'holes' in our allocated arenas. We then
	// try to allocate objects twice as big. At the end, we measure the
	// physical memory overhead of large objects.
	//
	// The purpose of this test is to ensure that the GC scavenges free
	// spans eagerly to ensure high physical memory utilization even
	// during fragmentation.
	const (
		// Unfortunately, measuring actual used physical pages is
		// difficult because HeapReleased doesn't include the parts
		// of an arena that haven't yet been touched. So, we just
		// make objects and size sufficiently large such that even
		// 64 MB overhead is relatively small in the final
		// calculation.
		//
		// Currently, we target 480MiB worth of memory for our test,
		// computed as size * objects + (size*2) * (objects/2)
		// = 2 * size * objects
		//
		// Size must be also large enough to be considered a large
		// object (not in any size-segregated span).
		size    = 1 << 20
		objects = 240
	)
	// Save objects which we want to survive, and condemn objects which we don't.
	// Note that we condemn objects in this way and release them all at once in
	// order to avoid having the GC start freeing up these objects while the loop
	// is still running and filling in the holes we intend to make.
	saved := make([][]byte, 0, objects)
	condemned := make([][]byte, 0, objects/2+1)
	for i := 0; i < objects; i++ {
		// Write into a global, to prevent this from being optimized away by
		// the compiler in the future.
		maybeSaved = make([]byte, size)
		if i%2 == 0 {
			saved = append(saved, maybeSaved)
		} else {
			condemned = append(condemned, maybeSaved)
		}
	}
	condemned = nil
	// Clean up the heap. This will free up every other object created above
	// (i.e. everything in condemned) creating holes in the heap.
	runtime.GC()
	// Allocate many new objects of 2x size.
	for i := 0; i < objects/2; i++ {
		saved = append(saved, make([]byte, size*2))
	}
	// Clean up the heap again just to put it in a known state.
	runtime.GC()
	// heapBacked is an estimate of the amount of physical memory used by
	// this test. HeapSys is an estimate of the size of the mapped virtual
	// address space (which may or may not be backed by physical pages)
	// whereas HeapReleased is an estimate of the amount of bytes returned
	// to the OS. Their difference then roughly corresponds to the amount
	// of virtual address space that is backed by physical pages.
	var stats runtime.MemStats
	runtime.ReadMemStats(&stats)
	heapBacked := stats.HeapSys - stats.HeapReleased
	// If heapBacked exceeds the amount of memory actually used for heap
	// allocated objects by 10% (post-GC HeapAlloc should be quite close to
	// the size of the working set), then fail.
	//
	// In the context of this test, that indicates a large amount of
	// fragmentation with physical pages that are otherwise unused but not
	// returned to the OS.
	overuse := (float64(heapBacked) - float64(stats.HeapAlloc)) / float64(stats.HeapAlloc)
	if overuse > 0.1 {
		fmt.Printf("exceeded physical memory overuse threshold of 10%%: %3.2f%%\n"+
			"(alloc: %d, sys: %d, rel: %d, objs: %d)\n", overuse*100, stats.HeapAlloc,
			stats.HeapSys, stats.HeapReleased, len(saved))
		return
	}
	fmt.Println("OK")
	runtime.KeepAlive(saved)
}

// Test that defer closure is correctly scanned when the stack is scanned.
func DeferLiveness() {
	var x [10]int
	escape(&x)
	fn := func() {
		if x[0] != 42 {
			panic("FAIL")
		}
	}
	defer fn()

	x[0] = 42
	runtime.GC()
	runtime.GC()
	runtime.GC()
}

//go:noinline
func escape(x interface{}) { sink2 = x; sink2 = nil }

var sink2 interface{}
