1. Euphoria DLLs and Multi-tasking
- Posted by mattlewis (admin) Sep 28, 2012
- 1386 views
Disclaimer: I'm not interested in rehashing old discussions. Some things have changed since then, and it would be a waste of time for obvious reasons.
Brief Overview
Euphoria's cooperative multitasking is handled by the backend of the interpreter or the runtime of a translated program. The interpreter, which manages the call stack and execution state of euphoria code, manually saves and restores these things as needed when a task is scheduled to run. In a translated program, the runtime uses either threads or fibers to implement the same thing, except that the OS manages the call stacks and execution states.
Adding Euphoria DLLs
If all of your euphoria code is part of your main program, then the tasking works well. However, you might want to also use a DLL created by translating some Euphoria code. There are two important things to note about this:
- The DLL is made up of compiled C code that was translated from euphoria code
- The DLL has a separate runtime than either the interpreter backend of your main program or the runtime library linked with your translated program.
These facts mean that there is no easy way to make tasking cross that main program / DLL boundary. And so, if you try to translate euphoria code into a DLL, and that euphoria code uses any of the multitasking API, you get an error in the translator.
A Solution?
I've managed to get multitasking to work across this boundary by using callbacks in my euphoria program that the DLL can use instead of the native multitasking API. It only works, however, when the main program is translated. The reason is that when it's translated, the call stack between the main program and the DLL is kept intact by the OS. When running the program with the interpreter, however, we swap out the euphoria call stack, but the "native" call stack between the main program and the DLL stays the same, and so we end up crashing.
The easiest solution to this is to only allow this kind of setup when running translated. This isn't a great situation, but it gets us closer to where we probably would like to be. I imagine using some ifdef magic in std/task.e to make all of this happen, and help set up the callbacks. I think the result would be that when running the main program interpreted, the multitasking calls would end up being a no-op, and they would work as one would expect when the main program was translated.
A more complex, and probably better solution may be to use those OS tools when interpreted that we use when translated. This seems like it would need some major surgery in the back end. Basically, it will require the entire back end to be thread safe, nearly identical to what would be required to make euphoria multi-threaded to begin with. This is probably a reasonable long term goal, but there are many things that need to be done to get there (not all of them even known right now).
Matt