--- a/kernel/eka/include/drivers/dma_v2.h Wed May 05 05:11:16 2010 +0100
+++ b/kernel/eka/include/drivers/dma_v2.h Mon May 10 11:40:53 2010 +0100
@@ -1197,14 +1197,53 @@
empty request queue, or immediately after the request count has become
zero because of request cancellation or completion.
- Depending on the current value of iQueuedRequests, the PSL may power
- down or power up the channel. Note that iQueuedRequests gets accessed
- and changed by different threads, so the PSL needs to take the usual
- precautions when evaluating the variable's value.
+ Depending on the current and previous observed values of
+ iQueuedRequests, the PSL may power down or power up the channel.
+
+ Note that iQueuedRequests gets accessed and changed by different
+ threads, so the PSL needs to take the usual precautions when evaluating
+ the variable's value. Also, due to the multithreaded framework
+ architecture, there is no guarantee that the function calls always
+ arrive at the PSL level in the strict chronological order of
+ iQueuedRequests being incremented/decremented in the PIL, i.e. it might
+ happen that the PSL finds iQueuedRequests to have the same value in two
+ or more consecutive calls (that's why the previous observed value needs
+ to be locally available and taken into account). It is however promised
+ that before any actual transfer commences the PSL will find the request
+ count to be greater than zero and that after the last request has
+ finished it will be found to be zero.
None of the internal DMA framework mutexes is being held by the PIL
when calling this function.
+ Here is an example implementation for a derived channel class:
+
+ @code
+
+ class TFooDmaChannel : public TDmaSgChannel
+ {
+ DMutex* iDmaMutex;
+ TInt iPrevQueuedRequests;
+ virtual void QueuedRequestCountChanged();
+ };
+
+ void TFooDmaChannel::QueuedRequestCountChanged()
+ {
+ Kern::MutexWait(*iDmaMutex);
+ if ((iQueuedRequests > 0) && (iPrevQueuedRequests == 0))
+ {
+ IncreasePowerCount(); // Base port specific
+ }
+ else if ((iQueuedRequests == 0) && (iPrevQueuedRequests > 0))
+ {
+ DecreasePowerCount(); // Base port specific
+ }
+ iPrevQueuedRequests = iQueuedRequests;
+ Kern::MutexSignal(*iDmaMutex);
+ }
+
+ @endcode
+
@see iQueuedRequests
*/
virtual void QueuedRequestCountChanged();