Task context at static location
Hi,
The main idea is to allocate space for task context in the TCB e.g.
typedef struct tskTaskControlBlock
{
#if ( configUSE_STATIC_CONTEXT_FRAME == 1 )
portSTACK_TYPE pxCpuContextFrame[ portCPU_CONTEXT_SIZE ];
#else
volatile portSTACK_TYPE *pxTopOfStack;
#endif
…
Basing on my previous experience with another RTOS and ARM platform I found that such solution has real advantages. It simplify and speeds up context save and restore (at least for the ARM7 platform).
The end results seems quite nice. For my benchmarks I got speedup up to 5% (five tasks with the same priority doing only taskYIELD).
I’ve also observed speedup of interrupt processing. The time between interrupt generation to the first line of C code in the ISR is shorter over 8% (even 9.5% with compiler optimized code) and time from last line of C code in the ISR to the first instrucion in task is shorter nearly 4%.
Tests was performed on LPC2114 using FreeRTOS 4.4 and GCC 4.2 compiler.
Example code for context save for ARM7:
/* push R0 as we are going to use the register */
STMDB SP!, {R0}
LDR R0, =pxCurrentTCB
LDR R0, [R0]
/* seek to R1 location */
ADD R0, R0, #16
STMIA R0, {R1-R14}^
LDR R1, =ulCriticalNesting
LDR R1, [R1]
MRS R2, SPSR
MOV R3, LR
/* pop R0 */
LDMIA SP!, {R4}
/* seek to SPSR location (begin of the context frame) */
SUB R0, R0, #16
/* R1 = ulCriticalNesting, R2 = SPSR, R3 = LR, R4 = R0 */
STMIA R0, {R1-R4}
Example code for context restore for ARM7:
LDR R0, =pxCurrentTCB
LDR R0, [R0]
/* R1 = ulCriticalNesting, R2 = SPSR */
LDMIA R0!, {R1-R2, LR}
LDR R3, =ulCriticalNesting
STR R1, [R3]
MSR SPSR_fsxc, R2
LDMIA R0, {R0-R14}^
NOP
SUBS PC, LR, #4
I welcome any questions and critique.
BTW> Full patchset is available at request.
Regards,
--
Artur Lipowski
Task context at static location
do you have an example, or patchset that could be downloaded somewhere. I’d like to give it a try. What negative effects does/could this patch introduce?
Task context at static location
Why is it faster to store the context in an array rather than on the stack?
Is this change portable?
Task context at static location
> do you have an example, or patchset that could be
> downloaded somewhere. I’d like to give it a try.
I will send you a code by e-mail.
> What negative effects does/could this patch introduce?
Well, till now I did not observe any bad things.
It is one of reasons why I wrote on this forum – maybe other people will able to spot weak sides of this idea (especially on other architectures).
Regards,
--
Artur Lipowski
Task context at static location
> Why is it faster to store the context in an array rather
> than on the stack?
Existing code for context switch on ARM requires retrieving of the SP from different processor mode which complicates things (a little bit). Another (small) speed up comes from the fact that we do not have to store SP twice in (TCB and on the stack).
In fact some speedup is also possible with using existing solution (SP as a part of TCB) and to treat stack as an array.
> Is this change portable?
For current implementation the change is optional and it is just a matter of defining configUSE_STATIC_CONTEXT_FRAME in FreeRTOSConfig.h
Obviously changes for all ARM architectures (including AVR32 ;-) ) are very easy to port for other compilers.
I will look at AVR if it can benefit from this idea.
For other architectures I can only to hope for some feedback from this forum.
Regards,
--
Artur Lipowski