Rejk, I apologise for making you boggle. I am looking at this from a “computer science” point of view and I think you are looking at it from a C/C++ programming point of view. I wasn’t trying to teach you to suck eggs, I was pointing out that “fork” and “copy on write” are not synonymous. RISC OS does not need to do copy on write in order to fork, it just means that the memory will always be allocated, even if the child does nothing. I think you are looking at fork() as a C function, I am suggesting the CONCEPT can be applied to other problems. Similarly, I think you are looking at threads in terms of C/C++ library functions, so their implementation is invisible to you as a programmer. But for two threads to run on two processor cores, the kernel needs to be have allocated the cores to those threads.
Druck, I would have to dig out my old PRMs from the loft to answer your questions properly, but I’ll try to explain what I have in mind for now. There are two different concepts here. The first, forking, is a suggestion for a methodology to allow the OS to run existing application simultaneously by allocating separate applications to separate cores. The second, “Wimp_Poll idea” is a suggestion for 1:1 multithreading of an application.
With regard to the question, “how can you split the API from the OS?” Would it make any difference if I used the term “API layer”, meaning a layer of software which began at the API and reached to various extents within the OS? Depending on the modularity of the OS, this could simply mean putting one module in the API layer, and another outside. It might be possible to implement some features using pre and post filtering, and some features will have to be completely rewritten.
So, for example, if we were able to intercept the calls to enumerate a directory, and store the context within the API layer, we can work around the problem. If an SWI causes only the core it was issued on to switch context (and I think that must be so), then we can intercept any call we choose within the API layer.
As for the Wimp_Poll idea, getting one task to run on multiple cores would require some rewriting of applications. Given that much of the available software is no longer maintained by original authors, I think it might be worthwhile concentrating on a single, well understood, part of the application; the Wimp_Poll loop, and its associated data. In 1:1 multithreading, the OS is aware of all a task’s threads and schedules them directly. I can see that allowing two threads to simultaneously access the same object (a window, for example) could cause problems, but there are ways around that. You have already mentioned semaphores and mutexes. Semaphores could be implemented as global task data. Mutexes are a little more complicated, but perhaps event handlers which were related to a single object (eg codes 1-6 etc) could call some sort of locking routine before dropping into the existing code.
I’m not going to claim that either of these suggestions is the best way forward; It may be necessary to intercept every call to the OS in order to have a forked API layer (too costly). But if there is a shortage of resources to rewrite all the applications and all of the OS, I think any methodology would be worth considering.