libgo patch committed: Set errno after Exitsyscall

Submitted by Ian Taylor on March 30, 2012, 9:21 p.m.

Details

Message ID mcrzkax944j.fsf@dhcp-172-18-216-180.mtv.corp.google.com
State New
Headers show

Commit Message

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 hide | download patch | download mbox

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"
     }