From cbfc4ff14e350e11f8f0e712a9497bb4251eab0b Mon Sep 17 00:00:00 2001 From: Jeffrey Lee <jlee@gitlab.riscosopen.org> Date: Tue, 11 Aug 2015 19:52:12 +0000 Subject: [PATCH] Fix some re-entrancy issues. Minor optimisations. Detail: s/TickEvents: - Change initial TickNodeLeft check in ProcessTickEventChain to exit on HI rather than NE. This fixes a case where the ticker event chain can become corrupted if ProcessTickEventChain is re-entered while in the middle of processing multiple nodes which are due to fire at the same time (after initial node is removed from the list, head node will be left with a TickNodeLeft value of 0) - Move "IRQ's off again" PSR write to be after the 10 label, to ensure that IRQs are off before we examine/process the next node (naughty CallEvery may have exited with IRQs enabled) - Stop using crusty old WritePSRc macro (currently generates 4 instructions for something that should be 1) - Also get rid of ARM2-era NOPs - Optimise CallEvery check to be MOVS rather than LDR + CMP Admin: Tested on Pandaboard Should fix problem reported on forums with apparent wrap-around of TickNodeLeft value of first node: https://www.riscosopen.org/forum/forums/5/topics/3544 May also fix other ticker corruption problems: https://www.riscosopen.org/forum/forums/4/topics/2708 Version 5.35, 4.79.2.278. Tagged as 'Kernel-5_35-4_79_2_278' --- VersionASM | 10 +++++----- VersionNum | 14 +++++++------- s/TickEvents | 18 ++++++++---------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/VersionASM b/VersionASM index 5c7bc82..407b672 100644 --- a/VersionASM +++ b/VersionASM @@ -13,11 +13,11 @@ GBLS Module_ComponentPath Module_MajorVersion SETS "5.35" Module_Version SETA 535 -Module_MinorVersion SETS "4.79.2.277" -Module_Date SETS "10 Aug 2015" -Module_ApplicationDate SETS "10-Aug-15" +Module_MinorVersion SETS "4.79.2.278" +Module_Date SETS "11 Aug 2015" +Module_ApplicationDate SETS "11-Aug-15" Module_ComponentName SETS "Kernel" Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel" -Module_FullVersion SETS "5.35 (4.79.2.277)" -Module_HelpVersion SETS "5.35 (10 Aug 2015) 4.79.2.277" +Module_FullVersion SETS "5.35 (4.79.2.278)" +Module_HelpVersion SETS "5.35 (11 Aug 2015) 4.79.2.278" END diff --git a/VersionNum b/VersionNum index 5b4df7d..dd5c882 100644 --- a/VersionNum +++ b/VersionNum @@ -5,19 +5,19 @@ * */ #define Module_MajorVersion_CMHG 5.35 -#define Module_MinorVersion_CMHG 4.79.2.277 -#define Module_Date_CMHG 10 Aug 2015 +#define Module_MinorVersion_CMHG 4.79.2.278 +#define Module_Date_CMHG 11 Aug 2015 #define Module_MajorVersion "5.35" #define Module_Version 535 -#define Module_MinorVersion "4.79.2.277" -#define Module_Date "10 Aug 2015" +#define Module_MinorVersion "4.79.2.278" +#define Module_Date "11 Aug 2015" -#define Module_ApplicationDate "10-Aug-15" +#define Module_ApplicationDate "11-Aug-15" #define Module_ComponentName "Kernel" #define Module_ComponentPath "castle/RiscOS/Sources/Kernel" -#define Module_FullVersion "5.35 (4.79.2.277)" -#define Module_HelpVersion "5.35 (10 Aug 2015) 4.79.2.277" +#define Module_FullVersion "5.35 (4.79.2.278)" +#define Module_HelpVersion "5.35 (11 Aug 2015) 4.79.2.278" #define Module_LibraryVersionInfo "5:35" diff --git a/s/TickEvents b/s/TickEvents index c7a5c63..47a9a95 100644 --- a/s/TickEvents +++ b/s/TickEvents @@ -145,11 +145,10 @@ ProcessTickEventChain ROUT LDR r2, [r1, #TickNodeLeft] SUBS r2, r2, #1 STR r2, [r1, #TickNodeLeft] - MOVNE pc, lr ; nothing to call yet (was MOVPL) + MOVHI pc, lr ; nothing to call yet (HI to cope with ordinary 1 -> 0 transition, and 0 -> -1 transition if re-entered while processing two or more events which are due to fire at the same time) Push "lr" ; save IRQ_lr - WritePSRc SVC_mode+I_bit, r10 ; switch to SVC mode, IRQ's off - NOP + MSR CPSR_c, #SVC32_mode+I32_bit ; switch to SVC mode, IRQ's off Push "lr" ; save SVC_lr 01 LDMIA r1, {r2, r10, r11, r12} ; load next ptr, redo state, @@ -162,8 +161,7 @@ ProcessTickEventChain ROUT BLX r11 ; call event handler ] - LDR r0, [r1, #TickNodeRedo] - CMP r0, #0 ; CallEvery? + MOVS r0, r10 ; CallEvery? BEQ %FT05 BL InsertTickerEvent ; yes, then re-insert timer @@ -172,7 +170,7 @@ ProcessTickEventChain ROUT 05 ; Return spent ticker node to heap - WritePSRc SVC_mode, r2 ; IRQ's ON for the S L O W bit + MSR CPSR_c, #SVC32_mode ; IRQ's ON for the S L O W bit MOV r2, r1 ; R2->node to free [ ChocolateSysHeap ASSERT ChocolateTKBlocks = ChocolateBlockArrays + 8 @@ -187,10 +185,11 @@ ProcessTickEventChain ROUT MOV r0, #HeapReason_Free SWI XOS_Heap ] - WritePSRc SVC_mode+I_bit, r1 ; IRQ's off again ; Check for more events at the same level in the list 10 + MSR CPSR_c, #SVC32_mode+I32_bit ; IRQ's off again (after returning node to heap, or after naughty CallEvery exits with IRQs on) + LDR r1, [r3, #TickNodeLink] ; get top of list CMP r1, #0 ; list empty? BEQ %FT02 ; yes then exit @@ -200,13 +199,12 @@ ProcessTickEventChain ROUT BEQ %BT01 ; yes then jump 02 Pull "lr" ; restore SVC_lr - WritePSRc IRQ_mode+I_bit, r10 ; back to IRQ mode - NOP + MSR CPSR_c, #IRQ32_mode+I32_bit ; back to IRQ mode Pull "pc" ; pull IRQ_lr from IRQ stack RemoveTickerEvent_Code ; R0 is address of code to remove, R1 the R12 value - WritePSRc SVC_mode+I_bit, r10 + MSR CPSR_c, #SVC32_mode+I32_bit LDR r10, =ZeroPage+TickNodeChain 01 LDR r11, [r10] -- GitLab