Commit cbfc4ff1 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

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'
parent 006183f9
......@@ -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
......@@ -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"
......@@ -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]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment