Symbian3/PDK/Source/GUID-30CAE438-6CC7-5532-8727-781B8E83574A.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Fri, 22 Jan 2010 18:26:19 +0000
changeset 1 25a17d01db0c
child 3 46218c8b8afa
permissions -rw-r--r--
Addition of the PDK content and example code for Documentation_content according to Feature bug 1607 and bug 1608

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-30CAE438-6CC7-5532-8727-781B8E83574A" xml:lang="en"><title>Heap
Locking in the Font and Bitmap Server </title><shortdesc>The Font and Bitmap Server's heap locking API is deprecated in
Symbian OS v9.3 and later versions. This topic explains the rationale for
this and how it affects existing applications that use the <codeph>CFBsBitmap::LockHeap()</codeph>, <codeph>CFBsBitmap::LockHeapLC()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> functions. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section><title>Heap locking in previous versions </title> <p>Prior to Symbian
OS v9.3, the Font and Bitmap Server made a distinction between small bitmaps
and large bitmaps. The data for large bitmaps was stored in a separate global
memory heap where a de-fragmentation algorithm was used. When necessary, this
algorithm moved bitmap data in the virtual address space. As a result it was
possible for an application to allocate a new bitmap and trigger the de-fragmentation
algorithm while an unrelated application accessed the data of another bitmap.
From an application's point of view, this meant that the value returned by <codeph>CFbsBitmap::DataAddress()</codeph> could
change unpredictably at any time. </p> <p>The solution was to lock the global
memory heap by calling <codeph>CFbsBitmap::LockHeap()</codeph> or <codeph>CFbsBitmap::LockHeapLC()</codeph> before
calling <codeph>CFbsBitmap::DataAddress()</codeph>. When the application finished
accessing the bitmap data, it unlocked the global memory heap by calling <codeph>CFbsBitmap::UnlockHeap().</codeph> Internally
the Font and Bitmap Server used a global mutual exclusion object to implement
the heap locking functions and waited on it before performing any operation
that could trigger the de-fragmentation algorithm. </p> <p>Although it was
undocumented functionality, multi-threaded applications could use the heap
locking functions as a way of synchronizing access to bitmaps shared among
several threads, because calls to <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> translated
into <codeph>Wait()</codeph> and <codeph>Signal()</codeph> operations on the
global mutual exclusion object. </p> </section>
<section><title>Removal of heap locking </title> <p><b>Use of a disconnected
memory chunk </b> </p> <p>From Symbian OS v9.3, all bitmap data is kept in
a disconnected global memory chunk. This is a new type of chunk that does
not require the set of pages committed to physical memory to form a contiguous
block in the virtual address space. A virtual address range much bigger than
the amount of physical memory is reserved, and pages are committed to physical
memory when allocating bitmaps and de-committed when freeing them. </p> <p>As
a result, fragmentation in the reserved virtual address range is not a problem
and fragmentation in the physical address space is handled transparently by
the Memory Management Unit (MMU). Therefore, de-fragmentation is not necessary
and bitmap operations do not need to move data belonging to other bitmaps. </p> <p><b>Removal
of in-place operations </b> </p> <p>Some bitmap operations, such as <codeph>CFbsBitmap::Resize()</codeph>, <codeph>CFbsBitmap::Compress()</codeph> and <codeph>CFbsBitmap::CompressInBackground()</codeph>, can change the
value returned by <codeph>CFbsBitmap::DataAddress()</codeph> because they
may need to re-allocate memory. These functions have a new implementation.
They now create a new bitmap object inside the Font and Bitmap Server and
update the reference contained in the <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> object.
The old bitmap is destroyed immediately if it is referenced only by the <codeph>CFbsBitmap</codeph> object
on which the re-allocating function was called. Otherwise, the old bitmap
is flagged as <b>dirty</b> and its destruction is deferred until its reference
count becomes zero. </p> <p>All of the functions in the <codeph>CFbsBitmap</codeph> class
now check whether the referenced bitmap is dirty before proceeding. If it
is, the Font and Bitmap Server updates the reference to point to the new bitmap.
When all of the <codeph>CFbsBitmap</codeph> objects that referenced the old
bitmap have had their references updated or have been deleted, the reference
count of the old bitmap becomes zero and it is destroyed. </p> <p>The impact
on performance of this change is negligible, because the dirty flag is tested
in the context of the client thread and in most cases bitmaps are "clean". </p> <p>Sometimes
multiple <codeph>CFbsBitmap</codeph> objects in different client threads reference
the same bitmap. When a client thread calls a re-allocating function on a
bitmap while another client thread is accessing the bitmap data through a
pointer returned by <codeph>CFbsBitmap::DataAddress()</codeph>, there is no
illegal memory access because the old bitmap still exists. This scenario typically
occurs when an application calls <codeph>CFbsBitmap::CompressInBackground()</codeph> on
a bitmap and continues to use it, because the compression is performed asynchronously
at an unspecified time. </p> <p><b>Deprecation of the heap locking functions </b> </p> <p>The
use of a disconnected memory chunk and the removal of in-place operations
allow the Font and Bitmap Server to work without heap locking. Therefore, <codeph>CFbsBitmap::LockHeap()</codeph>, <codeph>CFbsBitmap::UnlockHeap()</codeph> and <codeph>CFbsBitmap::LockHeapLC()</codeph> are no longer necessary and
have been deprecated.<b> These functions no longer provide any locking functionality
and cannot be used as a  synchronization mechanism</b>. </p> <p>It is recommended
that you replace all calls to <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> with
calls to the new functions <codeph>CFbsBitmap::BeginDataAccess()</codeph> and <codeph>CFbsBitmap::EndDataAccess()</codeph>.
If necessary also add a mutual exclusion object to multi-threaded applications.
Although not strictly necessary, calling <codeph>CFbsBitmap::BeginDataAccess()</codeph> and <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita#GUID-683A1D42-2764-3EB7-BD19-9E12559199AB/GUID-0C2D1B5F-46A8-32A1-9558-24BC8A413258"><apiname>CFbsBitmap::EndDataAccess()</apiname></xref> ensures
optimum performance in platforms with graphics hardware acceleration. </p> <p>For
the benefit of legacy applications that do not require changes, <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> now simply call <codeph>CFbsBitmap::BeginDataAccess()</codeph> and <codeph>CFbsBitmap::EndDataAccess()</codeph>,
respectively. </p> <p>Any number of client threads can now call <codeph>CFbsBitmap::DataAddress()</codeph> and
manipulate bitmap data at the same time. This does not cause a problem provided
each client thread accesses a different bitmap. If a multi-threaded application
shares a bitmap among several threads and assumes that <codeph>CFbsBitmap::LockHeap()</codeph> is
implemented as a <codeph>Wait()</codeph> operation on a mutual exclusion object,
you may need to modify the application. </p> <p><b>The impact of the change
on existing applications </b> </p> <p>The old documentation was ambiguous
about several aspects of the semantics of the heap locking API. However, because
the actual implementation used a global mutual exclusion object, it was possible
for a client thread to call <codeph>CFbsBitmap::LockHeap()</codeph> and prevent
any other client thread that called <codeph>CFbsBitmap::LockHeap()</codeph> from
proceeding. This included client threads that attempted to access the same
bitmap and totally unrelated client threads. Therefore, the heap locking API
may have been used as a synchronisation mechanism in multi-threaded applications.
This is no longer possible. </p> <p>The <xref href="GUID-B18430C6-0FC1-3EE6-AC5C-A30B6AE88217.dita"><apiname>SYMBIAN_DEBUG_FBS_LOCKHEAP</apiname></xref> macro
can be used to help detect multi-threaded applications that share a bitmap
among several threads and fail to provide their own mutual exclusion mechanism.
When this macro is defined in debug builds of the Font and Bitmap Server, <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> check whether more than one client thread has a call to <codeph>CFbsBitmap::LockHeap()</codeph> on
the same bitmap at the same time without a corresponding call to <codeph>CFbsBitmap::UnlockHeap()</codeph>.
When this is detected, a panic FBSCLI 22 is raised. </p> <p>The impact of
the change on existing multi-threaded applications that use the heap locking
API as a synchronisation mechanism is reduced, in most of the cases, to the
possibility of loss of bitmap data changes rather than illegal memory access
or any other kind of abnormal termination. An exception is the case of existing
multi-threaded applications that use the heap locking API as a synchronisation
mechanism where one thread calls <codeph>CFbsBitmap::Resize()</codeph> on
a bitmap while another thread calls <codeph>CFbsBitmap::SizeInPixels()</codeph> followed
by <codeph>CFbsBitmap::DataAddress()</codeph> on the same bitmap. This can
produce an incorrect value for the size in pixels and lead to an illegal memory
access. </p> </section>
</conbody><related-links>
<link href="GUID-71DADA82-3ABC-52D2-8360-33FAEB2E5DE9.dita"><linktext>Font and
Bitmap Server Overview</linktext></link>
<link href="GUID-90644B52-69D7-595C-95E3-D6F7A30C060D.dita"><linktext>Font and
Text Services Collection  Overview </linktext></link>
</related-links></concept>