1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import "C"
8import (
9	"internal/syscall/windows"
10	"runtime"
11	"sync"
12	"syscall"
13	"unsafe"
14)
15
16func init() {
17	register("StackMemory", StackMemory)
18}
19
20func getPagefileUsage() (uintptr, error) {
21	p, err := syscall.GetCurrentProcess()
22	if err != nil {
23		return 0, err
24	}
25	var m windows.PROCESS_MEMORY_COUNTERS
26	err = windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
27	if err != nil {
28		return 0, err
29	}
30	return m.PagefileUsage, nil
31}
32
33func StackMemory() {
34	mem1, err := getPagefileUsage()
35	if err != nil {
36		panic(err)
37	}
38	const threadCount = 100
39	var wg sync.WaitGroup
40	for i := 0; i < threadCount; i++ {
41		wg.Add(1)
42		go func() {
43			runtime.LockOSThread()
44			wg.Done()
45			select {}
46		}()
47	}
48	wg.Wait()
49	mem2, err := getPagefileUsage()
50	if err != nil {
51		panic(err)
52	}
53	// assumes that this process creates 1 thread for each
54	// thread locked goroutine plus extra 10 threads
55	// like sysmon and others
56	print((mem2 - mem1) / (threadCount + 10))
57}
58