In‑Depth Overview of Swoole Coroutine Implementation and C/PHP Stack Management

This article provides a comprehensive technical overview of Swoole's coroutine implementation in PHP 7.1, detailing C‑stack and PHP‑stack management, context switching via boost.context, coroutine creation, scheduling, and I/O event handling, supplemented with diagrams and code excerpts.

Xueersi Online School Tech Team
Xueersi Online School Tech Team
Xueersi Online School Tech Team
In‑Depth Overview of Swoole Coroutine Implementation and C/PHP Stack Management

Swoole Coroutine Overview

Swoole 4 introduces a powerful CSP‑style coroutine model for PHP, allowing concurrent execution via the go() function. Prior to Swoole 4, coroutine support existed but could not fully preserve PHP syntax because C‑stack information was not saved.

Swoole 4 adds C‑stack management, creating, switching, and releasing C‑stacks alongside PHP‑stacks during coroutine lifecycle.

Deep Dive into C‑Stack

Function calls involve instruction pointer jumps, data passing, and memory allocation/release, typically implemented with a stack frame. The article explains stack frames, registers (%rip, %rbp, %rsp), and provides C and assembly examples illustrating stack operations.

Swoole C‑Stack Management

Swoole uses boost.context (functions make_fcontext() and jump_fcontext()) to create and switch C‑stack contexts. The make_fcontext function allocates a memory block on the heap as the C‑stack and sets up the entry function. The jump_fcontext function saves the current registers, stores %rsp, and restores a target context.

The Context layer encapsulates these operations, providing Context(), SwapIn(), and SwapOut() for C‑stack handling.

Swoole PHP Stack Management

PHP uses two structures: zend_vm_stack (the raw stack) and zend_execute_data (execution frames). The default PHP VM stack size is 256 KB, while Swoole allocates an 8 KB stack for coroutines. The article shows the layout of these structures and how Swoole creates, pushes, and pops execution frames.

The php_coro_task structure stores coroutine‑specific PHP stack information. Creation, yielding, and resuming of coroutines involve saving and restoring this structure via PHPCoroutine::create_func, PHPCoroutine::on_yield, and PHPCoroutine::on_resume.

Swoole Coroutine Implementation Details

Each coroutine manages its own C‑stack and PHP‑stack. The Coroutine object holds identifiers, a pointer to its php_coro_task, and a Context for C‑stack handling. Static fields track the current coroutine, the last assigned ID, and function pointers for yielding and resuming.

Coroutine Creation

Coroutines are created with go(), which ultimately calls swoole_coroutine_create. The creation process saves the current PHP stack, allocates a new PHP stack, initializes a Context (C‑stack), and runs the coroutine entry function.

Coroutine Switching

Yielding ( Co::yield()) saves the current coroutine’s PHP stack, restores the origin coroutine’s stack, and swaps out the current coroutine. Resuming ( Co::resume()) performs the inverse, restoring the target coroutine’s PHP stack and swapping it in.

Four coroutine states exist: initialized, running, waiting, and finished. The origin field links coroutines into a chain, enabling cooperative scheduling.

Coroutine Scheduling

Swoole’s scheduler is event‑driven. It uses an underlying reactor (epoll/kqueue/select/poll) encapsulated in swReactor. Socket read/write events and timer events (including Co::sleep()) are registered with the reactor. When an event occurs, the associated coroutine is resumed.

For socket I/O, the Socket class holds a reference to the reactor and tracks which coroutine is blocked on read or write. The reactor’s event loop waits for epoll events, then calls callbacks such as readable_event_callback or writable_event_callback to resume the appropriate coroutine.

Timers are managed by swTimer, a min‑heap of timeout tasks. Adding a timer updates the reactor’s timeout value, and when the timer expires, the callback simply resumes the blocked coroutine.

Conclusion

The article systematically explains how Swoole implements coroutines by managing both C‑stack and PHP‑stack, using boost.context for low‑level context switching, and integrating an event‑driven reactor for I/O and timer scheduling, providing a complete picture of high‑performance asynchronous programming in PHP.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPcoroutineevent loopSwooleC Stack
Xueersi Online School Tech Team
Written by

Xueersi Online School Tech Team

The Xueersi Online School Tech Team, dedicated to innovating and promoting internet education technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.