runtime: start goroutine ids at 1

LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews, khr
https://golang.org/cl/117810043
diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go
index 8552d2f..c61fa16 100644
--- a/src/pkg/runtime/crash_test.go
+++ b/src/pkg/runtime/crash_test.go
@@ -167,6 +167,14 @@
 	}
 }
 
+func TestMainGoroutineId(t *testing.T) {
+	output := executeTest(t, mainGoroutineIdSource, nil)
+	want := "panic: test\n\ngoroutine 1 [running]:\n"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
 const crashSource = `
 package main
 
@@ -365,3 +373,10 @@
 	select{}
 }
 `
+
+const mainGoroutineIdSource = `
+package main
+func main() {
+	panic("test")
+}
+`
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 22ddce5..0b75415 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -1882,7 +1882,11 @@
 	newg->gopc = (uintptr)callerpc;
 	newg->status = Grunnable;
 	if(p->goidcache == p->goidcacheend) {
+		// Sched.goidgen is the last allocated id,
+		// this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch].
+		// At startup sched.goidgen=0, so main goroutine receives goid=1.
 		p->goidcache = runtime·xadd64(&runtime·sched.goidgen, GoidCacheBatch);
+		p->goidcache -= GoidCacheBatch - 1;
 		p->goidcacheend = p->goidcache + GoidCacheBatch;
 	}
 	newg->goid = p->goidcache++;