Refer to the following code:
void calledFunction(volatile uint8_t **inPtr);
volatile uint8_t buffer[] = {0,0,0,0,0,0};
volatile uint8_t *headPtr = buffer;
void foo(void)
{
volatile uint8_t *tmpPtr = NULL;
tmpPtr = headPtr;
//This function modifies tmpPtr
calledFunction(&tmpPtr);
headPtr = tmpPtr;
return;
}
This is a simplified version of code that I am attempting to make interrupt-safe, and I am not sure why this local is defined as a volatile. I know that there is no performance reason (i.e. to guarantee at least O(n) for this function) because this function should run as efficiently as possible.
This function can be called in both main execution and inside interrupts, but since tmpPtr is a nonstatic local variable, it should not be able to be modified by any other instance of foo().
I can't see any access pattern that would require the volatile keyword in this context.
In short, What is the purpose of the volatile keyword for tmpPtr in function foo()?
EDIT:Forgot a & in function argument
EDIT2: I have inherited this code and need to modify it.
My main question is whether the volatile keyword has any special effective reason for being in this context.
EDIT3: Added the prototype for calledFunction()
EDIT4: Added important clarification in original code that headPtr and buffer both have volatile
The reason tmpPtr has volatile is due to tmpPtr needing to reference a volatile uint8_t, not because tmpPtr itself is volatile (it isn't).
As initially pointed out by #Eugene Sh., this question came up due to a misunderstanding in syntax when defining volatile pointers and variables. This question has a great explanation of syntax for pointers to volatile vs volatile pointers.
Volatile restricts the compiler from optimizations when accessing (reading or writing) the data this pointer points to.
This comes up in embedded or interrupts often because memory-mapped peripherals can't have what would normally be "extraneous" reads or writes optimized out.
E.g.,
int32_t variable = 0;
variable = 1;
variable = 2;
variable = 3;
An optimizing compiler would skip setting the value of variable to 0, 1, and 2 and just set it to 3. That's fine generally, but if instead of writing to a normal variable we are writing to a memory-mapped port, we actually want each of those writes to happen.
This can happen even outside the world of hardware interfaces. If a separate thread is in a loop looking for variable to be set to 2, an optimizing compiler would preclude this from happening.
The fact that it's local is not material. It's just that most use cases for volatile happen be implemented with translation-unit (or cross-translation-unit using extern) scope.
Two examples are memory-mapped register definitions (the struct is typically global, often in a header file, and commonly the instance of the pointer to the struct is global though it doesn't have to be), and flags like our thread example.
I don't advocate for either design, but you will come across it frequently in embedded development.
Related
I have the following C code:
/* the memory entry points to can be changed from another thread but
* it is not declared volatile */
struct myentry *entry;
bool isready(void)
{
return entry->status == 1;
}
bool isready2(int idx)
{
struct myentry *x = entry + idx;
return x->status == 1;
}
int main(void) {
/* busy loop */
while (!isready())
;
while (!isready2(5))
;
}
As I note in the comment, entry is not declared as volatile even though the array it points to can be changed from another thread (or actually even directly from kernel space).
Is the above code incorrect / unsafe? My thinking is that no optimization could be performed in the bodies of isready, isready2 and since I repeatedly perform function calls from within main the appropriate memory location should be read on every call.
On the other hand, the compiler could inline these functions. Is it possible that it does it in a way that results in a single read happening (hence causing an infinite loop) instead of multiple reads (even if these reads come from a load/store buffer)?
And a second question. Is it possible to prevent the compiler from doing optimizations by casting to volatile only in certain places like that?
void func(void)
{
entry->status = 1;
while (((volatile struct myentry *) entry)->status != 2)
;
}
Thanks.
If the memory entry points to can be modified by another thread, then the program has a data race and therefore the behaviour is undefined . This is still true even if volatile is used.
To have a variable accessed concurrently by multiple threads, in ISO C11, it must either be an atomic type, or protected by correct synchronization.
If using an older standard revision then there are no guarantees provided by the Standard about multithreading so you are at the mercy of any idiosyncratic behaviour of your compiler.
If using POSIX threads, there are no portable atomic operations, but it does define synchronization primitives.
See also:
Why is volatile not considered useful in multithreaded C or C++ programming?
The second question is a bugbear, I would suggest not doing it because different compilers may interpret the meaning differently, and the behaviour is still formally undefined either way.
I think I have a tricky question, but I'm sure you will be able to help me.
Let's say I have a function like this:
char my_function (int example);
I use this function in multiple cases, sometimes the argument it receives is a volatile variable and sometimes a non-volatile variable.
That cause some warnings when I compile my code that can be easily removed by using casts, but I want to understand which is the safer scenario and why.
Scenario 1:
Prototype: char my_function (int example);
int a;
volatile int b;
my_function (a); // Everything is fine.
my_function ((int)b); // Avoided the warning, by casting the variable and saying it's no longer volatile.
Scenario 2:
Prototype: char my_function (volatile int example);
int a;
volatile int b;
my_function(b); // Everything is fine.
my_function((volatile int)a); // Avoided the warning, by casting 'a' saying that now it's volatile.
I understand how volatile modifier works, I mostly use it because I program micro-controllers and I need to ensure that some of my variables are never optimized out when they are hardware modified.
I am a bit confused about casting the volatile modifier and that is why I want to understand which is the safer scenario apart from just removing the warning.
It really depends on what my_function does with its argument.
Remember that volatile prevents certain optimizations - predominantly it forces the variable to be re-read every time it is referenced. Thus this code
volatile int a;
int b;
// ...
b = a + 1;
b = a + 2;
will read a for each statement and, as a may have changed values between them, give the correct result.
When you pass a volatile into a function as a parameter, you only get one read of the variable. This may then be used multiple times within the function (effectively losing the volatile nature).
Remember that C is pass-by-value. When you invoke the function as
my_function((int)b); // b is declared volatile
The compiler generates code to read b once in the calling code, and push the value it read onto the stack (usually), then invoke my_function. This copy is then referenced within my_function as example, and no matter how often you reference example you will always get the same value (even if the original b variable has since changed many times).
That might be exactly what you want - take a snapshot of the variable and do several computations on its value.
If it's not what you want, you need to consider passing in a pointer with the appropriate volatile qualifications.
char my_function( volatile int *example);
And call it thus:
my_function(&a);
my_function(&b);
Then reference *example inside my_function.
The cast doesn't actually do anything. In the call my_function (b); the code reads the volatile int b. That's where the "volatile" matters, during the read. The result of the read is already an int and not a volatile int. There are no volatile int values. Even if there were volatile int values, passing it to my_function would convert it to plain int, just as the cast does.
It may be that the compiler assumes that passing a volatile int variable to a function is something dangerous worth a warning, and by adding a cast to int you indicate that you know what you are doing.
I am very new to Sparse. And During running sparse I am seeing this warning:
warning: incorrect type in argument 2 (different address spaces)
expected void volatile [noderef] <asn:2>*addr
got void *
Basically, This is happening because of following:
struct context{
void __iomem *base;
};
readl(const volatile void __iomem* add){
....
....
}
function: foo(){
struct context *var;
readl(var->base); //---> here i got the above mentioned warning
}
TO fix this I did following:
struct context{
- void __iomem *base;
+ volatile void __iomem *base;
};
And warning get removed.
My question:
- is it harmful to use "volatile" in such case. and if yes then WHY?
- What I think is that I should not make the member of struct as "volatile". But, then how we can get rid off from the Csparse warning.
As per the documentation given # https://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt
# http://lwn.net/Articles/233482/.
we should always avoid the use of volatile.
No, it's not harmful. No idea why it should or could be, harmful to what?
If the code you're calling expects a volatile pointer, then it's incorrect to pass a non-volatile one, since the code in the calling context might not be properly adapted to the requirements of a volatile value in that case.
volatile instructs the compiler not to do any optimization for that variable. Thus, it would provide guarantee that the latest value of variable to use. This may be altered by an external event.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.
I don't think, it's harmful. But why should one use when not needed, because optimization helps in better efficiency, so if you are sure that even if the variable is optimized, it cannot be altered by external event, then fine, no volatile then.
For a embedded SW project we need to use some const volatile TYPE * pointers. Now we have some calculation functions which are looking like following:
uint8 calc(const volatile uint8 *array, uint8 value) { ... }
The data of both variables is not changing during the function execution.
The calling code looks like following:
const volatile uint8 *array = (const volatile uint8 *)0x00010111;
uint8 value = 8;
uint8 result = calc(array, value);
The question is now, would be there a difference, if we design the calucation functions without volatile arguments:
uint8 calc(const uint8 *array, uint8 value) { ... }
For the call we cast away the volatile:
uint8 result = calc((const uint8 *)array, value);
Pros for the second solution are more flexibility: We can use the function also for non volatile variables. But does it make a difference, if we cast away the volatile and our compiler does some strong optimizations?
You can ALWAYS use the function with non-volatile arguments. Its just that the code in the function handles the given objects as if they were volatile (losing performance on the way, most likely). Its a bit hard to imagine what a function with volatile arguments ("because they might change without notice") could sensibly do. As you write, in your case the data doesn't change anyway, so the most flexible solution is to declare the parameters const and forget about volatile.
And pretty please, use "uint8_t" and not some homegrown type name like uint8 - its in the standard since 1996!
There are two cases: either the function is manipulating hardware registers etc directly. Then you must have volatile in the parameter. Or the function has nothing to do with hardware registers at all. Then it should not have volatile. There is no middle ground between those two cases.
Furthermore, calc((const uint8_t*)array, value); is just a bad, possibly buggy version of
const uint8_t* ptr = array;
calc(ptr, value);
The former form is bad, because the order of evaluation of function arguments is unspecified behavior. The compiler may chose to evaluate the left operand or the right operand first, and you cannot know or assume the order. Since accessing a volatile is a side-effect, your original code can give different results each time the program is built. This is especially problematic (and possibly dangerous) in real time embedded systems.
Therefore it is recommended practice to never access volatile variables inside expressions (see MISRA-C:2004 12.2).
That depends on what really can happen due to volatile-ness.
If the values in this array change during function execution and these changes should be noticed, let them be volatile.
If it doesn't matter, or if the "old" values are more important, omit the volatile.
How do you declare a particular member of a struct as volatile?
Exactly the same as non-struct fields:
#include <stdio.h>
int main (int c, char *v[]) {
struct _a {
int a1;
volatile int a2;
int a3;
} a;
a.a1 = 1;
a.a2 = 2;
a.a3 = 3;
return 0;
}
You can mark the entire struct as volatile by using "volatile struct _a {...}" but the method above is for individual fields.
Should be pretty straight forward according to this article:
Finally, if you apply volatile to a
struct or union, the entire contents
of the struct/union are volatile. If
you don't want this behavior, you can
apply the volatile qualifier to the
individual members of the
struct/union.
I need to clarify volatile for C/C++ because there was a wrong answer here. I've been programming microcontroleurs since 1994 where this keyword is very useful and needed often.
volatile will never break your code, it is never risky to use it. The keyword will basically make sure the variable is not optimized by the compiler. The worst that shold happen if you overuse this keyword is that your program will be a bit bigger and slower.
Here is when you NEED this keyword for a variable :
- You have a variable that is written to inside an interrupt function.
AND
- This same variable is read or written to outside interrupt functions.
OR
If you have 2 interrupt functions of different priority that use the variable, then you should also use 'volatile'.
Otherwise, the keyword is not needed.
As for hardware registers, they should be treated as volatile even without the keyword if you don't do weird stuff in your program.
I just finished a data structure in which it was obvious where the volatile qualifier was required, but for a different reason than the ones stated above: It is simply because the struct requires a forceful locking mechanism because of (i) direct access and (ii) equivalent invocation.
Direct access deals with sustained RAM reading and writing.
Equivalent invocation deals with interchangeable method flows.
I haven't had much luck with this keyword unless the compiler knows exactly what to do about it. And that's my own personal experience. But I am interested in studying how it directly impacts a cross-platform compilation such as between a low-level system call and a back-end database.