Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

hard switching using Stackman #278

Closed
akruis opened this issue Jun 24, 2021 · 13 comments
Closed

hard switching using Stackman #278

akruis opened this issue Jun 24, 2021 · 13 comments

Comments

@akruis
Copy link

akruis commented Jun 24, 2021

The idea to share the stack switching code between different projects is not new, see issue #10. Last year Kristján Valur Jónsson made another attempt: pull request #230:

The Stackman project (http://github.com/kristjanvalur/stackman) aims to provide simple
stack switching code for modern platforms. The aim is to have application-agnostic code that
performs the basic functionality of saving machine registers and switching stack pointer, leaving the custom code of saving/restoring stack and choosing stack pointer to a user callback.

The resulting switching code is very succinct and easy to verify.

I open this issue to discuss those aspects, that are unrelated to a particular implementation.

What

Make it possible to use Stackman to implement stack-switching instead of the current Stackless code.

Why - Benefits and Drawbacks

argument \ stakeholder Stackless maintainer Python developer end user
Stackman is simpler to maintain. +
Supporting a new platform / architecture / compiler does not require changes to Stackless, only to Stackman +
Stackless own hard switching code works well, Stackman adds complexity to the overall project -
Performance is better / worse +/-

Are there any arguments, why the performance of Stackman is better/worse than legacy Stackless stack switching?

When

Now. Stackless 3.7 is near its eol and Stackless 3.8 hasn't been released. Stackman seems to be sufficiently mature.

How

Pull request #230 proves that Stackman can be used, but there are many more ways to do it.

Options

  1. Install Stackman as an external project. Add a make install option to Stackman. In Stackless add an option --with-stackman to configure.
  2. Like option 1, but automatically detect Stackman and use an option to disable Stackman (--without-stackman).
  3. Add Stackman as a git submodule to Stackless. That's what pull request implement switching using the Stackman submodule #230 does.
  4. Add a full copy of Stackman source (archive) to a sub-directory in the Stackless source code.
  5. Add a partial copy of Stackman to the Stackless source code and automatically use it.

There might be more options.

Requirements

Some requirements. There might be more.

  1. Using Stackman is a compile time option. It is still possible to use the legacy Stackless hard switching code.
  2. No user visible changes in API, stability, usage, if Stackless uses Stackman.
  3. Do not break a working build process, if building from a Stackless source archive. E.g.
    ./configure && make && make test && make install still works. Especially important for the Windows build process.
    As a consequence, Stackless should adhere to the Include-directory layout from C-Python.
  4. If Stackman is not bundled with Stackless source (options 1 and 2), there should be a mechanism to detect, if the found/specified version of Stackman is compatible with Stackless.
  5. No legal risk. Stackless currently is a leisure time project. (Currently I don't expect any problems here, it is just for completeness.)

Discussion

Just some preliminary thoughts

We can divide the possible options into two goups:

  • option 1,2: Stackman is only available, if separately installed
  • option 3...5: Stackman is always available

Currently Stackless is mostly used on Windows amd64 and Linux amd64 (32bit versions are fading away). On these platforms the existing hard switching code and building Stackless just works. Unless Stackman improves the performance, using Stackman or legacy Stackless stack-switching makes no difference. If there was a performance gain, we would prefer option 3...5.

Advantages of option 1 and 2:

  • Implementation of option 1 or 2 is probably simpler than option 3 or 4. Adding a complete copy of the Stackman source causes its header files to live outside of ./Include. Therefore we would need to modify the installation process (make install and Windows Tools/msi) or the build process.
  • Selecting the right library is a concern of the Stackman installation.
  • Stackless source does not contain any precompiled binary.

Option 5 would be fairly similar to the legacy solution. Upgrading to a newer Stackman version become complicated.

@kristjanvalur
Copy link
Collaborator

Stackman has until now been a one-person project. I did expend some effort in streamlining the api and trying to account for all use cases. I also added github actions to run test suite and prepare the pre-compiled binaries for supported platforms. I have been able to support all the modern desktop abis, except for the upcoming Windows on Arm64. The code is there, but unverified since I have been unable to actually get a runnable system with it. ...

@kristjanvalur
Copy link
Collaborator

Linux and windows Arm64 support would be a compelling reason...

@kristjanvalur
Copy link
Collaborator

There was a third attempt, years ago, when I replaced all the stack management code in stackless with the "tealet" module. I can't be sure, but I think it was back when we were using Mercurial and Bitbucket. That one probably never survived the transfer from Bitbucket.
I'll see if I have it at home. It was pretty radical.
libtealet now exists and is based on stackman. It adds stack management on top of stackman's raw switching callback skeleton.

@akruis
Copy link
Author

akruis commented Jun 25, 2021

Hi Kristján, can you point me to libtealet? I can't find the repo anywhere.

I'm going to convert https://bitbucket-archive.softwareheritage.org/projects/kr/krisvale/stackless-tealet.html to git.

@akruis
Copy link
Author

akruis commented Jun 26, 2021

The old tealet patch is now available in pull request #279.

@kristjanvalur
Copy link
Collaborator

kristjanvalur commented Jun 29, 2021

right, it is https://github.com/kristjanvalur/libtealet. It is currently private, but there is no reason to. You should have access to it. considering transferring it to Stackelss-dev and making it public.

@akruis
Copy link
Author

akruis commented Jul 9, 2021

Now that #283 is merged, the integration of Stackman should be straight forward. I'll upgrade merge request #230.
But I'm really curious, if we shouldn't better switch to libtealet?

I'm not sure that I understand the libtealet code well enough to port pull request #279 to our current code base. Additionally I have the impression, that #279 does a lot more than just replace the hard switching mechanism.

@akruis
Copy link
Author

akruis commented Jul 14, 2021

Finally pull request #230 is ready. Kristján, please have a final look at it.

I'm really more than happy to get this pull request finally merged. Many thanks for providing Stackman.

akruis pushed a commit that referenced this issue Jul 16, 2021
Stackless now uses Stackman https://github.com/stackless-dev/stackman for stack switching / hard tasklet switching. The legacy stack switching code is still available. See 'readme.txt' for details.

The Stackman code is in a git submodule located below Stackless/stackman.

You can control the usage of Stackman with the configure options "--with-stackman" and "--without-stackman". On Windows you can use the MSBuild property "stackmanDir". (To set a property add '"/p:name=value"' to the build.bat command line.)

Co-authored-by: Anselm Kruis <[email protected]>
@akruis
Copy link
Author

akruis commented Jul 16, 2021

I just merged pull request #230.

Still to do: eventually update the stackman version, if Kristján pushes more commits to https://github.com/stackless-dev/stackman.

akruis pushed a commit that referenced this issue Jul 16, 2021
@kristjanvalur
Copy link
Collaborator

Hi, sorry for being AFK for so long, have been on vacation. I'll try to take a look at the mismatch between the two stackman forks.
libtealet would be, a potentially even better future for stackless.

pros:

  • stack management of tasklets is managed by localized, python-non-specific code. "stack management" means saving and restoring stacks, managing the memory for them.
  • stackless python code becomes slimmer, much code can be thrown away
  • libtealet makes (in theory) better use of memory. Related tasklets that are sleeping can share heap storage. this memory saving is hypothetical and not tested in real use.

cons:

  • libtealet uses stackman, but doesn't have support for the old stack switching so we don't have fallbacks to the legacy platform switching
  • Initialization of the "main" tasklet changes a bit (all tasklets except the main must be entered via function call, there is no "capture"
  • libtealet needs a bit of love. it is currently private, I want to clean it up and move ownership to the stackless-dev. There is also a dependente pytealet which uses it, to provide a pure python layer, similar to the greenlet module for python.
  • libtealet needs a few extra features to capture statistics, such as the number of tasklets alive, the total memory used by inactive tasklets, the amount of memory saved by "shared" linked stacks.

@akruis
Copy link
Author

akruis commented Jul 25, 2021

Hi, sorry for being AFK for so long, have been on vacation.

Me too. :-) Actually, I was on a business trip.

akruis pushed a commit that referenced this issue Jul 31, 2021
Update stackman to commit dbc72fe520.
@akruis
Copy link
Author

akruis commented Jul 31, 2021

Still to do: eventually update the stackman version, if Kristján pushes more commits to https://github.com/stackless-dev/stackman.

After Kristján pushed his changes, I just updated stackman to commit c572d4d07cc85.

@akruis akruis closed this as completed Jul 31, 2021
akruis pushed a commit that referenced this issue Aug 1, 2021
Update smelly.py to not complain about the symbol prefix "stackman_".
@kristjanvalur
Copy link
Collaborator

Great. Btw, I'm working on better making stackman releases and how to distribute the release binaries, maybe there will be future change :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants