--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/PDK/Source/GUID-821C254A-40C6-45F9-B2F9-2CF28CAEB8CC.dita Fri Jan 22 18:26:19 2010 +0000
@@ -0,0 +1,82 @@
+<?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-821C254A-40C6-45F9-B2F9-2CF28CAEB8CC" xml:lang="en"><title>Interrupt
+Handling</title><shortdesc>Describes how interrupts are handled in the SMP environment.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>An interrupt is a signal from a hardware device or from an executable which
+causes a CPU to suspend normal execution, enter the interrupt handling state
+and jump to an interrupt handler. An interrupt handler, or ISR (interrupt
+service routine), schedules a DFC (delayed function call) on a DFC queue.</p>
+<section id="GUID-71D802FC-9A50-4BEB-8F21-497A7D04C814"><title>SMP-Safe Interrupt
+Handling</title><p>Interrupt handlers are used to implement the functionality
+of device drivers.</p><p>When a DFC executes on a unicore system, it disables
+interrupts to avoid clashing with its own ISR. </p><p>On a multicore system
+this is not sufficient to maintain data integrity. To maintain data integrity
+on an SMP system the code must:</p><ol>
+<li id="GUID-9A9C8A79-D53C-4B39-B108-86A0B04FCBE9"><p> acquire a spin lock
+on any data to be written, to block other cores from accessing the data.</p></li>
+<li id="GUID-87F5A9E5-2932-4BE8-8126-ECC1D4458476"><p>Interrupts must be disabled,
+as on unicore, before the spin lock is acquired.</p></li>
+</ol><p> Although these are conceptually two separate tasks, you use the spin
+lock API <xref href="GUID-FB1605A8-9946-364C-A649-DEF60E1F761B.dita"><apiname>TSpinLock</apiname></xref> in <filepath>nkern.h</filepath> to perform
+both tasks at the same time.</p><p>The following macros provide SMP-safe interrupt
+handling in most situations.</p><ul>
+<li><p><xref href="GUID-DBC27EF9-9C56-3FE8-B93C-BA2A74E1E6E6.dita"><apiname>__SPIN_LOCK_IRQSAVE</apiname></xref></p></li>
+<li><p><xref href="GUID-04EEFC44-C7FF-37D2-A8F1-7FBCDBAF9EE2.dita"><apiname>__SPIN_LOCK_IRQRESTORE</apiname></xref></p></li>
+</ul><p>If code using these macros is executed on a unicore system, they will
+disable interrupts in the normal way.</p><p>There are several other macros
+that can be used in the non standard situations or when you require greater
+control over the ordering of the delayed function call.</p><ul>
+<li><p><xref href="GUID-A6C6CADA-1552-3873-89BA-6DBDC6402FF2.dita"><apiname>__SPIN_LOCK_IRQSAVE(lock)</apiname></xref></p><p>Standard SMP-safe
+macro</p></li>
+<li><p><xref href="GUID-E7AB9188-3C0C-3267-96CF-751FD7C778EF.dita"><apiname> __SPIN_UNLOCK_IRQRESTORE(lock,irq)</apiname></xref></p><p>Standard
+SMP-safe macro</p></li>
+<li><p> <xref href="GUID-8E0151AC-1F70-35BE-9DBA-659C3054C8FA.dita"><apiname>__SPIN_FLASH_IRQRESTORE(lock,irq)</apiname></xref></p></li>
+<li><p><xref href="GUID-33E2A493-8F2F-32C1-A93C-A50F358C8126.dita"><apiname> __SPIN_LOCK(lock) __SPIN_UNLOCK(lock)</apiname></xref></p></li>
+<li><p><xref href="GUID-A9CDB15E-D435-3043-B9CA-265CC5C598DA.dita"><apiname> __SPIN_FLASH_PREEMPT(lock)</apiname></xref></p></li>
+<li><p> <xref href="GUID-5EF6D33D-998F-3BFD-95F1-478541221B35.dita"><apiname>__SPIN_LOCK_IRQ(lock)</apiname></xref></p></li>
+<li><p><xref href="GUID-F8FA6FEA-56A2-3924-BA59-8DF4B0546AC9.dita"><apiname> __SPIN_UNLOCK_IRQ(lock)</apiname></xref></p></li>
+<li><p> <xref href="GUID-E474AC45-13AE-3DE5-857C-7BE76EE084E3.dita"><apiname>__SPIN_FLASH_IRQ(lock)</apiname></xref></p></li>
+</ul><note><p> To ensure SMP Safety in Symbian^3, the kernel ensures that
+device driver, ISR and DFC are all tied to the same CPU. CPU0 has been stipulated
+for this purpose.</p></note></section>
+<section id="GUID-8BF9726E-B8E4-4558-98A4-7163CD13774A"><title>Making your
+device driver SMP safe</title><p>Once a device driver has been migrated to
+be SMP Safe using the advice above, the mmp file of each driver's binaries
+must be updated with the keyword <keyword>SMPSAFE</keyword>. As stated earlier,
+all kernel side threads and associated interrupts are locked to CPU0 for Symbian^3.
+Starting in Symbian^4 any binaries with <keyword>SMPSAFE</keyword> will be
+unlocked from CPU0 so they can be executed on any core. </p><p> <keyword>SMPSAFE</keyword> only
+has any effect when Compatibility Mode (see general impacts page) is being
+used. For interim testing of device driver migration, the CPU affinity API’s
+may be used to test driver thread migration. For example, </p><codeblock xml:space="preserve">NKern::ThreadSetCpuAffinity(NKern::CurrentThread(),KCpuAffinityAny);</codeblock></section>
+<example><p>In the following example, a spin lock protects memory being written
+by <codeph>DfcFun()</codeph> on CPU0 from corruption by <codeph>ISRFun()</codeph> running
+on a different core.</p><p>This code runs on CPU0:<codeblock xml:space="preserve">void DfcFun(TAny* aPtr)
+ {
+ …
+ irq = __SPIN_LOCK_IRQSAVE(iLock);
+ iState = EProcessed;
+ __SPIN_UNLOCK_IRQRESTORE(iLock,irq);
+
+ ...
+ }
+</codeblock></p><p>This code runs on a different core:<codeblock xml:space="preserve">void ISRFun(TAny* aPtr)
+ {
+ __SPIN_LOCK(iLock);
+ iState = EProcessing;
+ __SPIN_UNLOCK(iLock);
+ }
+</codeblock></p></example>
+</conbody><related-links>
+<link href="GUID-387E98B0-568D-4DBB-9A9E-616E41E96B58.dita"><linktext>SMP Overview</linktext>
+</link>
+</related-links></concept>
\ No newline at end of file