tpunt / phactor

An implementation of the Actor model for PHP
BSD 3-Clause "New" or "Revised" License
61 stars 5 forks source link

Initial implementation of unfixed machine stack sizes #1

Closed tpunt closed 6 years ago

tpunt commented 6 years ago

Currently, only actors with a fixed stack size are enabled. This is no good because it makes actors quite expensive in terms of memory, and means that the machine stack is going to be small (so there's an easy chance of triggering a stack overflow).

This PR makes actors use the spawned thread stack, where a memcpy operation saves the actor's stack, and then loads it back into the main thread stack when resuming an actor. This means that actors now have good space efficiency, at the cost of slowing down the machine's context switch. The incurred cost is an additional realloc when interrupting an actor (to partially save the machine's stack - this could probably be optimised away in some scenarios), and a memcpy when either interrupting or resuming an actor (to either save or restore the stack). Starting an actor from afresh will not incur any slow down.

This is being introduced as the default behaviour, where fixed stack sizes can still be utilised by compiling the project with PH_FIXED_STACK_SIZE (set to a sane value - at least 8kb).

I also looked into segmented stacks to dynamically resize the machine's stack at runtime, but this turned out to be completely unsuitable. Stack segmentation is only useful if the program has full control over the execution environment, where:

Even if this was a core extension, it would be too complex to robustly implement segmented stacks in PHP (likewise with almost any other project out there). So it largely seems like a useless feature in GCC/Clang...

The current implementation in this PR is a little messy. It could really use a tidy up (perhaps by segregating the APIs of fixed/unfixed stacks). A longjmp operation could be used to jump back up the stack (when interrupting an actor), but whether this would simplify things or not, I'm not sure.

tpunt commented 6 years ago

Merged in 99b3823d609ade0eef922cb467e56e7696fcbf93. In future, the realloc call could be made only in situations when the stack size to be saved is greater than the currently allocated stack size.