Physical RAM Defragmentation

Describes Symbian platform RAM defragmentation.

Symbian platform physical RAM defragmentation is the process of moving physical pages, used to back virtual allocations, in order to create empty physical ranges. This enables the powering off of individual RAM banks or, if required, the allocation of a large contiguous buffer, for example, for a CCD image. This functionality allows a more efficient use of RAM in terms of both memory and power consumption.

Note: Symbian platform RAM defragmentation is used to create large areas of contiguous RAM and/or allow the powering down of surplus RAM ICs: it does not locate and consolidate fragmented files and folders. This functionality enables more efficient use of physical RAM and may enable a lower Bill Of Materials (BOM), or increase battery life.

There are two interrelated use cases for defragmenting physical RAM:

  • many device drivers require physical RAM for use for buffers. For example, a camera driver may require a physically contiguous buffer for holding the output of the CCD. In releases 9.3 and before such memory was typically allocated at boot time. This practice increases initial RAM consumption after boot. Total RAM consumption can be reduced if memory for such buffers is only allocated as required, rather than at boot time. It is not possible to provide an absolute guarantee that the RAM will be available when needed, but it should succeed in all but exceptional cases.

  • typically, memory consumption of a phone while idle is less than the total memory available. Idle and active power consumption can be decreased by powering down unused RAM chips or unused RAM banks within a RAM chip. This may also involve cooperation with a higher level component in the UI which can shut down unused applications to reclaim more memory.

Defragmention of RAM

TRamDefragRequest is the class used by device drivers to perform all defragmentation operations. The three defragmentation operations provided are:

There are three overloads for each of these TRamDefragRequest defragmentation methods which behave differently:

  • The first overload is synchronous and blocks the calling thread until the defragmentation is complete (or is cancelled using TRamDefragRequest::Cancel). In this case, the return value is the result of the defragmentation – an appropriate system-wide error code.

  • The second overload is asynchronous and takes a pointer to an NFastSemaphore. The semaphore is signalled when the defragmentation is complete. The return value is KErrNone unless there was a problem initializing the request, in which case an appropriate system-wide error code is returned. The result of the defragmentation can be obtained by calling TRamDefragRequest::Result() after the semaphore has been signalled.

  • The third overload is asynchronous and takes a DFC. The DFC is queued when the defragmentation is complete. The return value is KErrNone unless there was a problem initializing the request, in which case an appropriate system-wide error code is returned. The result of the defragmentation can be obtained by calling TRamDefragRequest::Result().

All TRamDefragRequest defragmentation operations are placed onto a FIFO queue. Any currently running defragmentation operation must complete or be cancelled before a new defragmentation operation can begin.

All the TRamDefragRequest defragmentation methods have the following parameter in common:

aPriority

aPriority specifies the priority of the thread that performs the defragmentation. If aPriority = KInheritPriority, the default, then the defragmentation thread will execute with the same priority as thread that invokes the defragmentation operation.

Determining the result of a defragmentation operation

For synchronous overloads of the defragmentation methods the error code returned by the defragmentation method can be used to determine the result of the defragmentation operation. KErrNone signifies that the defragmentation operation was successful.

For asynchronous overloads of the defragmentation methods the result of the defragmentation operation is determined by invoking TRamDefragRequest::Result() after it has signalled that it has completed. Again, KErrNone signifies that the defragmentation operation was successful.

Cancelling a defragmentation operation

A defragmentation operation can be cancelled by invoking the TRamDefragRequest::Cancel() method. This method cancels the defragmentation, if it is in progress or is in the queue, and causes it to complete with KErrCancel. If the defragmentation operation has already completed, this method has no effect and the result remains as it was.

General defragmentation

TRamDefragRequest::DefragRam() initiates a general defragmentation. A general defragmentation attempts to arrange the currently allocated pages so that only the minimum number and the most preferable RAM zones required are powered and refreshed. Each time the general defragmentation successfully empties a RAM zone the base port invokes the RAM zone call back function with aOp = ERamZoneOp_PowerDown see RAM zone call back function. This informs the base port that it can decide to, not refresh or power down the empty RAM zone when it deems it to be appropriate.

Depending on the current state of the system and the value of aMaxPages, a general defragmentation may require a significant amount of time to complete. Therefore, if a general defragmentation is performed too frequently the power saving benefits achieved by powering down or not refreshing RAM zones, may prove to be less than the power consumed while performing the general defragmentation. It is recommended that a general defragmentation is only performed once the device has been idle for a significant period of time.

aMaxPages

TRamDefragRequest::DefragRam() is similar to the other defragmentation methods, except that it has an additional parameter aMaxPages. aMaxPages specifies a limit on the number of pages that can be moved during a general defragmentation when set to zero there is no limit. This can be useful in limiting the amount of processing a general defragmentation performs and therefore the power consumed by the general defragmentation. However, setting aMaxPages too low may prevent the general defragmentation from being able to empty a single RAM zone despite there being enough free pages in the most preferable RAM zones.

RAM defragmentation of Physically contiguous allocations

Some devices may define RAM Zones for use by particular applications or hardware peripherals requiring a block of physically contiguous RAM. TRamDefragRequest::ClaimRamZone() is used by the device driver when it requires use of the pre-determined RAM zone to be used for the block of physically contiguous RAM.

TRamDefragRequest::ClaimRamZone() is similar to the other defragmentation methods, except that it has two extra parameters:

  • aId – the ID of the RAM zone to be claimed.

  • aPhysAddr – on successful completion of the claim operation this is loaded with the physical base address of the claimed RAM zone.

Once a RAM zone has been successfully claimed its memory can be used by the device driver after being mapped into a shared chunk. When the claimed RAM zone is no longer required, the device driver must use Epoc::FreePhysicalRam to release it for use by the rest of the system.

Zone specific allocations

A device driver may attempt to allocate memory from a specific RAM zone using Epoc::ZoneAllocPhysicalRam(). If the allocation fails then use TRamDefragRequest::EmptyRamZone() to remove as many pages as is reasonable from the RAM zone.

TRamDefragRequest::EmptyRamZone() is similar to the other defragmentation methods, as described in Defragmention of RAM, except that it has an extra parameter:

  • aId – the ID of the RAM zone to be emptied.

Once the empty defragmentation operation has completed the RAM zone specific allocation can be attempted again. However, the RAM zone specific allocation may still fail in high RAM usage situations or if the RAM zone has too many fixed pages allocated.