Why is this code considered reetrant and what exactly happens when the OS interrupts a thread?
Asked Answered
T

2

7

Here's a snippet of code 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;
}

To me this code is not reentrant because index for the loop counter is being defined locally. Should the OS interrupt this thread inside the loop, and another thread call this function, index would be lost. What am I missing? Why is this code considered reentrant?

Does the OS save a copy of local variables like index on to a thread's stack when it interrupts the thread and then reestablishes the variables when processing continues?

It seems to make this function reentrant Index would have to be part of the interface as storage provided by the caller.

Tallyman answered 4/4, 2014 at 6:11 Comment(3)
Yes, stack variables are thread-local and will be saved if there is an interrupt.Thunder
So if thread A calls this function and is interrupted in the loop so thread B can call the same function, then when thread A continues, all the state info thread A needs to continue where it left off will be reestablished? And this happens because when the processor interrupts Thread A it saves local variable such as Index to the thread's stack and then reestablishes those variables when processing resumes? Thus there is never contention for functions and local variables.Tallyman
The local variable index isn't "saved" to the stack. It lives on the stack to begin with.Dunlop
O
6

not reentrant because index for the loop counter is being defined locally. Should the OS interrupt this thread inside the loop, and another thread call this function, index would be lost. What am I missing? Why is this code considered reentrant?

The CPU itself will save at least the current instruction pointer (likely the flags register and a few segment and stack registers too but it's CPU dependent) when an interrupt occurs, then e.g. (for x86) invoke code based on a table of function pointers at a specific memory address. Those interrupt handlers can be expected to save (e.g. push to stack) other registers they want to use, then restore them before returning.

Each thread has it's own stack, so this all hangs together.

Does the OS save a copy of local variables like index on to a thread's stack when it interrupts the thread and then reestablishes the variables when processing continues?

Often... either saved to stack, or some CPUs (e.g. Sparcs) have register windows - the same CPU opcodes address different registers while the interrupt handler runs, then the context switches back to the registers the program was using.


It's the use of non-stack data that stops a function from being re-entrant, such as a variable that's static within the function body, or some global variable/buffer.

Olivero answered 4/4, 2014 at 6:17 Comment(0)
S
4

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

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

Spoken answered 4/4, 2014 at 6:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.