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

StackOverflow https://stackoverflow.com/questions/22854872

Вопрос

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.

Это было полезно?

Решение

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.

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top