Patchwork libgo patch committed: Set errno after Exitsyscall

login
register
mail settings
Submitter Ian Taylor
Date March 30, 2012, 9:21 p.m.
Message ID <mcrzkax944j.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/149754/
State New
Headers show

Comments

Ian Taylor - March 30, 2012, 9:21 p.m.
In libgo, system calls that return errors convert from an errno value to
an error interface, a step that requires memory allocation.  Memory
allocation should be done while the goroutine is running on a thread
that the Go scheduler knows about, which is to say not between calls to
Entersyscall and Exitsyscall.  This patch to libgo moves the interface
conversion after the call to Exitsyscall.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline and 4.7
branch.

Ian

Patch

Index: libgo/go/syscall/mksyscall.awk
===================================================================
--- libgo/go/syscall/mksyscall.awk	(revision 186020)
+++ libgo/go/syscall/mksyscall.awk	(revision 186021)
@@ -199,6 +199,7 @@  BEGIN {
     }
     printf("c_%s(%s)\n", cfnname, args)
 
+    seterr = 0
     if (gofnresults != "") {
 	fields = split(gofnresults, goresults, ", *")
 	if (fields > 2) {
@@ -218,13 +219,17 @@  BEGIN {
 	    gotype = goparam[2]
 
 	    if (goname == "err") {
+		print "\tvar errno Errno"
+		print "\tsetErrno := false"
 		if (cfnresult ~ /^\*/) {
 		    print "\tif _r == nil {"
 		} else {
 		    print "\tif _r < 0 {"
 		}
-		print "\t\terr = GetErrno()"
+		print "\t\terrno = GetErrno()"
+		print "\t\tsetErrno = true"
 		print "\t}"
+		seterr = 1
 	    } else if (gotype == "uintptr" && cfnresult ~ /^\*/) {
 		printf("\t%s = (%s)(unsafe.Pointer(_r))\n", goname, gotype)
 	    } else {
@@ -243,6 +248,12 @@  BEGIN {
 	print "\tExitsyscall()"
     }
 
+    if (seterr) {
+	print "\tif setErrno {"
+	print "\t\terr = errno"
+	print "\t}"
+    }
+
     if (gofnresults != "") {
 	print "\treturn"
     }