---
title: newlib Thread Safety in GeMRTOS Nios V Multiprocessor RTOS
description: "In GeMRTOS on Altera FPGA platforms with **Nios V** processors, **newlib** functions are reentrant — but reentrancy does not guarantee thread safety. In uniprocessor multiprocessing systems, `_impure_ptr` is used to give newlib functions per-task reentrancy state, making them effectively thread-safe…"
url: "https://rcayssials.hopto.org/gemrtosdocs/newlib-reentrancy-and-thread-safe-in-multiprocessors/"
updated: "2026-06-01"
category: General
tags:
  - Avalon MM
  - GeMRTOS
  - Nios 2
  - Nios V
  - "RISC-V"
---

# newlib Thread Safety in GeMRTOS Nios V Multiprocessor RTOS

In GeMRTOS on Altera FPGA platforms with **Nios V** processors, **newlib** functions are reentrant — but reentrancy does not guarantee thread safety. In uniprocessor multiprocessing systems, `_impure_ptr` is used to give newlib functions per-task reentrancy state, making them effectively thread-safe through context switching. However, in multiprocessor systems, this approach breaks down: multiple tasks can execute simultaneously on different processors, so changing `_impure_ptr` per task is no longer valid. This article explains the distinction and the GeMRTOS solution.

## Reentrancy vs Thread Safety in newlib

**Reentrancy** means a function can be interrupted mid-execution and safely called again before the first call completes — typically by storing all state in caller-provided or per-call structures rather than global variables. newlib achieves reentrancy by storing per-task state in a `struct _reent` structure pointed to by `_impure_ptr`.

**Thread safety** is a stricter guarantee: a function can be called concurrently by multiple threads or tasks running at the same time without corrupting shared state. In a uniprocessor RTOS, tasks never truly run simultaneously — the scheduler switches `_impure_ptr` to each task's own `struct _reent` during context switches, making newlib calls effectively thread-safe by serialization.

## Why `_impure_ptr` Fails in Multiprocessor Systems

In a multiprocessor system, two or more tasks can execute simultaneously on separate processors. If both tasks call a newlib function at the same time, both access `_impure_ptr` concurrently. Since `_impure_ptr` is a single global pointer, there is no guarantee that each processor is referencing its own task's `struct _reent` — a context switch on one processor can change `_impure_ptr` while another processor is mid-execution of a newlib call that depends on it. This leads to corrupted reentrancy state and unpredictable behaviour.

The root problem is that the uniprocessor assumption — only one task runs at a time — no longer holds. Serializing `_impure_ptr` switches through context switching is insufficient when multiple processors execute tasks in parallel.

## The GeMRTOS Solution: Hardware Mutex

GeMRTOS provides a hardware mutex — **GRTOS_USER_CRITICAL_SECTION_GET** and **GRTOS_USER_CRITICAL_SECTION_RELEASE** — that enforces mutual exclusion across all processors at the hardware level. When a task needs to call a newlib function that is not multiprocessor-safe, it should bracket the call with the GeMRTOS mutex to prevent concurrent access:

1. Acquire the GeMRTOS mutex with `GRTOS_USER_CRITICAL_SECTION_GET`.
2. Execute the newlib function call.
3. Release the mutex with `GRTOS_USER_CRITICAL_SECTION_RELEASE`.

**Important:** while the GeMRTOS mutex is held, all GeMRTOS kernel functions are suspended until it is released. Avoid holding the mutex while accessing slow I/O devices or performing lengthy operations, as this will block the entire RTOS kernel across all processors for the duration.

## Key Takeaways

- **Reentrancy ≠ thread safety**: newlib functions are reentrant via `_impure_ptr` / `struct _reent`, but this only provides thread safety when tasks are serialized by a uniprocessor scheduler.
- In a **GeMRTOS multiprocessor Nios V** system, multiple tasks run simultaneously on separate processors — changing `_impure_ptr` per task during context switches no longer prevents concurrent access.
- The **GeMRTOS hardware mutex** (GRTOS_USER_CRITICAL_SECTION_GET / RELEASE) is the correct mechanism for making newlib calls safe across all processors.
- Keep mutex hold-time minimal — the entire GeMRTOS kernel is suspended while the hardware mutex is held, so it must not wrap slow I/O operations.
- This issue applies to any library or code that relies on global or shared state; the same mutex pattern should be used for any non-multiprocessor-safe function called from GeMRTOS tasks.
