aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/proc.c')
-rw-r--r--src/pkg/runtime/proc.c26
1 files changed, 25 insertions, 1 deletions
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();
@@ -284,6 +287,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)
{
// If there is no mcache runtime·callers() will crash,
@@ -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);
+}