examples/Base/IPC/condvar/condvarglobal/src/subtractor.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 // Implements the write operation on a shared memory block.
00015 //
00016 
00017 
00018 
00022 #include "sharedmem.h"
00023 #include "subtractor.h"
00024 
00030 CSubtractor* CSubtractor::NewL(CConsoleBase* aConsole)
00031         {
00032         CSubtractor* self = new (ELeave) CSubtractor;
00033         CleanupStack::PushL(self);
00034         self->ConstructL(aConsole);
00035         CleanupStack::Pop(self);
00036         return self;
00037         }
00038 
00043 void CSubtractor::RunL()
00044         {
00045         // Get the key code.
00046         TUint8 option = iConsole->KeyCode();
00047         // Print the selected option.
00048         _LIT(KTextFormat,"%c\n");
00049         iConsole->Printf(KTextFormat,option);
00050         // Stop the timer and the active scheduler.
00051         StopTimer();
00052         CActiveScheduler::Stop();
00053         }
00054 
00058 void CSubtractor::DoCancel()
00059         {
00060         if(IsActive())
00061                 {
00062                 // Cancel any outstanding read requests.
00063                 iConsole->ReadCancel();
00064                 }
00065         }
00066 
00070 CSubtractor::~CSubtractor()
00071         {
00072         // Cancel all outstanding requests.
00073         DoCancel();
00074         // Delete the timer object.
00075         iPeriodic->Cancel();
00076         delete iPeriodic;
00077         }
00078 
00082 CSubtractor::CSubtractor():CActive(EPriorityUserInput)
00083         {
00084         }
00085 
00091 void CSubtractor::ConstructL(CConsoleBase* aConsole)
00092         {
00093         // Open the global condition variable.
00094         User::LeaveIfError(iCondVar.OpenGlobal(KCondVarName));
00095         // Open the global chunk variable.
00096         User::LeaveIfError(iChunk.OpenGlobal(KChunkName,EFalse));
00097         // Open the global mutex variable.
00098         User::LeaveIfError(iMutex.OpenGlobal(KMutexName));
00099 
00100         // Create the CPeriodic object.
00101         iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00102         iConsole = aConsole;
00103 
00104         // Add the object to the active scheduler.
00105         CActiveScheduler::Add(this);
00106         }
00107 
00111 void CSubtractor::ReadFunction()
00112         {
00113         _LIT(KTextMessage,"Press a key to exit...\n");
00114         iConsole->Printf(KTextMessage);
00115         // Wait for a key press event.
00116         iConsole->Read(iStatus);
00117         SetActive();
00118         }
00119 
00124 void CSubtractor::StartTimer()
00125         {
00126         iPeriodic->Start(0,3000000,TCallBack(SubtractFunction,this));
00127         }
00128 
00132 void CSubtractor::StopTimer()
00133         {
00134         // Cancel the  outstanding request.
00135         iPeriodic->Cancel();
00136         }
00137 
00143 TInt CSubtractor::SubtractFunction(TAny* aPtr)
00144         {
00145         CSubtractor* ptr = static_cast<CSubtractor*> (aPtr);
00146         _LIT(KTxtPanic,"Unexpected datatype\n");
00147         __ASSERT_ALWAYS(ptr,User::Panic(KTxtPanic,-1));
00148         // Invoke the Subtract() function.
00149         ptr->Subtract();
00150         return KErrNone;
00151         }
00152 
00156 void CSubtractor::Subtract()
00157         {
00158         // Acquire the mutex.
00159         iMutex.Wait();
00160 
00161         // Get a random number.
00162         TInt randVal = Math::Random() % 10;
00163 
00164         // Get the address of the chunk.
00165         TUint8 *ptr = iChunk.Base();
00166 
00167         // Print the value of the chunk before subtraction.
00168         iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00169 
00170         // Subtract the random value from the shared memory variable.
00171         *ptr -= randVal;
00172 
00173         while(*ptr < KLowerThreshold)
00174                 {
00175                 // Wait on the condition variable if the result is lesser than 0.
00176                 _LIT(KBlockMessage,"Subtractor blocked by condVar until Adder signals that value has been increased.\nIntermediate value of the chunk = %d\n");
00177                 iConsole->Printf(KBlockMessage,*ptr);
00178                 iCondVar.Wait(iMutex);
00179                 }
00180         // Print the updated value of the chunk.
00181         iConsole->Printf(_L("Value of the shared memory decreased to : %d\n"),*ptr);
00182 
00183         // Signal the mutex and the condition variable.
00184         if(*ptr < KUpperThreshold)
00185                 {
00186                 // Signal that the level is safe for addition to (re)start.
00187                 iCondVar.Signal();
00188                 }
00189         iMutex.Signal();
00190         }
00191 
00192 LOCAL_D CConsoleBase* console;
00193 LOCAL_C void DoExampleL();
00194 LOCAL_C void callExampleL();
00195 
00196 LOCAL_C void DoExampleL()
00197         {
00198         // Create and install the active scheduler.
00199         CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00200         CleanupStack::PushL(scheduler);
00201         CActiveScheduler::Install(scheduler);
00202 
00203         // Create the CSubtractor object.
00204         CSubtractor* subtractor = CSubtractor::NewL(console);
00205         CleanupStack::PushL(subtractor);
00206 
00207         // Start the timer of the CSubtractor object.
00208         subtractor->StartTimer();
00209         // Issue an asynchronous read request.
00210         subtractor->ReadFunction();
00211         // Start the active scheduler.
00212         CActiveScheduler::Start();
00213 
00214         CleanupStack::PopAndDestroy(2,scheduler);
00215         }
00216 
00217 GLDEF_C TInt E32Main() // main function called by E32
00218     {
00219         __UHEAP_MARK;
00220         CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
00221         TRAPD(error,callExampleL()); // more initializations, then do example
00222         delete cleanup; // destroy clean-up stack
00223         __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00224         __UHEAP_MARKEND;
00225         return 0; // and return
00226     }
00227 
00228 LOCAL_C void callExampleL() // initialise and call example code under cleanup stack
00229     {
00230         console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00231         CleanupStack::PushL(console);
00232         TRAPD(error,DoExampleL()); // perform example function
00233         if (error)
00234                 console->Printf(KFormatFailed, error);
00235         else
00236                 console->Printf(KTxtOK);
00237         console->Printf(KTxtPressAnyKey);
00238         console->Getch(); // get and ignore character
00239         CleanupStack::PopAndDestroy(); // close console
00240     }

Generated by  doxygen 1.6.2