os/kernelhwsrv/kernel/eka/include/nkern/dfcs.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\include\nkern\dfcs.h
sl@0
    15
// 
sl@0
    16
// WARNING: This file contains some APIs which are internal and are subject
sl@0
    17
//          to change without notice. Such APIs should therefore not be used
sl@0
    18
//          outside the Kernel and Hardware Services package.
sl@0
    19
//
sl@0
    20
sl@0
    21
#ifndef __DFCS_H__
sl@0
    22
#define __DFCS_H__
sl@0
    23
sl@0
    24
#include <nklib.h>
sl@0
    25
sl@0
    26
class NThreadBase;
sl@0
    27
class NThread;
sl@0
    28
class NFastSemaphore;
sl@0
    29
class NFastMutex;
sl@0
    30
sl@0
    31
/********************************************
sl@0
    32
 * Delayed function call queue
sl@0
    33
 ********************************************/
sl@0
    34
sl@0
    35
/**
sl@0
    36
@publishedPartner
sl@0
    37
@released
sl@0
    38
sl@0
    39
The number of DFC priorities the system has, which range from 0
sl@0
    40
to KNumDfcPriorities - 1.
sl@0
    41
*/
sl@0
    42
const TInt KNumDfcPriorities=8;
sl@0
    43
sl@0
    44
/**
sl@0
    45
@publishedPartner
sl@0
    46
@released
sl@0
    47
sl@0
    48
The highest priority level for a DFC, which is equal to KNumDfcPriorities + 1.
sl@0
    49
*/
sl@0
    50
const TInt KMaxDfcPriority=KNumDfcPriorities-1;
sl@0
    51
sl@0
    52
class TDfc;
sl@0
    53
/**
sl@0
    54
@publishedPartner
sl@0
    55
@released
sl@0
    56
sl@0
    57
Defines a DFC queue.
sl@0
    58
sl@0
    59
Each DFC queue is associated with a thread.
sl@0
    60
sl@0
    61
@see TDfc
sl@0
    62
*/
sl@0
    63
class TDfcQue : public TPriList<TDfc,KNumDfcPriorities>
sl@0
    64
	{
sl@0
    65
public:
sl@0
    66
	IMPORT_C TDfcQue();
sl@0
    67
sl@0
    68
	inline TBool IsEmpty();		/**< @internalComponent */
sl@0
    69
	static void ThreadFunction(TAny* aDfcQ);
sl@0
    70
public:
sl@0
    71
	NThreadBase* iThread;		/**< @internalComponent */
sl@0
    72
	};
sl@0
    73
sl@0
    74
/**
sl@0
    75
@internalComponent
sl@0
    76
*/
sl@0
    77
inline TBool TDfcQue::IsEmpty()
sl@0
    78
	{ return (iPresent[0]==0); }
sl@0
    79
sl@0
    80
/********************************************
sl@0
    81
 * Delayed function call
sl@0
    82
 ********************************************/
sl@0
    83
sl@0
    84
/**
sl@0
    85
@publishedPartner
sl@0
    86
@released
sl@0
    87
sl@0
    88
The function type that can be set to run as a DFC or IDFC.
sl@0
    89
sl@0
    90
@see TDfc
sl@0
    91
*/
sl@0
    92
typedef void (*TDfcFn)(TAny*);
sl@0
    93
sl@0
    94
/**
sl@0
    95
@publishedPartner
sl@0
    96
@released
sl@0
    97
sl@0
    98
Defines a Deferred Function Call (DFC) or Immediate Deferred Function Call (IDFC).
sl@0
    99
sl@0
   100
A DFC is a kernel object that specifies a function to be run in a thread,
sl@0
   101
which is processing a DFC queue. A DFC is added to a DFC queue that is 
sl@0
   102
associated with a given thread, where it is cooperatively scheduled with other
sl@0
   103
DFCs on that queue.  Queued DFCs are run in order of their priority, followed
sl@0
   104
by the order they where queued.  When the DFC gets to run, the function is run
sl@0
   105
kernel side, and no other DFC in this queue will get to run until it 
sl@0
   106
completes. A DFC can be queued from any context.
sl@0
   107
sl@0
   108
An IDFC is run as soon as the scheduler is next run, which is during the IRQ
sl@0
   109
postamble if queued from an ISR; when the currently-running IDFC completes if
sl@0
   110
queued from an IDFC; or when the kernel is next unlocked if queued from thread
sl@0
   111
context.  Unlike a DFC, the IDFC is not run from a thread context, and its
sl@0
   112
execution time must be much smaller.  For these reasons, IDFCs are rarely used
sl@0
   113
directly, but are used for implementation of the kernel and RTOS personality
sl@0
   114
layers.  An important use of IDFCs is in the implementation of queuing DFCs from
sl@0
   115
an ISR context.  IDFCs are run with interrupts enabled but the kernel locked.
sl@0
   116
*/
sl@0
   117
class TDfc : public TPriListLink
sl@0
   118
	{
sl@0
   119
	// iPriority<KNumDfcPriorities => DFC, otherwise IDFC
sl@0
   120
	// iSpare2!=0 if on final queue, 0 if not queued or on pending queue
sl@0
   121
	// iSpare3!=0 if on pending or final queue, 0 if not queued
sl@0
   122
public:
sl@0
   123
	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr);									// create IDFC
sl@0
   124
	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TInt aPriority);					// create DFC, queue to be set later
sl@0
   125
	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority);	// create DFC
sl@0
   126
	IMPORT_C TBool Add();						// call from ISR or IDFC or thread with kernel locked
sl@0
   127
	IMPORT_C TBool Cancel();					// call from anywhere except ISR
sl@0
   128
	IMPORT_C TBool Enque();						// call from thread
sl@0
   129
	IMPORT_C TBool Enque(NFastMutex* aMutex);	// call from thread, signal fast mutex (anti-thrash)
sl@0
   130
	IMPORT_C TBool DoEnque();					// call from IDFC or thread with kernel locked
sl@0
   131
	IMPORT_C TBool RawAdd();					// same as Add() but without checks for 'correct' usage or other instrumentation
sl@0
   132
	IMPORT_C TBool QueueOnIdle();				// queue the DFC to be run when the system goes idle
sl@0
   133
	IMPORT_C NThreadBase* Thread();				// thread on which DFC runs, NULL for IDFC
sl@0
   134
	void DoEnqueFinal();
sl@0
   135
	inline TBool Queued();
sl@0
   136
	inline TBool IsIDFC();
sl@0
   137
	inline TBool TestAndSetQueued();			/**< @internalComponent */
sl@0
   138
	inline void SetDfcQ(TDfcQue* aDfcQ);
sl@0
   139
	inline void SetFunction(TDfcFn aDfcFn);
sl@0
   140
	inline void SetPriority(TInt aPriority);	/**< @internalComponent */
sl@0
   141
public:
sl@0
   142
	TAny* iPtr;			/**< @internalComponent */
sl@0
   143
	TDfcFn iFunction;	/**< @internalComponent */
sl@0
   144
	TDfcQue *iDfcQ;		/**< @internalComponent */
sl@0
   145
	};
sl@0
   146
sl@0
   147
/**
sl@0
   148
@publishedPartner
sl@0
   149
@released
sl@0
   150
sl@0
   151
Used to find out if the DFC/IDFC is queued on either the pending or final DFC queue.
sl@0
   152
sl@0
   153
@return TRUE if the DFC/IDFC is queued, otherwise FALSE.
sl@0
   154
sl@0
   155
*/
sl@0
   156
inline TBool TDfc::Queued()
sl@0
   157
	{ return iSpare3; }
sl@0
   158
sl@0
   159
/**
sl@0
   160
@publishedPartner
sl@0
   161
@released
sl@0
   162
sl@0
   163
Determines if the object represents a DFC or an IDFC.
sl@0
   164
sl@0
   165
@return TRUE if this represents an IDFC, otherwise FALSE meaning it is a DFC.
sl@0
   166
*/
sl@0
   167
inline TBool TDfc::IsIDFC()
sl@0
   168
	{ return iPriority>=KNumDfcPriorities; }
sl@0
   169
sl@0
   170
/**
sl@0
   171
@publishedPartner
sl@0
   172
@released
sl@0
   173
sl@0
   174
Sets the DFC queue that the DFC is to added to and executed by.
sl@0
   175
sl@0
   176
Note that this function should only be used in the initialisation of the DFC, 
sl@0
   177
when it is not on any queue.  This function does not move the DFC from one 
sl@0
   178
queue to another.
sl@0
   179
sl@0
   180
@param aDfcQ
sl@0
   181
sl@0
   182
	The DFC queue that the DFC is to be added to and executed by.
sl@0
   183
sl@0
   184
*/
sl@0
   185
inline void TDfc::SetDfcQ(TDfcQue* aDfcQ)
sl@0
   186
	{ iDfcQ=aDfcQ; }
sl@0
   187
sl@0
   188
/**
sl@0
   189
@publishedPartner
sl@0
   190
@released
sl@0
   191
sl@0
   192
Sets the function that is run when the DFC/IDFC is scheduled.
sl@0
   193
sl@0
   194
@param aDfcFn
sl@0
   195
sl@0
   196
	The function that the DFC/IDFC runs when it is scheduled.
sl@0
   197
sl@0
   198
*/
sl@0
   199
inline void TDfc::SetFunction(TDfcFn aDfcFn)
sl@0
   200
	{ iFunction=aDfcFn; }
sl@0
   201
sl@0
   202
/**
sl@0
   203
@internalComponent
sl@0
   204
*/
sl@0
   205
inline void TDfc::SetPriority(TInt aPriority)
sl@0
   206
	{ iPriority = (TUint8)aPriority; }
sl@0
   207
sl@0
   208
#ifdef __INCLUDE_TDFC_DEFINES__
sl@0
   209
#define	iOnFinalQ		iSpare2
sl@0
   210
#define	iQueued			iSpare3
sl@0
   211
#endif
sl@0
   212
sl@0
   213
sl@0
   214
/********************************************
sl@0
   215
 * Kernel-side asynchronous request,
sl@0
   216
 * based on DFC queueing
sl@0
   217
 ********************************************/
sl@0
   218
sl@0
   219
class TAsyncRequest : protected TDfc
sl@0
   220
	{
sl@0
   221
public:
sl@0
   222
	IMPORT_C void Send(TDfc* aCompletionDfc);
sl@0
   223
	IMPORT_C void Send(NFastSemaphore* aCompletionSemaphore);
sl@0
   224
	IMPORT_C TInt SendReceive();
sl@0
   225
	IMPORT_C void Cancel();
sl@0
   226
	IMPORT_C void Complete(TInt aResult);
sl@0
   227
	inline TBool PollForCancel()
sl@0
   228
		{ return iCancel; }
sl@0
   229
protected:
sl@0
   230
	IMPORT_C TAsyncRequest(TDfcFn aFunction, TDfcQue* aDfcQ, TInt aPriority);
sl@0
   231
protected:
sl@0
   232
	TAny*	iCompletionObject;
sl@0
   233
	volatile TBool	iCancel;
sl@0
   234
	TInt	iResult;
sl@0
   235
	};
sl@0
   236
sl@0
   237
sl@0
   238
#endif