Directives for choosing the best course or for determining success
An application or library should be easily portable, avoiding conditional compilation that isn't behind some portable abstraction.
There should be no need for special actions (such as compiling part of an application as a module) just for RISC OS. (I think that would annoy RISC OS-unaware maintainers of portable (or port-worthy) libraries and applications.)
The new environment should have little negative impact on current efficiency.
Well, it's not a disaster if that's what we end up with, but we want something still uniquely RISC OS, more than just a UNIX-like OS on an ARM chip.
We already have UNIX-like OSes on ARM.
Existing WIMP applications should continue to run, unaware of new capabilities.
We don't want old applications to have to be rewritten, and preferably not even re-compiled, just to continue working.
Existing taskwindow (and single-tasking) applications should continue to run, unaware of new capabilities.
We don't want old applications to have to be rewritten, and preferably not even re-compiled, just to continue working.
Every application automatically executes as a (still non-pre-emptive) task — as soon as it calls the kernel with certain blocking calls, the kernel should allow it to be swapped out.
The Wimp_Initialise operation should simply
indicate participation in the GUI.
These two functions should not be conflated, as they are in the current WIMP system. This conflation complicates “Application/library portability”.
It should not be necessary to write some parts of an application as a module just to deal with certain timeliness issues, like delivery of data to a sound buffer.
This supports “Application/library portability”. Maintaining a component of a port-worthy library in a manner specific to a ?cult? operating system complicates the over-all maintenance, discouraging support for that OS. On the other hand, if the component doesn't have to be written as a module, the library becomes more portable as the maintenance for different operating systems converges.
The set of subsystems is not fixed (although some may be well-known). New subsystems will register when they are loaded (as modules).
We cannot predict what subsystems will exist in the future. Consider how OS_ReadC services callbacks while idle, but Wimp_Poll(Idle) initially did not — the ability to service callbacks should be part of a common subsystem interface which new unforeseen subsystems can take advantage of.
The goal of “Decoupling of GUI and multitasking/context-switching” is accomplished by making the GUI a distinct subsystem, with a position no more special than any other.
Subsystems are presented with an interface to allow them to indicate when they are blocking on behalf of a thread, or resuming control. They do not have to deal with applications that block on multiple resources at once.
It should be straight-forward to design and implement a new subsystem such that it can provide blocking operations without blocking the entire system.
This supports “Extensible subsystem space”, “Application-level timeliness” and “Decoupling of GUI and multitasking/context-switching”.
In general, a subsystem should be able to associate context (defined by that subsystem) with each process, accessible automatically when that process enters that subsystem. Each subsystem simply asks ?Where's my data for the current caller??, perhaps by supplying a handle assigned to it for the duration of the machine's runtime.
If necessary, a subsystem should also be able to be informed when a process is switched, which would be useful to managing shared memory.
This supports “Extensible subsystem space” and “Shared-memory support”.
Subsystems should be able to be informed when a process, with which they have associated context, forks, so that they can duplicate the context. Similarly, they should be informed of exiting processes, in order to delete redundant context and tidy up.
Forking (combined with exec and duplicated file
descriptors) is a powerful paradigm for process generation —
and may support “Application/library portability”.
It's also part of “Generic subsystem context
switching”.
By ?native?, we mean that the system itself supports threading; it is not merely possible within a process (e.g. as a lightweight library).
It should be possible for control to leave a process via one thread, and return by another; or, to put it another way, one thread blocking on a system call should not block the entire process. This supports “Application-level timeliness”.
It also supports “Application/library portability” by having a thread implementation available.
New applications should be able to declare themselves as pre-emptible. (Applications should not be forced to be pre-emptible, until all legacy applications have been replaced. And even then…)
We would be relying on non-pre-emptible tasks being very well behaved, which is what we do anyway.
The voluntary aspect supports “Backward compatibility with WIMP” and “Backward compatibility with taskwindow applications”. The possibility of pre-emption supports “Application-level timeliness”.
The context switcher should be able to cope with several processors using it, allowing each to have its own ?current context?. Although this goal is at a low priority, it should be considered in the definition of the various SWI and SVC interfaces, such that it is not prevented in a future implementation.
Since ARM speeds always seem to be somewhat behind x86 machines, multiple ARMs sharing the load might allow the more intensive applications to be used.