Multi-core RISC OS proposal

By Adrian Smith11 Jun 20101300 words6 mins to read

I was reading an article about the RISC OS operating system and the fact that it doesn't support multiple CPU cores. Then I got to thinking, how would one implement multi-CPU support on such an operating system?

Between 1989 and 1994 I used a British computer running the operating system RISC OS. This operating system is still alive, and is still in use. It was produced by Acorn Computers and runs on the ARM processor ("Acorn Risc Machine"), now found in many computing platforms such as the iPhone. It has many innovative features which haven't made it yet to other operating systems (although is the topic for a post of its own!)

Back then there was obviously no need to support multiple CPUs. So today one has the choice of either finding single-core CPUs (will become increasingly difficult) or using a multi-core CPU with all but one core inactive (which is a waste). Various fora speculate on the technical possibility or impossibility of utilizing the extra cores. I don't think it would be especially difficult. This article describes how I would go about it.

Constraints and information about RISC OS:

For me at least, I would say that the way the system currently operates on a single core is already very fast (when running at less than full speed via emulation on an x86 processor – it runs faster than it did on native hardware in the 1990s, it runs faster than Windows ran in the 1990s, and faster than Windows runs today.) So I think for most tasks, there is no need to use additional cores.

I am used to working in companies with limited human resources, and due to the fact that RISC OS isn't a mainstream operating system, I am going to assume that this would also be a constraint with any solution to introduce multi-core capabilities to RISC OS. That means a complete re-write of RISC OS and applications, or even visiting every single part of the operating system and introducing locking and the expectation that any function can be called at any time due to pre-emptive multi-tasking and simultaneous execution by multiple cores, is also out of the question.

So my solution would be to assume that those extra cores should do "pure CPU" work, for example video processing, rendering fractals, or other CPU-intensive work. All work like accessing the filesystem, interacting with the user, which is already fast enough, would not be given the opportunity to work even faster by being executed in parallel on multiple cores.

I would write a very simply layer, similar to a hypervisor, which would run under RISC OS, which would simply handle allocation of CPU and memory resources. This supervisor would allow processes to run, which would not share memory (and thus not need to support shared-memory primitives such as locking). Pipes would allow processes managed by the supervisor to communicate.

The first, and often the only process, which this supervisor would manage, would be the entire existing RISC OS and all applications. This process would manage the user-interface, network, filesystem, printers and communication between all running RISC OS applications. So this "RISC OS + applications" process would run largely unaltered from the existing software (saving much development time; but also providing no benefit in terms of speed increase).

But there would be an extra API available to applications to spawn new processes managed by the supervisor, which would execute asynchronously, and primitives to pass/receive messages from those spawned processes. The supervisor would run these processes on the different cores, and pre-emptively multi-task the processes in the case of more processes than cores.

I would take the approach to concurrency of "message-passing with no shared memory" as opposed to "shared memory (threads)" for two reasons:

I would allow "pipes" to be created between the processes and the pipes store an ordered set of "messages", each message is simply a bunch of bytes. RISC OS software is generally written in C so just passing the byte-contents of a "struct" is easy and convenient. (This is the Erlang philosophy: Facebook say "Erlang... approaches concurrency with three iron rules: no shared memory even between processes on the same computer, a standard format for messages passed between processes, and a guarantee that messages are read in the order in which they were received.")

This proposal has the following consequences:

Admittedly there although there is no performance loss, there is also no performance gain until apps are extended. However I think spending the work to add pre-emptive multi-tasking to RISC OS (a huge undertaking) simply isn't necessary: RISC OS works well as it is, and arguably is a lot more reliable (in terms of repeatable and therefore testable behaviour) due to its cooperative nature. The original designers of RISC OS could have created a pre-emptive multi-tasking operating system instead of RISC OS — the hardware supported it (RISC/iX ran on it) — but they actively decided not to do that.

See also:

This article was written by Adrian Smith on 11 Jun 2010

Follow me: Facebook | Twitter | LinkedIn | Email

More on: Algorithms | RISC OS | Operating Systems