From 665feeedcbef8a1c968d6da5be052e9fd9678380 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 16 Aug 2013 22:25:26 -0400 Subject: runtime: impose thread count limit Actually working to stay within the limit could cause subtle deadlocks. Crashing avoids the subtlety. Fixes #4056. R=golang-dev, r, dvyukov CC=golang-dev https://golang.org/cl/13037043 --- src/pkg/runtime/proc.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/pkg/runtime/proc.c') diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 6950f4b179..dab62ad69b 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -32,6 +32,7 @@ struct Sched { int32 nmidle; // number of idle m's waiting for work int32 nmidlelocked; // number of locked m's waiting for work int32 mcount; // number of m's that have been created + int32 maxmcount; // maximum number of m's allowed (or die) P* pidle; // idle P's uint32 npidle; @@ -126,6 +127,8 @@ runtime·schedinit(void) int32 n, procs; byte *p; + runtime·sched.maxmcount = 10000; + m->nomemprof++; runtime·mprofinit(); runtime·mallocinit(); @@ -283,6 +286,16 @@ runtime·tracebackothers(G *me) } } +static void +checkmcount(void) +{ + // sched lock is held + if(runtime·sched.mcount > runtime·sched.maxmcount) { + runtime·printf("runtime: program exceeds %d-thread limit\n", runtime·sched.maxmcount); + runtime·throw("thread exhaustion"); + } +} + static void mcommoninit(M *mp) { @@ -295,7 +308,7 @@ mcommoninit(M *mp) runtime·lock(&runtime·sched); mp->id = runtime·sched.mcount++; - + checkmcount(); runtime·mpreinit(mp); // Add to runtime·allm so garbage collector doesn't free m @@ -2821,3 +2834,14 @@ runtime·topofstack(Func *f) f->entry == (uintptr)runtime·lessstack || f->entry == (uintptr)_rt0_go; } + +void +runtime∕debug·setMaxThreads(intgo in, intgo out) +{ + runtime·lock(&runtime·sched); + out = runtime·sched.maxmcount; + runtime·sched.maxmcount = in; + checkmcount(); + runtime·unlock(&runtime·sched); + FLUSH(&out); +} -- cgit v1.3