Why is this code considered repeated and what exactly happens when the OS interrupts the thread?

Here's the code snippet that IBM says is reentrant:

/* reentrant function (a better solution) */ char *strtoupper_r(char *in_str, char *out_str) { int index; for (index = 0; in_str[index]; index++) out_str[index] = toupper(in_str[index]); out_str[index] = 0 return out_str; } 

This code is not reentrant to me, because the index for the loop counter is determined locally. If the OS interrupts this thread inside the loop and another thread calls this function, the index will be lost. What am I missing? Why is this code considered reentrant?

Does the OS save a copy of local variables, such as an index, to the stream stack when it interrupts the stream and then restores the variables when processing continues?

It seems that this function of the reentrant function should be part of the interface as storage provided by the caller.

+7
c ++ multithreading winapi reentrant
source share
2 answers

not reentrant, because the index for the loop counter is determined locally. If the OS interrupts this thread inside the loop and another thread calls this function, the index will be lost. What am I missing? Why is this code considered reentrant?

The processor itself will save at least the current instruction pointer (probably the flag register and several segment and stack registers, but it depends on the processor) when an interrupt occurs, and then, for example, (for x86) call the code based on the table of function pointers to a specific memory address. You can expect these interrupt handlers to save (for example, push to stack) the other registers that they want to use, and then restore them before returning.

Each thread has its own stack, so it all binds together.

Does the OS save a copy of local variables, such as an index, to the stream stack when it interrupts the stream and then restores the variables when processing continues?

Often ... either they are saved on the stack, or some processors (for example, Sparcs) have registration windows - the same processor codes address different registers during the execution of the interrupt handler, then the context switches back to the registers that the program used.


This is the use of data other than the stack, which stops the function from re-entering, for example, a variable that is static inside the body of the function, or some global variable / buffer.

+6
source share

Non-static local variables are usually allocated on the stack or in registers. Each thread has its own copy of the stack and registers (or, at least, the OS creates this illusion by saving and restoring the contents).

Therefore, non-static local variables are thread safe, they do not "forget" their value when a context switch occurs.

+4
source share

All Articles