Should xPendingReadyList be volatile?

richard_damon wrote on Tuesday, April 09, 2019:

List_t* const pxConstList = (pxList);

Is very well defined code, even if List_t has a volatile as part of its definition. It says that pxConstList has a constant value, that of pxList at that point in time, and that value can not change (but the List_t that it points to can). Perhaps the compiler has a bug that it thinks that const pointers imply that the objects they point to are constant (which they aren’t, they are allowed to change). The POINTER is constant, the POINTEE is volatile, and are very different objects.

As an example, you sell your house and new people move in. The contents of the house have changed, but a letter with a constant address, used to refer to you, but now referers to the new owners. pxConstList is like that letter, it knows exactly which List_t it is refering to, and which one can’t change, but the value of that List_t can change all over the place (including the pointers within it)

ldb wrote on Tuesday, April 09, 2019:

So explain the difference carefully between the normal form
const List_t* pxConstList
and this weird form
List_t* const pxConstList

I have never used the second form … not ever

Then we get to the inner detail
1.) Why make the pointer constant … what is the point of it?
2.) There is no context switch why are volatiles having to be put on the fields?

richard_damon wrote on Tuesday, April 09, 2019:

const List_t* pxConstList

says pxConstList is a pointer (that we can change) to a List_t that we can’t change (but perhaps others can).

List_t * const pxConstList

Is a pointer, that we can’t change the value of to a List_t that we can.

It is actually not that uncommon of a form.

One thing to remember when dealing with a pointer, is you really have two distinct objects being used, one object is the pointer itself, and the second object is the object the pointer points to (and changing the value of the pointer changes what object is being pointer to).

Why make the pointer const? I suppose for the same reason you make ANY object const, you know that you are not going to change it and you want the compiler to check that and give you and error if you do. It also means that sometimes the compiler may be able to optimize a bit better.

As to the possible need for volatile, the only time you need volatile is if something the compiler might not know about can change the object, that might be due to an ISR affecting them. In this case, I think the code is running in a critical section, so we shouldn’t need to worry about volatile

I think that is true in general, which is one reason List_t’s are volatile by default, but perhaps bugs like this might be the reason the option was created, Richard Barry will likely know that better than me.

ldb wrote on Tuesday, April 09, 2019:

Yeah I think I will just stick to normal typedefs and avoid that mess … don’t know any compiler that gets them wrong :slight_smile:

rtel wrote on Wednesday, April 10, 2019:

Yes, analysis showed the volatiles should not be necessary - but due to
this kind of issue we left a back door to be able to add them back in
without changing the source code.

As to why const - optimisation. There are some places in the code where
a pointer becomes a loop invariant (won’t change inside the loop) so we
make a local const version of the same pointer. Analyzing the compiler
output showed the reduction in asm instructions made it worthwhile.

cobusve wrote on Wednesday, April 10, 2019:

This is a very important form which you definitely should learn about. You probably needed it many times but just had not encoutered it before. It is very common to have a pointer which must always point to the same location, but the contents of the location itself is not const (like the head of a global linked list e.g.).

There is a clarifying example in section 6.7.5.1 of the C99 standard.

Here it is with the explanation. The section is called Pointer Declarators, semantics:

EXAMPLE The following pair of declarations demonstrates the difference between a ‘‘variable pointer to a constant value’’ and a ‘‘constant pointer to a variable value’’.
const int *ptr_to_constant;
int *const constant_ptr;

The contents of any object pointed to by ptr_to_constant shall not be modified through that pointer, but ptr_to_constant itself may be changed to point to another object. Similarly, the contents of the int pointed to by constant_ptr may be modified, but constant_ptr itself shall always point to the same location.

ldb wrote on Wednesday, April 10, 2019:

I can think of a dozen better ways to get that optimized with going to a dicey C syntax that is always going to be problematic with a range of embedded compilers.

Anyhow just looking at it freaked me that much I have pulled the list unit out of my FreeRTOS implementation and replaced it. So I won’t comment further as it just becomes noise for you Richard.