I have a function with the following implementation:
void func (uint8 index, uint8 status)
{
if (status == 1)
{
myArrayOfStructures[index].status = 1;
}
else if (status == 0)
{
myArrayOfStructures[index].status = 0;
}
else
{
/* Nothing */
}
}
NB: myArrayOfStructures is a global variable on the file.
I thought that this function is re-entrant as long as the passing of its arguments is done through stack because of the following analysis:
The 2 arguments of the functions, on function call, are pushed onto stack. If the function is interrupted by itself from another OS task the argument are pushed onto stack a second time. Thus the 2 instances of the function are "independent" as each has its own set of arguments in stack.
Until, I have optimized this file for speed using a certain compiler option.
After optimization, I found that the passing of those arguments is done through registers (I know that the compiler has the right to do such thing (Register Allocation)). But this optimization has made this function non-re-entrant.
So, my question is
- Is the above function really a re-entrant or not ?
- If yes (re-entrant), how could the compiler make such an optimization which could revert its re-entrancy status ?
Please refer me to a reference with your answer.
Thanks a lot.
Your function is re-entrant, regardless of the parameter passing mode the compiler chooses.
Although relying on global state for correct execution breaks re-entrancy, simply accessing global state does not necessarily make your function non re-entrant. In particular, if you never read global variables, as is the case in your function, your code is re-entrant, because its execution has no dependency on the global state.
As far as passing parameters through registers is concerned, a context switch saves the content of all registers as well, so the values are interrupt-safe regardless of the parameter passing mode.