http://www.chibios.org/dokuwiki/doku.ph ... l_sections
"Critical sections" in virtually every other OS means a specific thing (are you aware of any exceptions?). There is an expectation that atomicity of actions taken with the "critical section" will be respected. I recommend describing the specific behavior of chibios "critical sections" in the documentation vis-a-vis typical RTOSes and the expectations that users will undoubtedly have if they read that term.
context switch observed inside S-locked state Topic is solved
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: context switch observed inside S-locked state
Those are critical sections, it is just that you are calling functions that perform context switch inside and other threads exit the critical section. The critical section is global, it is not per-thread.
The critical section is in effect non-stop from lock until unlock, don't call S-class functions if you don't want context switch in the middle because there is no delaying of context switch, it is done synchronously in the exact moment it is required because there is a "before" and an "after" context switch, no uncertainty allowed.
If it is unlike other RTOSes, well, I am glad to hear that , probably this is also why it is running circles around other "typical RTOSes".
Giovanni
The critical section is in effect non-stop from lock until unlock, don't call S-class functions if you don't want context switch in the middle because there is no delaying of context switch, it is done synchronously in the exact moment it is required because there is a "before" and an "after" context switch, no uncertainty allowed.
If it is unlike other RTOSes, well, I am glad to hear that , probably this is also why it is running circles around other "typical RTOSes".
Giovanni
- sabdulqadir
- Posts: 49
- Joined: Fri Mar 23, 2018 7:29 pm
- Has thanked: 13 times
- Been thanked: 4 times
Re: context switch observed inside S-locked state
Giovanni wrote:...
If it is unlike other RTOSes, well, I am glad to hear that , probably this is also why it is running circles around other "typical RTOSes".
Giovanni
Way to go Faisal, you made Giovanni's day today
Coming back to the topic, m,y confusion stems from the fact that chThdSuspendS() would unlock the system when it reschedules. This is not apparent nor mentioned anywhere in the documentation (I may have missed something though), do we agree to that?
Thanks,
AQ
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: context switch observed inside S-locked state
sabdulqadir wrote:Coming back to the topic, m,y confusion stems from the fact that chThdSuspendS() would unlock the system when it reschedules. This is not apparent nor mentioned anywhere in the documentation (I may have missed something though), do we agree to that?
S functions DO NOT unlock the system but DO perform a context switch, it is the thread switched-in that performs an unlock, this is inherent in passing control to another thread.
Functions like chThdSuspendS() put the thread to sleep, I think one should not expect for interrupts to be disabled while the thread is sleeping.
Giovanni
- sabdulqadir
- Posts: 49
- Joined: Fri Mar 23, 2018 7:29 pm
- Has thanked: 13 times
- Been thanked: 4 times
Re: context switch observed inside S-locked state
Giovanni wrote:sabdulqadir wrote:Coming back to the topic, m,y confusion stems from the fact that chThdSuspendS() would unlock the system when it reschedules. This is not apparent nor mentioned anywhere in the documentation (I may have missed something though), do we agree to that?
S functions DO NOT unlock the system but DO perform a context switch, it is the thread switched-in that performs an unlock, this is inherent in passing control to another thread.
Functions like chThdSuspendS() put the thread to sleep, I think one should not expect for interrupts to be disabled while the thread is sleeping.
Giovanni
So yes, you are right, I followed chThdSuspendS() and it did not unlock the system. It just performed a context switch.
Then I tried looking for "implicit" or "inherent" ways that System may get unlocked. I found _dbg_check_unlock() within _port_switch_from_isr(). I understand this is where we unlock the system from isr perspective. What about threads? Is there a place where I should find these implicit unlock calls when my chThdSuspendS() context, switches to another thread?
Thanks,
AQ
Re: context switch observed inside S-locked state
The _dbg_check_unlock is an assert check for the lock state. It does not change the lock state.
I'm looking at the ARMv6-M port for reference. The unlock happens as "cpsie i" in chcoreasm.S, or "port_unlock_from_isr" in chcore.c NMIHandler (config option). However, that is for interrupt / asynchronously preempted threads only. The trick is that context-switching will actually leave the thread being switched out in the middle of __port_switch_from_isr. It will resume at the instruction after chSchDoPreemption. It will then hit the unlock and resume unlocked execution.
Synchronous preemption (chThdSuspendS / chSysGoSleepS), leaves the thread being switched out at chSysSwitch. It will resume execution from either of these calls.
The simplified call chains are:
Into synchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> chSysGoSleepS (after chSysSwitch) -> User code (still S-Locked).
Into asynchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> __port_switch_from_isr (in the middle of it, unlocking as it goes) -> User code (unlocked).
I hope this didn't add more confusion.
I'm looking at the ARMv6-M port for reference. The unlock happens as "cpsie i" in chcoreasm.S, or "port_unlock_from_isr" in chcore.c NMIHandler (config option). However, that is for interrupt / asynchronously preempted threads only. The trick is that context-switching will actually leave the thread being switched out in the middle of __port_switch_from_isr. It will resume at the instruction after chSchDoPreemption. It will then hit the unlock and resume unlocked execution.
Synchronous preemption (chThdSuspendS / chSysGoSleepS), leaves the thread being switched out at chSysSwitch. It will resume execution from either of these calls.
The simplified call chains are:
Into synchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> chSysGoSleepS (after chSysSwitch) -> User code (still S-Locked).
Into asynchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> __port_switch_from_isr (in the middle of it, unlocking as it goes) -> User code (unlocked).
I hope this didn't add more confusion.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: context switch observed inside S-locked state
Absolutely, it is a good description.
IRQ "tail" processing is a very tricky part of the Cortex-M ports. It has to deal with the stacked interruptions and make sure that switch happens when the exceptions stack had been emptied.
Giovanni
IRQ "tail" processing is a very tricky part of the Cortex-M ports. It has to deal with the stacked interruptions and make sure that switch happens when the exceptions stack had been emptied.
Giovanni
- sabdulqadir
- Posts: 49
- Joined: Fri Mar 23, 2018 7:29 pm
- Has thanked: 13 times
- Been thanked: 4 times
Re: context switch observed inside S-locked state
Thanks for the reply psyco, really appreciate it.
So I was following _dbg_check_unlock->_dbg_leave_lock()->ch.dbg.lock_cnt = (cnt_t)0
I assumed lock_cnt maintains the chibios system state (my concern).
About the global interrupt being enabled, yes you are right. On ARMv7-M it is handled by SVC_Handler() which is called after _dbg_check_unlock().
Based on what you said, I still have few questions.
I have synchronous preemption (chThdSuspend()) and yet I see a system unlock.
I have a simple program, which only has "main" and "idle" threads.
main()->...->chThdSuspend()->...->chSysSwitch()
This is where "main" thread calls for a context switch and should switch into "idle" thread (and wait for interrupt).
I see
__port_switch_from_isr (resumed after chSchDoReschedule()) -> dbg_check_unlock() -> SVC_Handler() -> idle_thread()
Based on this, I am assuming as we are not getting into the "user code", your first statement stands. If the system gets into user code instead of idle thread, it would still be s-locked. Am I correct here?
Also,
I am confused on why after a context switch, execution resumed from the middle of port_switch_from_isr().
Is there any literature that I should be reading to help me understand scheduling and context switching on chibios (or any forum threads)?
Thanks psyco and Giovanni for your time.
AQ
psyco wrote:The _dbg_check_unlock is an assert check for the lock state. It does not change the lock state.
So I was following _dbg_check_unlock->_dbg_leave_lock()->ch.dbg.lock_cnt = (cnt_t)0
I assumed lock_cnt maintains the chibios system state (my concern).
About the global interrupt being enabled, yes you are right. On ARMv7-M it is handled by SVC_Handler() which is called after _dbg_check_unlock().
psyco wrote:Synchronous preemption (chThdSuspendS / chSysGoSleepS), leaves the thread being switched out at chSysSwitch. It will resume execution from either of these calls.
The simplified call chains are:
Into synchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> chSysGoSleepS (after chSysSwitch) -> User code (still S-Locked).
Into asynchronously preempted: (S-Locked) chSysGoSleepS -> __port_switch -> __port_switch_from_isr (in the middle of it, unlocking as it goes) -> User code (unlocked).
I hope this didn't add more confusion.
Based on what you said, I still have few questions.
I have synchronous preemption (chThdSuspend()) and yet I see a system unlock.
I have a simple program, which only has "main" and "idle" threads.
main()->...->chThdSuspend()->...->chSysSwitch()
This is where "main" thread calls for a context switch and should switch into "idle" thread (and wait for interrupt).
I see
__port_switch_from_isr (resumed after chSchDoReschedule()) -> dbg_check_unlock() -> SVC_Handler() -> idle_thread()
Based on this, I am assuming as we are not getting into the "user code", your first statement stands. If the system gets into user code instead of idle thread, it would still be s-locked. Am I correct here?
Also,
I am confused on why after a context switch, execution resumed from the middle of port_switch_from_isr().
Is there any literature that I should be reading to help me understand scheduling and context switching on chibios (or any forum threads)?
Thanks psyco and Giovanni for your time.
AQ
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: context switch observed inside S-locked state
After calling port_switch() you always return from a port_switch() called in another place. This is why you return in __port_switch_from_isr(), a port_switch() is called from there.
If trying to understand it is better if you work using -O0, that makes things much easier.
Giovanni
If trying to understand it is better if you work using -O0, that makes things much easier.
Giovanni
Who is online
Users browsing this forum: No registered users and 49 guests