# How to Configure Shared Stack Mode in libfiber to Reduce Memory Usage

> Reduce memory usage in libfiber by configuring shared stack mode. Learn to set the ACL_FIBER_ATTR_SHARE_STACK flag or use go_share(size) to reuse stack buffers efficiently.

- Repository: [iQIYI/libfiber](https://github.com/iqiyi/libfiber)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Enable shared stack mode by setting the `ACL_FIBER_ATTR_SHARE_STACK` flag via `acl_fiber_attr_setsharestack()`, passing `true` to `fb.start()` in C++, or using the `go_share(size)` macro to reuse a single stack buffer across all fibers, cutting memory usage from megabytes per fiber to a single shared buffer.**

The iqiyi/libfiber library supports high-performance coroutines with a memory-efficient **shared stack mode** that eliminates per-fiber stack allocations. Unlike the default private-stack mode where each fiber reserves its own memory region, shared stack mode allocates one global buffer that all fibers reuse during execution. This guide demonstrates the exact API calls and source files needed to configure this feature in both C and C++.

## How Shared Stack Mode Works

In the default configuration, libfiber allocates a private stack for every fiber (typically 320 KB per fiber), which consumes massive memory when spawning thousands of concurrent tasks. Shared stack mode reverses this model by maintaining a single memory region that acts as a temporary workspace for whichever fiber is currently executing.

When a fiber yields or blocks, libfiber swaps the current stack contents into a save buffer and restores the next fiber's stack into the shared region. This approach requires only enough memory to hold the deepest call stack among active fibers, plus small per-fiber metadata structures. According to the implementation in [`c/include/fiber/fiber_base.h`](https://github.com/iqiyi/libfiber/blob/main/c/include/fiber/fiber_base.h), the flag `ACL_FIBER_ATTR_SHARE_STACK` (lines 13–15) controls this behavior, while `acl_fiber_attr_setsharestack()` (lines 20–21) provides the runtime interface.

## Configuring Shared Stack Mode in C

The C API exposes granular control over stack sharing through attribute structures and global size setters defined in [`c/include/fiber/fiber_base.h`](https://github.com/iqiyi/libfiber/blob/main/c/include/fiber/fiber_base.h).

### Setting the Global Shared Stack Size

Before creating any fibers, optionally adjust the shared buffer size from its default of 1,024,000 bytes (1 MB) using the global setter. This buffer must accommodate the maximum recursion depth of any fiber in your application.

```c
#include "fiber/lib_fiber.h"

// Reduce shared buffer to 512 KB before any fiber creation
acl_fiber_set_shared_stack_size(512 * 1024);

```

The getter and setter prototypes reside in [`fiber_base.h`](https://github.com/iqiyi/libfiber/blob/main/fiber_base.h) (lines 30–34), with the underlying storage defined in the library's internal state.

### Creating Fibers with Shared Stack Attributes

To enable sharing for a specific fiber, initialize an `ACL_FIBER_ATTR` structure and set the share flag before creation. The implementation in [`c/src/fiber.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/fiber.c) (lines 713–720) handles the flag assignment.

```c
#include "fiber/lib_fiber.h"

static void fiber_task(ACL_FIBER *fb, void *ctx) {
    // Fiber logic executes using the shared buffer
    printf("Fiber %u running on shared stack\n", acl_fiber_id(fb));
}

int main(void) {
    // Optional: Adjust global buffer size first
    acl_fiber_set_shared_stack_size(256 * 1024);
    
    ACL_FIBER_ATTR attr;
    acl_fiber_attr_init(&attr);                    // Initialize defaults
    acl_fiber_attr_setsharestack(&attr, 1);        // Enable shared mode
    
    // Create 10,000 fibers sharing one stack buffer
    for (int i = 0; i < 10000; ++i) {
        acl_fiber_create2(&attr, fiber_task, NULL);
    }
    
    acl_fiber_schedule();  // Start the event loop
    return 0;
}

```

## Configuring Shared Stack Mode in C++

The C++ wrapper in [`cpp/include/fiber/fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/cpp/include/fiber/fiber.hpp) provides ergonomic methods that mirror the C API while maintaining object-oriented semantics.

### Using the fiber::start Method

When starting a fiber instance, pass `true` as the second argument to the `start()` method. The signature in [`fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/fiber.hpp) (lines 55–60) accepts a stack size and a boolean share flag.

```cpp
#include "fiber/libfiber.hpp"

class Worker : public acl::fiber {
protected:
    void run() override {
        printf("Worker %u executing\n", self());
    }
};

int main() {
    // Set global shared buffer to 512 KB
    acl::fiber::set_shared_stack_size(512 * 1024);
    
    // Launch 10,000 fibers with shared stack mode
    for (int i = 0; i < 10000; ++i) {
        Worker* w = new Worker();
        w->start(256 * 1024, true);  // true enables shared stack
    }
    
    acl::fiber::schedule();
    return 0;
}

```

Static helper methods `acl::fiber::set_shared_stack_size()` and `acl::fiber::get_shared_stack_size()` (lines 60–71 in [`fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/fiber.hpp)) wrap the underlying C functions for convenient class-level access.

### Using the go_share Macro

For lambda-based fiber creation, libfiber provides the `go_share(size)` macro defined in [`cpp/include/fiber/go_fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/cpp/include/fiber/go_fiber.hpp) (lines 37–38). This macro expands to `acl::go_fiber(size, true)`, automatically enabling shared stack mode without manual attribute handling.

```cpp
#include "fiber/go_fiber.hpp"
#include <memory>

void concurrent_counter() {
    auto counter = std::make_shared<int>(0);
    
    // Spawn 10 fibers sharing a 128 KB stack buffer
    for (int i = 0; i < 10; ++i) {
        go_share(128 * 1024)[counter] {
            (*counter)++;
        };
    }
    
    acl::fiber::schedule();
    printf("Final count: %d\n", *counter);
}

```

## Memory Usage Comparison

The difference between private and shared stack modes becomes dramatic at scale:

- **Private stack mode**: 10,000 fibers × 320 KB default stack = ~3.2 GB RAM
- **Shared stack mode**: 10,000 fibers × ~64 bytes metadata + 1 MB shared buffer = ~1.6 MB RAM

The trade-off requires that fibers yield cooperatively; if a fiber blocks without yielding, other fibers cannot execute because the shared buffer remains occupied. This constraint aligns naturally with libfiber's coroutine model where fibers surrender control during I/O waits or explicit yields.

## Reference Implementation

The repository includes a production-ready demonstration in [`samples/cxx/shared_stack/main.cpp`](https://github.com/iqiyi/libfiber/blob/main/samples/cxx/shared_stack/main.cpp). This sample creates 10,000 fibers using `go_share(1024)` and verifies that all execution contexts operate within a single 1 MB buffer, printing the final counter value to confirm successful shared-stack operation.

## Summary

- **Shared stack mode** reduces memory from megabytes per fiber to a single reusable buffer by setting the `ACL_FIBER_ATTR_SHARE_STACK` flag.
- **Configuration options** include `acl_fiber_attr_setsharestack()` in C, `fb.start(size, true)` in C++, and the `go_share(size)` macro for lambda syntax.
- **Buffer sizing** is controlled globally via `acl_fiber_set_shared_stack_size()` (default 1,024,000 bytes) defined in [`c/include/fiber/fiber_base.h`](https://github.com/iqiyi/libfiber/blob/main/c/include/fiber/fiber_base.h).
- **Implementation references** span [`c/src/fiber.c`](https://github.com/iqiyi/libfiber/blob/main/c/src/fiber.c) (lines 713–720) for C logic and [`cpp/include/fiber/fiber.hpp`](https://github.com/iqiyi/libfiber/blob/main/cpp/include/fiber/fiber.hpp) (lines 55–71) for C++ wrappers.
- **Practical validation** is available in [`samples/cxx/shared_stack/main.cpp`](https://github.com/iqiyi/libfiber/blob/main/samples/cxx/shared_stack/main.cpp), demonstrating 10,000 concurrent fibers in under 2 MB total memory.

## Frequently Asked Questions

### What is the default size of the shared stack buffer in libfiber?

The default shared stack buffer size is **1,024,000 bytes** (approximately 1 MB), as defined in the implementation of `acl_fiber_set_shared_stack_size()` and `acl_fiber_get_shared_stack_size()` in [`c/include/fiber/fiber_base.h`](https://github.com/iqiyi/libfiber/blob/main/c/include/fiber/fiber_base.h) (lines 30–41). You should adjust this value before creating any fibers to match your application's maximum call depth.

### Can I mix shared-stack and private-stack fibers in the same program?

Yes, libfiber supports mixing both modes simultaneously. The shared-stack flag is set per-fiber via `ACL_FIBER_ATTR` or the boolean parameter in `acl::fiber::start()`, allowing some fibers to use private stacks while others reuse the global buffer. Each fiber operates independently regardless of the stack mode chosen for its peers.

### What happens if a fiber's stack usage exceeds the shared buffer size?

If a fiber's recursion depth exceeds the configured shared stack size, the program will encounter **stack overflow** or memory corruption, similar to exceeding a private stack limit. The buffer does not dynamically expand, so you must profile your deepest call chain and set the global size using `acl_fiber_set_shared_stack_size()` accordingly before spawning fibers.

### Does shared stack mode affect performance compared to private stacks?

Shared stack mode introduces a **context-switch overhead** due to stack copying when fibers yield. When switching contexts, libfiber must save the current fiber's stack contents from the shared buffer to its private save area, then restore the incoming fiber's stack. However, for I/O-bound workloads typical of coroutines, this copying cost is negligible compared to the memory savings achieved.