--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/PDK/Source/GUID-5B1D8D9C-90EF-5FCC-8D7D-01B13D6C2E68.dita Fri Jan 22 18:26:19 2010 +0000
@@ -0,0 +1,117 @@
+<?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-5B1D8D9C-90EF-5FCC-8D7D-01B13D6C2E68" xml:lang="en"><title>Nanokernel</title><shortdesc>The nanokernel is the core of the Kernel, and is a small real-time
+operating system (RTOS) designed to run Symbian platform.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>A <xref href="GUID-2700AAC8-A034-5E7D-B0E0-26B49E68BB18.dita">Personality Layer
+for Real Time Applications</xref> is a client of the nanokernel, and this
+topic is intended for writers of personality layers. </p>
+<section id="GUID-B8D8C73E-75CB-417D-A6DA-EE8B77A28256"><title>Nanokernel threads</title> <p>The fundamental unit of execution
+is the nanokernel thread, an <xref href="GUID-187D314F-1115-3671-AC46-37AEC5DFB2AC.dita"><apiname>NThread</apiname></xref> object. </p> <p>A
+nanokernel thread has an integer priority, between 0 and 63 inclusive, and
+is scheduled according to priority, the highest priority first. Equal priority
+threads are scheduled on either a round robin or a run-to-completion basis,
+selectable for each thread. For round robin scheduling, the time slice is
+selectable for each thread. </p> <p>Priority 0 is reserved for the system
+idle thread. </p> <p>Priorities 1-27 inclusive, and priority 48 are currently
+used by Symbian platform threads; 12 is the priority of the foreground Symbian
+platform application. There are, therefore, 35 distinct priorities that are
+totally unused and available for a real time application. </p> <p>Nanokernel
+threads may be created and destroyed dynamically, but the nanokernel does
+not do any memory management. Memory for both the thread object and the thread
+stack must be provided by the caller at create time. In fact the same rule
+applies throughout the nanokernel - all memory for dynamically created objects
+must be provided by the caller and freed by the caller after object destruction. </p> </section>
+<section id="GUID-45416245-24B2-40FA-98C2-94C29F94A200"><title>Nanokernel synchronisation</title> <p>The nanokernel provides
+the following synchronisation objects: </p> <ul>
+<li id="GUID-F94065EB-10A6-51A8-8B11-A0B887B994C6"><p>A fast semaphore, a <xref href="GUID-22982E51-E746-37CB-9672-97B58C2672BF.dita"><apiname>NFastSemaphore</apiname></xref> object.
+This is a lightweight counting semaphore owned by a specific nanokernel thread.
+Any thread can signal it, but only the owning thread can wait on it. </p> </li>
+<li id="GUID-CFA09EAD-34FE-5F41-83D5-52381B4A6C81"><p>A fast mutex, a <xref href="GUID-D5B555DA-3D17-3ED2-A931-CB35BD93A953.dita"><apiname>NFastMutex</apiname></xref> object.
+This is a lightweight mutual exclusion primitive. It is optimised for very
+fast acquisition and release in the case where there is no contention, and
+it provides priority inheritance. It is non-nestable, i.e. a thread is not
+allowed to hold two fast mutexes simultaneously or to wait on one which it
+already holds. In addition, a thread that holds a fast mutex cannot block
+on any other wait object. </p> </li>
+<li id="GUID-598F43D7-0517-5866-85BF-6E7D67C5CFDE"><p>Deferred function calls
+(DFCs). </p> </li>
+</ul> <p>There is also the option of thread synchronisation by doing one of: </p> <ul>
+<li id="GUID-F3DBBDC5-1245-5C74-A02B-39FC5EFF8484"><p>disabling interrupts,
+by calling <xref href="GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02.dita#GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02/GUID-8C251C65-FDE7-3161-8D2B-61401FB6487F"><apiname>NKern::DisableAllInterrupts()</apiname></xref> </p> </li>
+<li id="GUID-869B40AF-9311-5539-8F5F-AFF1BF6F56F6"><p>disabling preemption,
+by calling <xref href="GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02.dita#GUID-3A3C08F3-3D33-3D9E-80E7-7855C7B21E02/GUID-7CBBF72B-4519-38DD-92CA-38AF636AFD8A"><apiname>NKern::Lock()</apiname></xref> </p> </li>
+</ul> <p>However, these two techniques must be used with caution as they affect
+all parts of the system. </p> </section>
+<section id="GUID-640C747E-6A7B-47B3-BC05-84A10DAE484F"><title>Scheduling threads following a hardware interrupt</title> <p>In
+order to keep interrupt latency to a minimum the vast majority of the nanokernel
+runs with interrupts enabled; this includes the scheduler and other code which
+manipulates the thread ready list. A consequence of this is that it is <i>not</i> permissible
+for an interrupt service routine (ISR) to add a thread to the thread ready
+list. The only way an ISR can influence the scheduling of threads is by means
+of an Immediate Deferred Function Call (IDFC). </p> <p>An IDFC is a function
+call that runs either: </p> <ul>
+<li id="GUID-4324A39E-D9F9-5F21-93BA-8014B39D17A0"><p>immediately after the
+completion of the ISR, and any other ISRs that are pending. </p> </li>
+</ul> <p>or </p> <ul>
+<li id="GUID-BAA5895F-DBBC-5B42-B57A-5AF4DEC90824"><p>as soon as preemption
+is re-enabled, if preemption was disabled at the time the interrupt occurred. </p> </li>
+</ul> <p>IDFCs run in FIFO order, i.e. the first one queued is first one to
+run, with interrupts enabled and preemption disabled. This means that IDFCs
+cannot be preempted either by threads or by other IDFCs, but only by ISRs.
+However, they can add threads to the ready list and thus cause rescheduling. </p> <p>As
+IDFCs are nonpreemptive, they need to be kept short. This means that they
+affect thread latency. If a large amount of work needs to be done in response
+to an ISR, then a Deferred Function Call (DFC) should be used. </p> <p>A DFC
+is a function call that runs in the context of a nominated thread. A DFC is
+associated with a DFC queue, which in turn is associated with a thread. The
+thread simply waits forever for a DFC to be added to the queue and then calls
+back the DFC. DFCs execute with both interrupts and preemption enabled. Because
+DFCs are so common in Symbian platform driver code, the nanokernel provides
+a shortcut to allow them to be queued directly by ISRs instead of by an IDFC.
+The same object, a <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita"><apiname>TDfc</apiname></xref>, is used for both IDFCs and DFCs.
+When this object is queued by an ISR, it first executes as an IDFC; the code
+for this IDFC is buried in the nanokernel. This code transfers the object
+to the final DFC queue and wakes up the DFC thread as required. </p> </section>
+<section id="GUID-1EB1E07D-433B-4058-9CE3-4825A8945704"><title>Nanokernel thread handlers</title> <p>Each nanokernel thread
+can have the following handlers defined: </p> <ul>
+<li id="GUID-A52FA56C-D5CF-5186-A3A4-09941C17C0E0"><p>Exit handler. This is
+called in the context of the exiting thread just before it is terminated. </p> </li>
+<li id="GUID-66E53EEE-B076-5116-AA72-CDE4EE19315D"><p>Exception handler. This
+is called if a CPU exception occurs during the execution of the thread; it
+is called, in the context of the thread. </p> </li>
+<li id="GUID-8369C8AD-C9C1-505D-89F3-983F23009F9B"><p>Time-out handler. This
+is called if the thread's wait time-out expires with the thread in the BLOCKED
+state, or in an unknown state. It is called in the context of the nanokernel
+timer thread, DFC Thread 1, with preemption enabled. It is used in Symbian
+platform wait-with-timeout operations. </p> </li>
+<li id="GUID-7665E6CA-8BB4-5F1B-8CEB-DA5F59D77619"><p>State handler. <i>This
+is the fundamental hook used for personality layers.</i>. It is called if: </p> <ul>
+<li id="GUID-7996AB09-C5DF-520E-ADBB-B65AF9EC536F"><p>the thread is suspended </p> </li>
+<li id="GUID-39CC9F5E-663F-5BAD-8D04-55E698F7D405"><p>the thread is resumed </p> </li>
+<li id="GUID-4DE5F701-EA02-5C43-896D-38202F9CB8EE"><p>the thread is released </p> </li>
+<li id="GUID-EA3FCFAF-890B-537B-BE1F-F605B19BF9B5"><p>the thread has its priority
+changed </p> </li>
+<li id="GUID-63E0ABEB-2878-5F4D-92CB-AF2EB28D2A54"><p>the thread's wait timeout
+expires and there is no time-out handler and the thread is in an unrecognised
+nanokernel state. </p> </li>
+</ul> </li>
+</ul> <p>See also <filepath>...\e32\personality\example\personality.cpp</filepath>. </p> </section>
+<section id="GUID-600F44F2-9F2D-409A-9D66-10526319020C"><title>Timer management </title> <p>The nanokernel provides a basic
+relative timer object, an <xref href="GUID-D8CF05A3-5C9B-3662-92DA-3290C6EE7FD2.dita"><apiname>NTimer</apiname></xref>, which can generate either
+one-shot or periodic interrupts. </p> <p>A time-out handler is called when
+the timer expires, either from the timer ISR or from the nanokernel timer
+thread. Timer objects may be manipulated from any context. The timers are
+driven from a periodic system tick interrupt, usually a 1ms period. </p> <p>For
+the purposes of power management, an API is provided to return the number
+of ticks left until the next timer expiry, thus enabling the tick interrupt
+to be suppressed and a deep sleep mode to be entered. </p> </section>
+</conbody></concept>
\ No newline at end of file