That is a long-standing suggestion and challenge - dating back to the mid 2000s - if you are into a non-heated view of the situation, I would highly recommend reading the following paper, authored by several long-term FlightGear contributors back then (none of whom were/are any core developers):
http://wiki.flightgear.org/Technical_Re ... _SimulatorIn layman terms, the thing as it stands is that FlightGear is/was designed with a mainloop assuming a really fast single core - so that tons of code has been added without any of it being written with multiple cores in mind. As time moved on, more and more people suggested the use of multi-threading (for all the reasons you mention), many of whom spoke up on the devel list - and Curt made some rather elaborate statements why threading would be problematic in a real-life application like FlightGear.
Ultimately, what took place is that people politely decided not to argue with Curt, but still added additional threads to FG - unfortunately, Curt ended up being right, we're seeing tons of threading related problems these days, i.e. segfaults/crashes that can definitely be linked back to FlightGear related threaded code.
The thing is, there is a fairly massive legacy code base that was written with the fixed/single-core assumption in mind, and as things moved on, more and more threading was added - especially in the light of the PLIB/SG->OSG migration - OSG can be extremely aggressive, and good, at multi-threading - but for that to work properly, you need to make use of certain coding patterns - absent that, you don't automatically benefit from any of that functionality, but you add semi-functional (=crippled) functionality that sometimes works, and sometimes just crashes - see the warning at:
http://wiki.flightgear.org/Howto:Activa ... PU_supportMulti-threading is something that is extremely difficutl to get right, and basically impossible to add well after the fact - especially in an unorganized codebase like FlightGear with tons of subsystems treating the property tree as a global dump space for all sorts of state.
The OSG port was initiated over a decade ago, and has never really been completed - so there is tons of legacy functionality that people care about (as in legacy code) that simply cannot be removed, but that is massively incompatible (conflicting) with the way OSG wants to see things done - this is severely limiting FlightGear's evolution.
Nasal is definitely contributing to this, but it's far from the only culprit - I have posted patches that demonstrate how Nasal can be entirely disabled, but there is tons of other legacy code that ends up running in the main loop where it simply doesn't belong.
To some extent, the Canvas system can help us getting rid of certain code, such as the legacy 2D panels code, hard-coded MFDs, HUDs or GUI - because the Canvas system can reimplement those features using a fraction of the size of the legacy C++ code, while internally falling back to just a handful of so called Canvas "elements", all of which are using OSG natively - which is why a number of core developers originally suggested using this approach to help unifying the 2D rendering back-end:
http://wiki.flightgear.org/Unifying_the ... via_canvasIf this should end up being pursued/picked up again, it would be much easier to get rid of tons of legacy rendering code, that can be simply yanked - at the mere cost of writing Nasal parsers that turn the legacy definition files (think 2D panels, GUI dialogs, HUDs) into the corresponding Canvas representation, which is what the pui2canvas parser is doing:
http://wiki.flightgear.org/Howto:Proces ... ing_CanvasCurt nicely summed up the multi-threading challange FlightGear is facing in one of the 2015 sourceforge interviews:
https://sourceforge.net/blog/november-2 ... lightgear/Curt wrote:Defining a multi-threaded client-server architecture from the beginning would make a big difference today but, of course, that wasn’t a priority back then.
[...]
Currently we don’t take good advantage of multi-core CPUs.
[...]
We’re also planning to use HLA/RTI, which will allow FlightGear to integrate with distributed simulation environments (important for industrial applications) and make better use of multi-core processors.
And this is backed up by many discussions in the archives:
http://wiki.flightgear.org/Multi-Thread ... FlightGearIt is hard to come up with something that could be presented as a consensus given the plethora of differing views/approaches, but one of the most commonly mentioned suggestion is decoupling/partitioning the simulator at the sgsubsystem/property tree level, by having one subsystem-specific and private property tree per subsystem, and allowing each subsystem to subscribe to state/events from other subsystems, dispatched using a global property tree - where each property tree would maintain a queue of read/write requests, and only ever handle those in a single-threaded fashion, possibly exposed using an XDR-based PUB/SUB mechanism to get/set properties in different subsystems, where each subsystem would be running in its own/separate thread - here's an article written by James summarizing that idea here:
http://wiki.flightgear.org/Property_threading At that point, you could decouple the simulation from rendering with reasonable effort, but would still need to explicitly stop using/calling any APIs from "outside" subsystems without using serialization.
This is particularly important for subsystems that make heavy use of other subsystems - and Nasal is the main suspect here, because it's sole purpose is using a bunch of existing code/functonality without people having to know C++, so it makes sense that Nasal is the most obvious candidate to optimize when it comes to threading/IPC, because it is touching a ton of places in a very chaotic fashion, which is further complicated by FlightGear -so far- using a single global property tree for all subsystems, instead of having private, and subsystem-specific property trees that are inaccessible from other subsystems at the C++ level without going through an IPC mechanism like networking (heck, even Torsten's websockets would be better than the current mess).
This is where RPC (remote procedure calls), and "IPC" (inter-process communciation) come in - because you inevitably need a way to call functionality/code living in another process/thread at some point, as well as get something back from that. This why some folks have been actively working towards supporting HLA:
http://wiki.flightgear.org/High-Level_ArchitectureAnyway, before Nasal can go, or even just alternatives be considered, people need to understand why FGPythonSys would suffer from the same restrictions.
HLA is all great and dandy, but for that to actually work and be beneficial, certain groundwork has to happen first - and that involves making Nasal entirely optional, so that we can get rid of the hard-coded assumption that Nasal is always up and running.
The next step is making subsystem initialization incremental in its entirety - which also entails stopping to load all sorts of subsystem-specific Nasal scripts despite some subsystems having become optional these days (thanks to James reset/re-init work).
In other words, imagine a scenario where ATC-chatter is loaded but sound is not running/disabled, or the tanker scenario/script with AI disabled (and even moreso Bombable), or gui.nas loaded without PUI being active etc.
And like many people have stated previously, the extreme use of Nasal embedded in GUI dialogs has to stop, too - it's hugely chaotic and almost perverse, it is adding tons of problems, and making it next to impossile to come up with other UIs.
Equally, even the way people code avionics is problematic from the standpoint of wanting a simulation without Nasal in the main loop - as it doesn't scale, it also assumes that Nasal is always running in the main loop - so once/if people shuffle it out of the main loop, there would be all sorts of race conditions (=crashes) caused by such code.
The way Nasal is used in FlightGear is certainly very problematic, but before FGPythonSys (or other alternatives) can be considered, there are a handful of things that need to happen first, e.g.:
- providing an option to disable Nasal entirely: http://wiki.flightgear.org/Howto:Disable_Nasal_entirely
- allow Nasal to be stopped/restarted and removed/re-added at runtime using the subsystemFactory/fgcommands
- providing an option to initialize Nasal much earlier and better formalize subsystem/script dependencies: http://wiki.flightgear.org/Initializing_Nasal_early
- get rid of Nasal hacks commonly used in GUI dialogs and MFDs, i.e. introduce dedicated XML tags for common hacks (think widgets) and instead of having blobs of Nasal code, introduce fgcommands (possibly just mapped to Nasal code), so that other GUIs (think Phi/qt5) can support those files without them having to support Nasal
- Integrating IPC/RPC functionality, so that Nasal interpreters can access other subsystem specific property trees without causing race conditions
- Allow multiple instances of the scripting interpreter to be instantiated, so that these can run in different threads - e.g. with aircraft/scenery scripts running separately from GUI or weather/environmental scripts.