]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/cgocall.go
[dev.typeparams] all: merge master (46fd547) into dev.typeparams
[gostls13.git] / src / runtime / cgocall.go
index 479878e6d2f68b3f8b23ff053b9bf73e7385cc89..2f3c609907649b2e385e98ab03183a02efc56a0a 100644 (file)
@@ -213,6 +213,8 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
        // a different M. The call to unlockOSThread is in unwindm.
        lockOSThread()
 
+       checkm := gp.m
+
        // Save current syscall parameters, so m.syscall can be
        // used again if callback decide to make syscall.
        syscall := gp.m.syscall
@@ -228,15 +230,20 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
 
        osPreemptExtExit(gp.m)
 
-       cgocallbackg1(fn, frame, ctxt)
+       cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
 
        // At this point unlockOSThread has been called.
        // The following code must not change to a different m.
        // This is enforced by checking incgo in the schedule function.
 
+       gp.m.incgo = true
+
+       if gp.m != checkm {
+               throw("m changed unexpectedly in cgocallbackg")
+       }
+
        osPreemptExtEnter(gp.m)
 
-       gp.m.incgo = true
        // going back to cgo call
        reentersyscall(savedpc, uintptr(savedsp))
 
@@ -245,6 +252,11 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
 
 func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
        gp := getg()
+
+       // When we return, undo the call to lockOSThread in cgocallbackg.
+       // We must still stay on the same m.
+       defer unlockOSThread()
+
        if gp.m.needextram || atomic.Load(&extraMWaiters) > 0 {
                gp.m.needextram = false
                systemstack(newextram)
@@ -324,10 +336,6 @@ func unwindm(restore *bool) {
 
                releasem(mp)
        }
-
-       // Undo the call to lockOSThread in cgocallbackg.
-       // We must still stay on the same m.
-       unlockOSThread()
 }
 
 // called from assembly