Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are malloc() and printf() said as non-reentrant?

In UNIX systems we know malloc() is a non-reentrant function (system call). Why is that?

Similarly, printf() also is said to be non-reentrant; why?

I know the definition of re-entrancy, but I wanted to know why it applies to these functions. What prevents them being guaranteed reentrant?

like image 646
ultimate cause Avatar asked Oct 15 '10 10:10

ultimate cause


People also ask

What is reentrant and non-reentrant function in C?

A reentrant function does not hold static data over successive calls, nor does it return a pointer to static data. All data is provided by the caller of the function. A reentrant function must not call non-reentrant functions.

What does it mean if a function is reentrant?

A function is said to be reentrant if there is a provision to interrupt the function in the course of execution, service the interrupt service routine and then resume the earlier going on function, without hampering its earlier course of action.

What is reentrant code and why is it needed?

Reentrant (multi-instance) code is a reusable routine that multiple programs can invoke, interrupt, and reinvoke simultaneously. When you want to reuse code, but associate each instance of the shared code with unique, preserved data, use reentrant code.

Is reentrant a write?

So, for write() , the function itself is Reentrant, but if called with same file descriptor from different thread, it will obviously produce erroneous result.


2 Answers

malloc and printf usually use global structures, and employ lock-based synchronization internally. That's why they're not reentrant.

The malloc function could either be thread-safe or thread-unsafe. Both are not reentrant:

  1. Malloc operates on a global heap, and it's possible that two different invocations of malloc that happen at the same time, return the same memory block. (The 2nd malloc call should happen before an address of the chunk is fetched, but the chunk is not marked as unavailable). This violates the postcondition of malloc, so this implementation would not be re-entrant.

  2. To prevent this effect, a thread-safe implementation of malloc would use lock-based synchronization. However, if malloc is called from signal handler, the following situation may happen:

    malloc();            //initial call   lock(memory_lock); //acquire lock inside malloc implementation signal_handler();    //interrupt and process signal malloc();            //call malloc() inside signal handler   lock(memory_lock); //try to acquire lock in malloc implementation   // DEADLOCK!  We wait for release of memory_lock, but    // it won't be released because the original malloc call is interrupted 

    This situation won't happen when malloc is simply called from different threads. Indeed, the reentrancy concept goes beyond thread-safety and also requires functions to work properly even if one of its invocation never terminates. That's basically the reasoning why any function with locks would be not re-entrant.

The printf function also operated on global data. Any output stream usually employs a global buffer attached to the resource data are sent to (a buffer for terminal, or for a file). The print process is usually a sequence of copying data to buffer and flushing the buffer afterwards. This buffer should be protected by locks in the same way malloc does. Therefore, printf is also non-reentrant.

like image 145
P Shved Avatar answered Sep 20 '22 19:09

P Shved


Let's understand what we mean by re-entrant. A re-entrant function can be invoked before a previous invocation has finished. This might happen if

  • a function is called in a signal handler (or more generally than Unix some interrupt handler) for a signal that was raised during execution of the function
  • a function is called recursively

malloc isn't re-entrant because it is managing several global data structures that track free memory blocks.

printf isn't re-entrant because it modifies a global variable i.e. the content of the FILE* stout.

like image 28
JeremyP Avatar answered Sep 19 '22 19:09

JeremyP