diff --git a/sysutil/sysutil.go b/sysutil/sysutil.go new file mode 100644 index 0000000..f17bae1 --- /dev/null +++ b/sysutil/sysutil.go @@ -0,0 +1,23 @@ +package sysutil + +import ( + "runtime/debug" +) + +// SetMaxThreads sets the maximum number of operating system +// threads that the Go program can use. If it attempts to use more than +// this many, the program crashes. +// SetMaxThreads returns the previous setting. +// The initial setting is 10,000 threads. +// +// The limit controls the number of operating system threads, not the number +// of goroutines. A Go program creates a new thread only when a goroutine +// is ready to run but all the existing threads are blocked in system calls, cgo calls, +// or are locked to other goroutines due to use of runtime.LockOSThread. +// +// SetMaxThreads is useful mainly for limiting the damage done by +// programs that create an unbounded number of threads. The idea is +// to take down the program before it takes down the operating system. +func SetMaxThreads(threads int) int { + return debug.SetMaxThreads(threads) +} diff --git a/sysutil/sysutil_test.go b/sysutil/sysutil_test.go new file mode 100644 index 0000000..994a9ec --- /dev/null +++ b/sysutil/sysutil_test.go @@ -0,0 +1,20 @@ +package sysutil + +import ( + "runtime/debug" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSetMaxThreads(t *testing.T) { + originalMaxThreads := debug.SetMaxThreads(10000) + defer debug.SetMaxThreads(originalMaxThreads) + + newMaxThreads := 5000 + previousMaxThreads := SetMaxThreads(newMaxThreads) + require.Equal(t, 10000, previousMaxThreads, "Expected previous max threads to be 10000") + require.Equal(t, newMaxThreads, debug.SetMaxThreads(newMaxThreads), "Expected max threads to be set to 5000") + + SetMaxThreads(originalMaxThreads) +}