Both sides previous revisionPrevious revisionNext revision | Previous revision |
rfc:fiber [2018/04/17 23:49] – lvht | rfc:fiber [2018/06/12 07:40] (current) – move back to discussion krakjoe |
---|
| |
=== Implementation Detail === | === Implementation Detail === |
In our simple implementation, we only backup/restore the **zend stack**. If you pause a Fiber in some internal function call like `array_map`, the c stack frame maybe over write which will trigger coredump. | In our simple implementation, we only backup/restore the **zend stack**. We **cannot** pause a Fiber during internal function call like `array_map`. |
| |
Martin Schröder has another implementation at https://github.com/fiberphp/fiber-ext/pull/30. Martin's work backup/restore both the zend stack and the c stack. | |
| |
| |
^Property^Martin's Fiber^Our Fiber^ | |
|Minimum Memory Usage|VM stack only (4 KB)|VM & C stack (4 KB + 4 KB)| | |
|Supported Architecturs|any platform supported by compiler|only x86 systems at this time| | |
|Yield in Internal Function|unsupported|supported| | |
|Yield in Iterator|unsupported|supported| | |
| |
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== |
| |
===== Open Issues ===== | ===== Open Issues ===== |
<blockquote>What happens if there are internal calls on the call stack?Say something like array_map(function() { await; }, [1, 2, 3]); inside a fiber. | <blockquote>Why not support backup/restore the c stack?</blockquote> |
</blockquote> | Martin Schröder is working on this at https://github.com/fiberphp/fiber-ext/pull/30. |
| |
Calling Fiber::yield in a internal call will trigger a fatal error. | And here is the comparison. |
| ^Property^Stackless Fiber^Native Fiber^ |
| |1 Minimum Memory Usage|VM stack only (4 KB)|VM & C stack (4 KB + 4 KB)| |
| |2 Supported Architecturs|any platform|x86 at this time| |
| |3 Yield in Internal Function|unsupported|supported| |
| |4 Yield in Iterator|unsupported|supported| |
| |
<blockquote>How do you determine when a fiber has returned? Separate methods similar to Generator would be better.</blockquote> | Stackless fiber use less memory and are not platform-dependend (1 & 2) which makes them very portable and efficient. They do however lack support for anything that involves internal function calls (3) including opcode handlers (4, e.g. foreach loop). |
| |
Offering methods like <code>Fiber::alive()</code>, <code>Fiber::running()</code> makes any meaningful difference to check the <code>Fiber::status()</code> return value. This is just a coding style issue. And as a language feature, Fiber only offer the essential API and let other works to the userland code. | Native fibers are very platform-dependend (2) and use more memory because they do need to allocate a C call stack (1). While memory allocation will be done using mmap() it will still reserve virtual memory (can be problematic for a large number of fibers on 32 bit systems due to limited virtual memory addressing). The big advantage is that all kinds of internal function call (3 & 4) are supported without any changes to the existing codebase. |
| |
<blockquote>Using Fiber::resume() to initialize the fiber and resume feels awkward. Separate methods again would be better.</blockquote> | <blockquote>Why not introduce helper like **Fiber::alive(),Fiber::running()**?</blockquote> |
| |
Both Ruby's Fiber and Lua's coroutine using the same **resume()** API to **init** and **resume** their coroutine. | And as a language feature, Fiber should only offer the essential API. User can implement these methods in user land code easily. |
| |
<blockquote>I think a keyword here would be beneficial, even if it has a minor BC impact.</blockquote> | <blockquote>Why not introduce a dedicate method other than **Fiber::resume()** for Fiber initialization?</blockquote> |
| |
Introducing new keywords like await/emit does not offer any essential benefit but only cause BC impact. | Both Ruby's Fiber and Lua's coroutine using the same **resume()** API to **init** and **resume** their coroutine. |
| |
Both Ruby's Fiber and Lua's coroutine use method to pause and resume their coroutine. | |
| |
===== Unaffected PHP Functionality ===== | ===== Unaffected PHP Functionality ===== |
| |
===== Future Scope ===== | ===== Future Scope ===== |
This sections details areas where the feature might be improved in future, but that are not currently proposed in this RFC. | |
| |
===== Proposed Voting Choices ===== | Syntax like async/await can be implemented in the future, but it's out of the scope of this RFC. |
2/3+1 voting majority | |
| |
===== Patches and Tests ===== | ===== Patches and Tests ===== |