Migration Tutorial: Demand Paging

Demand paging is a change to how the Kernel can use RAM from Symbian platform v9.3. This topic describes the possible results for base port.

When demand paging is used, the contents of memory are available to a program when they are required - i.e. 'on demand'. When the contents are no longer required, the RAM can be used for other content. In this way, the total RAM required to store content is less than if it were all permanently available.

The Device Driver Guide provides Suggested techniques for mitigating the effects of demand paging for writers of device drivers. These recommendations can result in a more ‘multithreaded’ base-port. This may have the following impact that needs to be considered:

  • A base-port component may provide services to device drivers, exposing to them a shared resource; either hardware or software:

    • hardware - may be a hardware controller whose non-instantaneous operation, once initiated, cannot be disturbed until it completes

    • software - may be a list of requests for services.

  • A hardware component has a control interface that can be used by a number of drivers. Operations on the control interface although near instantaneous, are not atomic and cannot be interrupted.

In the case of the base-port component, when the state of a resource needs to be protected from the effects of pre-emption for a non-negligible period of time, the recommended approach is to use mutual exclusion, protecting the resource with a mutex: unless there is any chance that the same driver may trigger the same operation before the previous one completed. For example, when operations are non-blocking and happen in a context different from the initiator’s, a NFastMutex should suffice.

An example of the hardware component situation is a set-clear control interface, where a pair of registers (one containing the bits to be set, the other the bits to be cleared) have to be written to produce the desired change. If the operation is pre-empted after bits are set but before they are cleared for a desired final output, and a new set-clear operation is initiated, the final state of the interface may be undetermined. Pre-emption protection in this case is achieved by simply locking the Kernel using NKern::Lock() before the operation starts and unlocking it with NKern::Unlock() after it completes. If the interface is to be used from an interrupt context disabling all interrupts is sufficient to protect against thread concurrency.