|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-30CAE438-6CC7-5532-8727-781B8E83574A" xml:lang="en"><title>Heap |
|
13 Locking in the Font and Bitmap Server </title><shortdesc>The Font and Bitmap Server's heap locking API is deprecated in |
|
14 Symbian OS v9.3 and later versions. This topic explains the rationale for |
|
15 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> |
|
16 <section><title>Heap locking in previous versions </title> <p>Prior to Symbian |
|
17 OS v9.3, the Font and Bitmap Server made a distinction between small bitmaps |
|
18 and large bitmaps. The data for large bitmaps was stored in a separate global |
|
19 memory heap where a de-fragmentation algorithm was used. When necessary, this |
|
20 algorithm moved bitmap data in the virtual address space. As a result it was |
|
21 possible for an application to allocate a new bitmap and trigger the de-fragmentation |
|
22 algorithm while an unrelated application accessed the data of another bitmap. |
|
23 From an application's point of view, this meant that the value returned by <codeph>CFbsBitmap::DataAddress()</codeph> could |
|
24 change unpredictably at any time. </p> <p>The solution was to lock the global |
|
25 memory heap by calling <codeph>CFbsBitmap::LockHeap()</codeph> or <codeph>CFbsBitmap::LockHeapLC()</codeph> before |
|
26 calling <codeph>CFbsBitmap::DataAddress()</codeph>. When the application finished |
|
27 accessing the bitmap data, it unlocked the global memory heap by calling <codeph>CFbsBitmap::UnlockHeap().</codeph> Internally |
|
28 the Font and Bitmap Server used a global mutual exclusion object to implement |
|
29 the heap locking functions and waited on it before performing any operation |
|
30 that could trigger the de-fragmentation algorithm. </p> <p>Although it was |
|
31 undocumented functionality, multi-threaded applications could use the heap |
|
32 locking functions as a way of synchronizing access to bitmaps shared among |
|
33 several threads, because calls to <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> translated |
|
34 into <codeph>Wait()</codeph> and <codeph>Signal()</codeph> operations on the |
|
35 global mutual exclusion object. </p> </section> |
|
36 <section><title>Removal of heap locking </title> <p><b>Use of a disconnected |
|
37 memory chunk </b> </p> <p>From Symbian OS v9.3, all bitmap data is kept in |
|
38 a disconnected global memory chunk. This is a new type of chunk that does |
|
39 not require the set of pages committed to physical memory to form a contiguous |
|
40 block in the virtual address space. A virtual address range much bigger than |
|
41 the amount of physical memory is reserved, and pages are committed to physical |
|
42 memory when allocating bitmaps and de-committed when freeing them. </p> <p>As |
|
43 a result, fragmentation in the reserved virtual address range is not a problem |
|
44 and fragmentation in the physical address space is handled transparently by |
|
45 the Memory Management Unit (MMU). Therefore, de-fragmentation is not necessary |
|
46 and bitmap operations do not need to move data belonging to other bitmaps. </p> <p><b>Removal |
|
47 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 |
|
48 value returned by <codeph>CFbsBitmap::DataAddress()</codeph> because they |
|
49 may need to re-allocate memory. These functions have a new implementation. |
|
50 They now create a new bitmap object inside the Font and Bitmap Server and |
|
51 update the reference contained in the <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> object. |
|
52 The old bitmap is destroyed immediately if it is referenced only by the <codeph>CFbsBitmap</codeph> object |
|
53 on which the re-allocating function was called. Otherwise, the old bitmap |
|
54 is flagged as <b>dirty</b> and its destruction is deferred until its reference |
|
55 count becomes zero. </p> <p>All of the functions in the <codeph>CFbsBitmap</codeph> class |
|
56 now check whether the referenced bitmap is dirty before proceeding. If it |
|
57 is, the Font and Bitmap Server updates the reference to point to the new bitmap. |
|
58 When all of the <codeph>CFbsBitmap</codeph> objects that referenced the old |
|
59 bitmap have had their references updated or have been deleted, the reference |
|
60 count of the old bitmap becomes zero and it is destroyed. </p> <p>The impact |
|
61 on performance of this change is negligible, because the dirty flag is tested |
|
62 in the context of the client thread and in most cases bitmaps are "clean". </p> <p>Sometimes |
|
63 multiple <codeph>CFbsBitmap</codeph> objects in different client threads reference |
|
64 the same bitmap. When a client thread calls a re-allocating function on a |
|
65 bitmap while another client thread is accessing the bitmap data through a |
|
66 pointer returned by <codeph>CFbsBitmap::DataAddress()</codeph>, there is no |
|
67 illegal memory access because the old bitmap still exists. This scenario typically |
|
68 occurs when an application calls <codeph>CFbsBitmap::CompressInBackground()</codeph> on |
|
69 a bitmap and continues to use it, because the compression is performed asynchronously |
|
70 at an unspecified time. </p> <p><b>Deprecation of the heap locking functions </b> </p> <p>The |
|
71 use of a disconnected memory chunk and the removal of in-place operations |
|
72 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 |
|
73 have been deprecated.<b> These functions no longer provide any locking functionality |
|
74 and cannot be used as a synchronization mechanism</b>. </p> <p>It is recommended |
|
75 that you replace all calls to <codeph>CFbsBitmap::LockHeap()</codeph> and <codeph>CFbsBitmap::UnlockHeap()</codeph> with |
|
76 calls to the new functions <codeph>CFbsBitmap::BeginDataAccess()</codeph> and <codeph>CFbsBitmap::EndDataAccess()</codeph>. |
|
77 If necessary also add a mutual exclusion object to multi-threaded applications. |
|
78 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 |
|
79 optimum performance in platforms with graphics hardware acceleration. </p> <p>For |
|
80 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>, |
|
81 respectively. </p> <p>Any number of client threads can now call <codeph>CFbsBitmap::DataAddress()</codeph> and |
|
82 manipulate bitmap data at the same time. This does not cause a problem provided |
|
83 each client thread accesses a different bitmap. If a multi-threaded application |
|
84 shares a bitmap among several threads and assumes that <codeph>CFbsBitmap::LockHeap()</codeph> is |
|
85 implemented as a <codeph>Wait()</codeph> operation on a mutual exclusion object, |
|
86 you may need to modify the application. </p> <p><b>The impact of the change |
|
87 on existing applications </b> </p> <p>The old documentation was ambiguous |
|
88 about several aspects of the semantics of the heap locking API. However, because |
|
89 the actual implementation used a global mutual exclusion object, it was possible |
|
90 for a client thread to call <codeph>CFbsBitmap::LockHeap()</codeph> and prevent |
|
91 any other client thread that called <codeph>CFbsBitmap::LockHeap()</codeph> from |
|
92 proceeding. This included client threads that attempted to access the same |
|
93 bitmap and totally unrelated client threads. Therefore, the heap locking API |
|
94 may have been used as a synchronisation mechanism in multi-threaded applications. |
|
95 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 |
|
96 can be used to help detect multi-threaded applications that share a bitmap |
|
97 among several threads and fail to provide their own mutual exclusion mechanism. |
|
98 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 |
|
99 the same bitmap at the same time without a corresponding call to <codeph>CFbsBitmap::UnlockHeap()</codeph>. |
|
100 When this is detected, a panic FBSCLI 22 is raised. </p> <p>The impact of |
|
101 the change on existing multi-threaded applications that use the heap locking |
|
102 API as a synchronisation mechanism is reduced, in most of the cases, to the |
|
103 possibility of loss of bitmap data changes rather than illegal memory access |
|
104 or any other kind of abnormal termination. An exception is the case of existing |
|
105 multi-threaded applications that use the heap locking API as a synchronisation |
|
106 mechanism where one thread calls <codeph>CFbsBitmap::Resize()</codeph> on |
|
107 a bitmap while another thread calls <codeph>CFbsBitmap::SizeInPixels()</codeph> followed |
|
108 by <codeph>CFbsBitmap::DataAddress()</codeph> on the same bitmap. This can |
|
109 produce an incorrect value for the size in pixels and lead to an illegal memory |
|
110 access. </p> </section> |
|
111 </conbody><related-links> |
|
112 <link href="GUID-71DADA82-3ABC-52D2-8360-33FAEB2E5DE9.dita"><linktext>Font and |
|
113 Bitmap Server Overview</linktext></link> |
|
114 <link href="GUID-90644B52-69D7-595C-95E3-D6F7A30C060D.dita"><linktext>Font and |
|
115 Text Services Collection Overview </linktext></link> |
|
116 </related-links></concept> |