summaryrefslogtreecommitdiff
path: root/src/runtime/asm_arm.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/asm_arm.s')
-rw-r--r--src/runtime/asm_arm.s38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index 01621245dc..cd692e51a3 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -630,6 +630,16 @@ nosave:
TEXT ·cgocallback(SB),NOSPLIT,$12-12
NO_LOCAL_POINTERS
+ // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
+ // It is used to dropm while thread is exiting.
+ MOVW fn+0(FP), R1
+ CMP $0, R1
+ B.NE loadg
+ // Restore the g from frame.
+ MOVW frame+4(FP), g
+ B dropm
+
+loadg:
// Load m and g from thread-local storage.
#ifdef GOOS_openbsd
BL runtime·load_g(SB)
@@ -639,7 +649,8 @@ TEXT ·cgocallback(SB),NOSPLIT,$12-12
BL.NE runtime·load_g(SB)
#endif
- // If g is nil, Go did not create the current thread.
+ // If g is nil, Go did not create the current thread,
+ // or if this thread never called into Go on pthread platforms.
// Call needm to obtain one for temporary use.
// In this case, we're running on the thread stack, so there's
// lots of space, but the linker doesn't know. Hide the call from
@@ -653,7 +664,7 @@ TEXT ·cgocallback(SB),NOSPLIT,$12-12
needm:
MOVW g, savedm-4(SP) // g is zero, so is m.
- MOVW $runtime·needm(SB), R0
+ MOVW $runtime·needAndBindM(SB), R0
BL (R0)
// Set m->g0->sched.sp = SP, so that if a panic happens
@@ -724,14 +735,31 @@ havem:
MOVW savedsp-12(SP), R4 // must match frame size
MOVW R4, (g_sched+gobuf_sp)(g)
- // If the m on entry was nil, we called needm above to borrow an m
- // for the duration of the call. Since the call is over, return it with dropm.
+ // If the m on entry was nil, we called needm above to borrow an m,
+ // 1. for the duration of the call on non-pthread platforms,
+ // 2. or the duration of the C thread alive on pthread platforms.
+ // If the m on entry wasn't nil,
+ // 1. the thread might be a Go thread,
+ // 2. or it's wasn't the first call from a C thread on pthread platforms,
+ // since the we skip dropm to resue the m in the first call.
MOVW savedm-4(SP), R6
CMP $0, R6
- B.NE 3(PC)
+ B.NE done
+
+ // Skip dropm to reuse it in the next call, when a pthread key has been created.
+ MOVW _cgo_pthread_key_created(SB), R6
+ // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
+ CMP $0, R6
+ B.EQ dropm
+ MOVW (R6), R6
+ CMP $0, R6
+ B.NE done
+
+dropm:
MOVW $runtime·dropm(SB), R0
BL (R0)
+done:
// Done!
RET