Multi-Tasking with RISC OS (Part 2)

David Spencer concludes our introduction to the RISC OS multi-tasking system by looking at it from a programmer's point of view.

Before explaining how the multi-tasking system works, we need to understand the interaction between the Window Manager and a program running in a WIMP environment. The key to this is a technique called polling.

The program must regularly call a routine in the Window Manager (via a SWI call) known as the polling routine. The Window Manager uses this opportunity to perform any of its own processing, such as redrawing a drag box, and then returns a reason code to the program. This reason code informs the program of any actions that the Window Manger requires it to perform. For example, if a reason code of 3 was returned, then this would mean that the user had clicked on the 'Quit' box of an open window. Before performing any other actions, the program must find out which window is to be closed, and ask the Window Manager to close it.

Similarly, a reason code of 1 means that a window needs redrawing (perhaps because a window that was on top has been closed), while a reason code of 8 signifies that the user has pressed a key. A reason code of 0 means that the Window Manager doesn't want any actions performing at that point, and the program is free to do any processing of its own, for example updating the display. Whatever the reason code returned from the polling routine, as soon as the program has performed the necessary action, it must return to the loop that performs the polling.

The net outcome of the polling system is that control is bounced backwards and forwards between the application program and the Window Manager. To achieve multi-tasking all that is necessary is for the Window Manager to pass control to each application in turn. This is shown graphically in the diagram, which illustrates the multi-tasking of six applications. We will take as a starting point the situation where App.1 is about to call the polling routine. App.1 calls the Window Manager, much in the same way as would happen in a single task situation. However, when the Window Manager has finished its processing, rather than returning to App.1, it instead passes control to App.2, which performs any necessary actions and duly calls the polling routine again. Subsequently, control is passed to App.3, and then App.4 and so on. Finally, when App.6 calls the polling routine, the Window Manager will pass control back to App.1, with whatever reason code applies to App.1 at that time.

As far as App.1 is concerned, it has called the Window Manager's polling routine, and the Window Manager has eventually returned a reason code back to it. App.1 is totally unaware of the fact that six other applications have been activated one after another, while it was waiting for the routine to return. Had we considered how any of the other five applications viewed what was happening, the situation would be unchanged. As far as each application is concerned, it is the only one running.

Therefore, we have achieved our aim of a multi-tasking system with very little effort. It should also be clear now why the Window Manager plays such an important role in multi-tasking, and why all multi-tasked applications run in a WIMP environment.

MEMORY ALLOCATION

In a multi-tasking system it is important to control the allocation and use of memory. All applications running under RISC OS expect to have a contiguous area of RAM starting at address &8000 to use as workspace. In the case of applications loaded from a file, they actually load at this address and then use the memory above them as workspace. Module based applications, such as Basic, are free to use all the application memory as workspace.

The amount of application workspace available overall is not set directly. Instead, all the RAM left over after the areas have been allocated for the screen, modules, sprites, etc. is used as application workspace. In a single-tasking environment, only one application is active at a time, and consequently, all the application workspace is allocated to this application.

The WIMP polling system

The WIMP polling system

In a multi-tasking environment, the situation is more complicated. The Task Manager maintains a pool of free memory, out of which, memory can be allocated to tasks. A certain quantity of this memory is made available to the next application that is started. The user can change this allocation via the task display window. When a new application is loaded it uses a star command to tell the task manager the minimum amount of memory it requires, and the maximum that it could use if more was available. Provided that the memory set aside for the next task is enough, the application will be started and allocated the appropriate amount of workspace. Some applications can change the amount of memory they have while they are running. They do this by claiming more memory from the free pool when needed, and returning it when it is no longer required. An example of this type of application is ArcEdit on the Welcome disc. When an application is re-moved, its memory is returned to the free pool.

It is all very well to allocate self contained blocks of memory to each application, but there still remains the problem of ensuring that whenever an application is actually executing, its workspace lies in a block from location &8000 upwards. One obvious way would be to copy the workspace of the current application to somewhere else, copying the workspace for the next application down to &8000, and then finally executing the next application. However, even with the speed of the ARM, copying a large amount of memory wastes a lot of time.

Luckily, MEMC, the ARM memory controller chip, provides a far more elegant solution. Instead of mapping addresses directly to locations within the physical RAM, MEMC supports a concept known as logical memory. The actual physical memory is split up into 128 pages. Therefore, on a 310, each page is 8K long, while on a 440 it is 32K. A 305 keeps a page size of 8K and only uses 64 pages, rather than having a 4K page size. For each page of physical memory, it is possible to define where it appears in the memory map of the ARM processor. The mapping between the logical processor addresses and the actual physical addresses is controlled by an area of very fast memory within MEMC called a Content Addressable Memory (CAM). It is by using this technique that RISC OS arranges for the areas of RAM allocated to the screen, sprites, etc. to start at well-defined addresses.

However, the ability to change the address at which a page of memory appears is perfectly suited to the task of moving application memory. When switching from one application to another, RISC OS changes the contents of the CAM so that the current application's workspace is remapped to an address that is out of the way of anything else. The RAM pages that belong to the next application are then located using a table kept by the Window Manager, and the CAM is further changed so that these pages are mapped from address &8000 upwards. This achieves the effect of moving around large amounts of memory by only altering a few locations within the CAM. Furthermore, MEMC also allows pages of memory to be protected, and RISC OS ensures that all application memory not in use at that time is protected so that it cannot be written to. This means there is less likelihood of one application accidentally corrupting the workspace belonging to another.

This ends our introductory look into the world of multi-tasking, but we will return to the subject in future issues of RISC User.