checkdead()
        unlock(&sched.lock)
 
-       if GOOS == "darwin" {
+       if GOOS == "darwin" || GOOS == "ios" {
                // Make sure pendingPreemptSignals is correct when an M exits.
                // For #41702.
                if atomic.Load(&m.signalPending) != 0 {
 
        // On Darwin, wait for all pending preemption signals to
        // be received. See issue #41702.
-       if GOOS == "darwin" {
+       if GOOS == "darwin" || GOOS == "ios" {
                for int32(atomic.Load(&pendingPreemptSignals)) > 0 {
                        osyield()
                }
 
        atomic.Xadd(&gp.m.preemptGen, 1)
        atomic.Store(&gp.m.signalPending, 0)
 
-       if GOOS == "darwin" {
+       if GOOS == "darwin" || GOOS == "ios" {
                atomic.Xadd(&pendingPreemptSignals, -1)
        }
 }
 func preemptM(mp *m) {
        // On Darwin, don't try to preempt threads during exec.
        // Issue #41702.
-       if GOOS == "darwin" {
+       if GOOS == "darwin" || GOOS == "ios" {
                execLock.rlock()
        }
 
        if atomic.Cas(&mp.signalPending, 0, 1) {
-               if GOOS == "darwin" {
+               if GOOS == "darwin" || GOOS == "ios" {
                        atomic.Xadd(&pendingPreemptSignals, 1)
                }
 
                signalM(mp, sigPreempt)
        }
 
-       if GOOS == "darwin" {
+       if GOOS == "darwin" || GOOS == "ios" {
                execLock.runlock()
        }
 }
                        // no non-Go signal handler for sigPreempt.
                        // The default behavior for sigPreempt is to ignore
                        // the signal, so badsignal will be a no-op anyway.
-                       if GOOS == "darwin" {
+                       if GOOS == "darwin" || GOOS == "ios" {
                                atomic.Xadd(&pendingPreemptSignals, -1)
                        }
                        return