mirror of
https://github.com/golang/go
synced 2024-11-22 01:24:42 -07:00
runtime: disable preemption during software fp routines
It's okay to preempt at ordinary function calls because compilers arrange that there are no live registers to save on entry to the function call. The software floating point routines are function calls masquerading as individual machine instructions. They are expected to keep all the registers intact. In particular, they are expected not to clobber all the floating point registers. The floating point registers are kept per-M, because they are not live at non-preemptive goroutine scheduling events, and so keeping them per-M reduces the number of 132-byte register blocks we are keeping in memory. Because they are per-M, allowing the goroutine to be rescheduled during software floating point simulation would mean some other goroutine could overwrite the registers or perhaps the goroutine would continue running on a different M entirely. Disallow preemption during the software floating point routines to make sure that a function full of floating point instructions has the same floating point registers throughout its execution. R=golang-dev, dave CC=golang-dev https://golang.org/cl/12298043
This commit is contained in:
parent
e2a1bd68b3
commit
e03dd07981
@ -23,6 +23,8 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "zasm_GOOS_GOARCH.h"
|
||||
|
||||
arg=0
|
||||
|
||||
/* replaced use of R10 by R11 because the former can be the data segment base register */
|
||||
@ -54,7 +56,28 @@ TEXT _sfloat(SB), 7, $64-0 // 4 arg + 14*4 saved regs + cpsr
|
||||
MOVW R1, 60(R13)
|
||||
WORD $0xe10f1000 // mrs r1, cpsr
|
||||
MOVW R1, 64(R13)
|
||||
// Disable preemption of this goroutine during _sfloat2 by
|
||||
// m->locks++ and m->locks-- around the call.
|
||||
// Rescheduling this goroutine may cause the loss of the
|
||||
// contents of the software floating point registers in
|
||||
// m->freghi, m->freglo, m->fflag, if the goroutine is moved
|
||||
// to a different m or another goroutine runs on this m.
|
||||
// Rescheduling at ordinary function calls is okay because
|
||||
// all registers are caller save, but _sfloat2 and the things
|
||||
// that it runs are simulating the execution of individual
|
||||
// program instructions, and those instructions do not expect
|
||||
// the floating point registers to be lost.
|
||||
// An alternative would be to move the software floating point
|
||||
// registers into G, but they do not need to be kept at the
|
||||
// usual places a goroutine reschedules (at function calls),
|
||||
// so it would be a waste of 132 bytes per G.
|
||||
MOVW m_locks(m), R1
|
||||
ADD $1, R1
|
||||
MOVW R1, m_locks(m)
|
||||
BL runtime·_sfloat2(SB)
|
||||
MOVW m_locks(m), R1
|
||||
SUB $1, R1
|
||||
MOVW R1, m_locks(m)
|
||||
MOVW R0, 0(R13)
|
||||
MOVW 64(R13), R1
|
||||
WORD $0xe128f001 // msr cpsr_f, r1
|
||||
|
Loading…
Reference in New Issue
Block a user