How does context switching work?
Richi Dubey
richidubey at gmail.com
Mon Nov 2 15:21:19 UTC 2020
Hi Mr. Dörfler,
Thanks for your reply.
When the first task is reactivated, it leaves the contextswitch function.
> Therefore all the code around the context switch function handles the same
> task it was called for.
When I am debugging sp16.exe,after TA1 calls task_wake_after, it calls the
_Context_Switch() function, and I think (correct me if I am wrong) TA5
follows the execution after TA1 calls _Context_Switch.
I have attached the gdb trace with this mail. Let me know what you think.
Thanks,
Richi.
On Sun, Nov 1, 2020 at 12:35 AM Thomas Dörfler <
thomas.doerfler at embedded-brains.de> wrote:
> Richi,
>
> inside the contextswitch function, the current context ist suspended (so
> it is stuck/frozen die nside the context switch code) and execution
> switches to a different task. When the first task is reactivated, it leaves
> the contextswitch function. Therefore all the code around the context
> switch function handles the same task it was called for.
>
> --------------------------------------------
> embedded brains GmbH
> Thomas Doerfler
> Dornierstr. 4
> D-82178 Puchheim
> Germany
> email: Thomas.Doerfler at embedded-brains.de
> Phone: +49-89-18 94 741-12
> Fax: +49-89-18 94 741-09
> PGP: Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>
>
>
> Am 31.10.2020 16:49 schrieb Richi Dubey <richidubey at gmail.com>:
>
> Hi,
>
> I want to learn more about how context switching works in RTEMS. I saw the
> following lines in theaddispatch.c:
>
> _Thread_Save_fp( executing );
> _Context_Switch( &executing->Registers, &heir->Registers );
> _Thread_Restore_fp( executing );
>
> I do not understand how it works. Here, the executing process saves its
> context by calling _Thread_Save_fp( executing ), then if a different
> process resumes execution after the context switch, why does it get the
> context of previous process (executing)?
>
> Can someone help me learn more about this?
>
> Thanks,
> Richi.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20201102/e2dca42b/attachment.html>
-------------- next part --------------
Right now we are in Task_1:
197 puts( "TA1 - rtems_task_wake_after - yield processor" );
(gdb)
0x00102590 197 puts( "TA1 - rtems_task_wake_after - yield processor" );
(gdb)
0x00102594 197 puts( "TA1 - rtems_task_wake_after - yield processor" );
(gdb)
198 status = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
(gdb) si
0x0010259a 198 status = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
(gdb)
rtems_task_wake_after (ticks=46) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/rtems/src/taskwakeafter.c:28
28 {
(gdb) ni
0x0010b27a 28 {
(gdb)
0x0010b27c 28 {
(gdb)
0x0010b27e 28 {
(gdb)
36 cpu_self = _Thread_Dispatch_disable();
(gdb)
0x0010b284 36 cpu_self = _Thread_Dispatch_disable();
(gdb)
37 executing = _Per_CPU_Get_executing( cpu_self );
(gdb)
0x0010b288 37 executing = _Per_CPU_Get_executing( cpu_self );
(gdb)
0x0010b28c 37 executing = _Per_CPU_Get_executing( cpu_self );
(gdb)
39 if ( ticks == 0 ) {
(gdb)
0x0010b290 39 if ( ticks == 0 ) {
(gdb)
0x0010b292 39 if ( ticks == 0 ) {
(gdb)
40 _Thread_Yield( executing );
(gdb) ni
0x0010b296 40 _Thread_Yield( executing );
(gdb)
0x0010b29a 40 _Thread_Yield( executing );
(gdb)
46 _Thread_Dispatch_direct( cpu_self );
(gdb) si
0x0010b2ba 46 _Thread_Dispatch_direct( cpu_self );
(gdb)
_Thread_Dispatch_direct (cpu_self=0x202180 <_RTEMS_tasks_Objects+1280>) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/src/threaddispatch.c:351
351 {
(gdb) ni
0x00110662 351 {
(gdb)
0x00110664 351 {
(gdb)
0x00110666 351 {
(gdb)
354 if ( cpu_self->thread_dispatch_disable_level != 1 ) {
(gdb)
0x0011066a 354 if ( cpu_self->thread_dispatch_disable_level != 1 ) {
(gdb)
354 if ( cpu_self->thread_dispatch_disable_level != 1 ) {
(gdb)
0x0011066e 354 if ( cpu_self->thread_dispatch_disable_level != 1 ) {
(gdb)
358 _ISR_Local_disable( level );
(gdb)
0x0011067a 358 _ISR_Local_disable( level );
(gdb)
359 _Thread_Do_dispatch( cpu_self, level );
(gdb)
0x0011067e 359 _Thread_Do_dispatch( cpu_self, level );
(gdb) si
0x00110680 359 _Thread_Do_dispatch( cpu_self, level );
(gdb)
_Thread_Do_dispatch (cpu_self=0x1, level=48) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/src/threaddispatch.c:260
260 {
(gdb) ni
0x0011059a 260 {
(gdb)
0x0011059c 260 {
(gdb)
0x0011059e 260 {
(gdb)
0x001105a0 260 {
(gdb)
267 !_ISR_Is_enabled( level )
(gdb)
0x001105a4 267 !_ISR_Is_enabled( level )
(gdb)
0x001105a8 267 !_ISR_Is_enabled( level )
(gdb) ni
267 !_ISR_Is_enabled( level )
(gdb)
0x001105ae 267 !_ISR_Is_enabled( level )
(gdb)
266 if (
(gdb)
0x001105b2 266 if (
(gdb)
276 executing = cpu_self->executing;
(gdb)
0x001105bc 276 executing = cpu_self->executing;
(gdb) p executing
$1 = (Thread_Control *) 0x600f01d3
(gdb) ni
0x001105be 276 executing = cpu_self->executing;
(gdb)
281 level = _Thread_Preemption_intervention( executing, cpu_self, level );
(gdb) p executing
$2 = (Thread_Control *) 0x202180 <_RTEMS_tasks_Objects+1280>
(gdb) ni
0x001105c2 281 level = _Thread_Preemption_intervention( executing, cpu_self, level );
(gdb)
0x001105c4 281 level = _Thread_Preemption_intervention( executing, cpu_self, level );
(gdb)
0x001105c6 281 level = _Thread_Preemption_intervention( executing, cpu_self, level );
(gdb)
0x001105ca 281 level = _Thread_Preemption_intervention( executing, cpu_self, level );
(gdb)
282 heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
(gdb)
0x001105ce 282 heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
(gdb)
0x001105d2 282 heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
(gdb)
289 if ( heir == executing )
(gdb)
0x001105d6 289 if ( heir == executing )
(gdb)
0x001105d8 289 if ( heir == executing )
(gdb)
0x001105da 289 if ( heir == executing )
(gdb)
296 if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
(gdb)
0x001105de 296 if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
(gdb)
296 if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
(gdb)
0x001105e4 296 if ( heir->budget_algorithm == THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE )
(gdb)
299 _ISR_Local_enable( level );
(gdb)
0x001105f8 299 _ISR_Local_enable( level );
(gdb)
304 _Thread_Save_fp( executing );
(gdb)
0x001105fe 304 _Thread_Save_fp( executing );
(gdb)
305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb) si
0x00110604 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
0x00110608 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
0x0011060a 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
0x0011060e 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
0x00110610 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
0x00110612 305 _Context_Switch( &executing->Registers, &heir->Registers );
(gdb)
_CPU_Context_switch () at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/cpu/arm/cpu_asm.S:56
56 DEFINE_FUNCTION_ARM(_CPU_Context_switch)
(gdb) ni
_CPU_Context_switch_arm () at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/cpu/arm/cpu_asm.S:58
58 GET_SELF_CPU_CONTROL r2
(gdb)
59 ldr r3, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
(gdb)
60 stm r0, {r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
(gdb)
63 add r5, r0, #ARM_CONTEXT_CONTROL_D8_OFFSET
(gdb)
64 vstm r5, {d8-d15}
(gdb)
67 str r3, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
(gdb)
75 dmb
(gdb)
76 add sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE)
(gdb)
_CPU_Context_switch_arm () at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/cpu/arm/cpu_asm.S:77
77 mov r3, #0
(gdb)
78 strb r3, [r0, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
(gdb)
83 add r3, r1, #ARM_CONTEXT_CONTROL_IS_EXECUTING_OFFSET
(gdb)
84 ldrexb r4, [r3]
(gdb)
85 cmp r4, #0
(gdb)
86 bne .L_get_potential_new_heir
(gdb)
89 mov r4, #1
(gdb)
90 strexb r5, r4, [r3]
(gdb)
91 cmp r5, #0
(gdb)
92 bne .L_get_potential_new_heir
(gdb)
93 dmb
(gdb)
103 ldr r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
(gdb)
106 ldr r4, [r1, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
(gdb)
109 add r5, r1, #ARM_CONTEXT_CONTROL_D8_OFFSET
(gdb)
110 vldm r5, {d8-d15}
(gdb)
114 mcr p15, 0, r3, c13, c0, 3
(gdb)
117 str r4, [r2, #PER_CPU_ISR_DISPATCH_DISABLE]
(gdb)
121 ldm r1, {r4, r5, r6, r7, r8, r9, r10, r11, r13, pc}
(gdb)
_Thread_Do_dispatch (cpu_self=0x200580 <_Per_CPU_Information>, level=1610678611) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/src/threaddispatch.c:306
306 _Thread_Restore_fp( executing );
(gdb)
0x00110618 306 _Thread_Restore_fp( executing );
(gdb)
308 _User_extensions_Thread_switch( NULL, executing );
(gdb)
0x0011061e 308 _User_extensions_Thread_switch( NULL, executing );
(gdb)
0x00110620 308 _User_extensions_Thread_switch( NULL, executing );
(gdb)
316 cpu_self = _Per_CPU_Get();
(gdb)
0x00110628 316 cpu_self = _Per_CPU_Get();
(gdb)
318 _ISR_Local_disable( level );
(gdb)
0x0011062e 318 _ISR_Local_disable( level );
(gdb)
319 } while ( cpu_self->dispatch_necessary );
(gdb)
0x00110632 319 } while ( cpu_self->dispatch_necessary );
(gdb)
0x00110634 319 } while ( cpu_self->dispatch_necessary );
(gdb)
319 } while ( cpu_self->dispatch_necessary );
(gdb)
0x00110638 319 } while ( cpu_self->dispatch_necessary );
(gdb)
321 post_switch:
(gdb)
323 cpu_self->thread_dispatch_disable_level = 0;
(gdb) p cpu_self->executing;
Invalid character ';' in expression.
(gdb) p cpu_self->executing
$3 = (struct _Thread_Control *) 0x202680 <_RTEMS_tasks_Objects+2560>
(gdb) ni
0x00110640 323 cpu_self->thread_dispatch_disable_level = 0;
(gdb)
0x00110642 323 cpu_self->thread_dispatch_disable_level = 0;
(gdb)
324 _Profiling_Thread_dispatch_enable( cpu_self, 0 );
(gdb)
0x00110646 324 _Profiling_Thread_dispatch_enable( cpu_self, 0 );
(gdb)
0x00110648 324 _Profiling_Thread_dispatch_enable( cpu_self, 0 );
(gdb)
326 _ISR_Local_enable( level );
(gdb)
0x0011064e 326 _ISR_Local_enable( level );
(gdb)
328 _Thread_Run_post_switch_actions( executing );
(gdb) ni
0x00110654 328 _Thread_Run_post_switch_actions( executing );
(gdb)
329 }
(gdb)
0x0011065a 329 }
(gdb)
0x0011065c 329 }
(gdb)
0x0011065e 329 }
(gdb)
_Thread_Dispatch_direct (cpu_self=0x200580 <_Per_CPU_Information>) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/src/threaddispatch.c:360
360 }
(gdb)
0x00110686 360 }
(gdb)
0x00110688 360 }
(gdb)
0x0011068a 360 }
(gdb)
_Thread_queue_Enqueue (queue=0x200888 <_Region_Objects+16>, operations=0x123204 <_Thread_queue_Operations_FIFO>, the_thread=0x202680 <_RTEMS_tasks_Objects+2560>, queue_context=0x20fc38) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/score/src/threadqenqueue.c:453
453 }
(gdb)
0x001145ec 453 }
(gdb)
0x001145ee 453 }
(gdb)
rtems_region_get_segment (id=838926337, size=3072, option_set=0, timeout=0, segment=0x20fd14) at /home/richi/quick-start/src/rtems/c/src/../../cpukit/rtems/src/regiongetsegment.c:113
113 return _Status_Get_after_wait( executing );
(gdb)
0x0010a13c 113 return _Status_Get_after_wait( executing );
(gdb)
0x0010a140 113 return _Status_Get_after_wait( executing );
(gdb)
0x0010a142 113 return _Status_Get_after_wait( executing );
(gdb)
119 }
(gdb)
0x0010a152 119 }
(gdb)
0x0010a154 119 }
(gdb)
0x0010a156 119 }
(gdb)
0x00103c82 in Task5 (argument=0) at /home/richi/quick-start/src/rtems/c/src/../../testsuites/sptests/sp16/task5.c:53
53 status = rtems_region_get_segment(
(gdb)
60 puts_nocr( "TA5 - got segment from region 1 - " );
More information about the devel
mailing list