context switch observed inside S-locked state Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

context switch observed inside S-locked state

Postby faisal » Tue Apr 10, 2018 12:49 am

I'm doing something like this:

Code: Select all

chSysLock();
chFifoSendObjectS(&fifo, &data);
uint32_t size = chMBGetUsedCountI(&fifo.mbx);
chSysUnlock();


I noticed size is always 0. How is that possible? I single stepped thru chFifoSendObjectS() and confirmed it did a context switch to the thread waiting on that mailbox, it emptied it .. and then eventually context switched back to this thread and checked the size using chMBGetUsedCountI .... *all while inside an S-Locked state!*

I have all state checking debug options turned on, even the trace event log. I confirmed in the trace that it is indeed context switching.

When I look at the sequence of actions taken, I can see how a context switch occured ...
chSysLock()->chFifoSendObjectS->chMBPostTimeoutS->chSchRescheduleS->chSchDoRescheduleAhead->chSysSwitch->port_switch

I'm pretty sure no context switching or even non-fast interrupts should occur in an S-Lock state. What is going on?
From documentation:
S-Locked. Kernel locked and regular interrupt sources disabled. Fast interrupt sources are enabled. S-Class and I-Class APIs are invokable in this state.

faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

Re: context switch observed inside S-locked state

Postby faisal » Tue Apr 10, 2018 1:10 am

So ... I looked deeper (The first page :) )in the documentation and saw the logical state transition diagram here:
http://chibios.sourceforge.net/docs3/rt/concepts.html .

Apparently, a context switch *can* occur in an S-Locked state ... but to an I-Locked state? But in my case it's not going to an ISR, it's just context switching to another ready thread with higher priority. How then can we implement critical regions to manipulate shared data and other atomic operations? If you can go in an S-locked state, and then a context switch occurs in the middle - then the other context and break the atomicity of your actions in the S-locked state and wreak havoc on any shared data.

Also, the state diagram at http://chibios.sourceforge.net/docs3/rt/concepts.html has a typo .. SRI should be ISR, ya?

User avatar
Giovanni
Site Admin
Posts: 13586
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 877 times
Been thanked: 751 times
Contact:

Re: context switch observed inside S-locked state  Topic is solved

Postby Giovanni » Tue Apr 10, 2018 7:54 am

Hi,

SRI is "Serving Regular Interrupt", not a typo.

By design all context switches are guaranteed to occur in S-Locked state, it is the state where that is done. Putting an I-class function after an S-Class is legal *if* the I-class function does not wakeup other threads, if it does then a call to chSchRescheduleS() is required.

Note that in that diagram is not shown an implicit transition from I-locked to S-locked before the switch occurs, that is handled in the port ASM part usually.

I-Class functions are a remaining historical ambiguity because, depending on the function, those could require a reschedule or not, not unambiguous as it should be. Probably in next kernels (RT 6, NIL 4) a new suffix will be introduced for those I-class calls that do not require a reschedule, probably "N". BTW, those requiring a reschedule are those calling any variant of "ready" or "wakeup" (changing some other thread to ready state).

So:
X - Any state, from anywhere.
S - From critical zone, thread context, it can reschedule.
I - From critical zone, thread or ISR context, it requires a reschedule afterwards if called from thread context, ISRs always reschedule if required.
N - From critical zone, thread or ISR context, it does not require a reschedule afterwards (guaranteed to not contain calls to "ready" or "wakeup").

This could seem complex but rules enforcements is important IMHO.

Giovanni

faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

Re: context switch observed inside S-locked state

Postby faisal » Tue Apr 10, 2018 1:23 pm

Ok, I understand how things are.

But, how do I implement critical sections of code? For example if I want to post multiple fifobjects and signal a thread atomically, how could I go about doing that?

You say that I-class functions are a remaining historical ambiguity - but now I want I-class variants of everything so I can control if any context switching could occur within my critical sections.

User avatar
Giovanni
Site Admin
Posts: 13586
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 877 times
Been thanked: 751 times
Contact:

Re: context switch observed inside S-locked state

Postby Giovanni » Tue Apr 10, 2018 1:37 pm

I-class functions never perform a context switch, s-class can do that.

The procedure is:

chSysLock();
I-class()
I-class()
I-class()
chSchRescheduleS();
chSysUnlock();

The number of I-class functions is only constrained by the length of the critical section. The context switch only happens in chSchRescheduleS().

The ambiguity is that chSchRescheduleS() could not be required depending on which I-class functions you are using, it does not hurt anyway. In general, those I-class functions that can wakeup other threads require the final reschedule.

See this article: http://chibios.org/dokuwiki/doku.php?id ... :kb:atomic

Giovanni

faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

Re: context switch observed inside S-locked state

Postby faisal » Wed Apr 11, 2018 2:32 am

Giovanni wrote:I-class functions never perform a context switch, s-class can do that.

The procedure is:

chSysLock();
I-class()
I-class()
I-class()
chSchRescheduleS();
chSysUnlock();

The number of I-class functions is only constrained by the length of the critical section. The context switch only happens in chSchRescheduleS().

The ambiguity is that chSchRescheduleS() could not be required depending on which I-class functions you are using, it does not hurt anyway. In general, those I-class functions that can wakeup other threads require the final reschedule.

See this article: http://chibios.org/dokuwiki/doku.php?id ... :kb:atomic

Giovanni


Yes, exactly. That's why I said that I would like to have I-class variants of everything so I can control when the context switch happens. For example, if I wanted to atomically post multiple things to a message fifo - that wouldn't be possible as no I-class variant is available. If I have to use an S-class, then a context switch could occur after each post to the fifo within the 'critical' section. I guess I'll start reviewing my code, and will request I-class variants of various APIs in the small change requests :) .

User avatar
Giovanni
Site Admin
Posts: 13586
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 877 times
Been thanked: 751 times
Contact:

Re: context switch observed inside S-locked state

Postby Giovanni » Wed Apr 11, 2018 7:56 am

hi,

I-Class is not possible for blocking functions, this is why there is not an I-class variant. If you specify TIME_IMMEDIATE it makes sure that the function is non-blocking and you can use it as an I-class (but only in thread context).

Giovanni

faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

Re: context switch observed inside S-locked state

Postby faisal » Wed Apr 11, 2018 1:32 pm

Giovanni wrote:hi,

I-Class is not possible for blocking functions, this is why there is not an I-class variant. If you specify TIME_IMMEDIATE it makes sure that the function is non-blocking and you can use it as an I-class (but only in thread context).

Giovanni


Yep, thanks for reminder. Sometimes there isn't an I-class variant because it's just missing and no other reason. For example, an I-class variant of chFifoSendObjectS is possible, as it uses TIME_IMMEDIATE with chMBPostTimeoutS internally. The I-class variant would use chMBPostI internally.

As mentioned previously, I'll post in small change requests for the I-class variants I find missing.

Thanks!

User avatar
Giovanni
Site Admin
Posts: 13586
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 877 times
Been thanked: 751 times
Contact:

Re: context switch observed inside S-locked state

Postby Giovanni » Fri Apr 13, 2018 7:54 am

No problems, I will evaluate it.

Giovanni

faisal
Posts: 289
Joined: Wed Jul 19, 2017 12:44 am
Has thanked: 38 times
Been thanked: 38 times

Re: context switch observed inside S-locked state

Postby faisal » Sun May 02, 2021 12:46 am

Ok, I'm back to this slightly confused state with S class functions. So, if I want to implement a critical zone and manipulate a global variable , it seems that isn't possible to o guarantee in an S-lock state?

So below a high priority thread is waiting to receive a fifo object. The low priority thread increments a global variable (thinking it is safe to do so because we're in a critical zone) and sends an object in a fifo. The a context switch happens while doing chFifoSendObjectS, and the high priority thread gets activated. It processes the incoming fifo object and decrements the global variable. This seems quite possible, and is a source of confusion for me where critical zone no longer means critical zone. What is critical about an S-class 'critical zone'? Perhaps the confusion is using the typical RTOS terminology of 'critical zone' - where S locked state never promises to be a 'critical zone'?
Maybe the way to think about this is if I want to guarantee no context switching occurs in an S-locked state and that it is truly a 'critical zone', to only use I-class functions. I think this needs to be better explained in the documentation. I know all the facts are there in the documentation, but its not readily apparent to a user when one is used to hearing 'lock' states as meaning something else everywhere else.


Thread 1: (low priority)
chSysLock()
global_var++
chFifoSendObjectS
ChSysUnlock()

Thread 2: (high priority)
chSysLock
chFifoReceiveObjectTimeoutS
global_var--


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 1 guest