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

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: Implements the write operation on a shared memory block.  
00028 */
00029 
00030 
00031 
00035 #include "sharedmem.h"
00036 #include "subtractor.h"
00037 
00043 CSubtractor* CSubtractor::NewL(CConsoleBase* aConsole)
00044         {
00045         CSubtractor* self = new (ELeave) CSubtractor;
00046         CleanupStack::PushL(self);
00047         self->ConstructL(aConsole);
00048         CleanupStack::Pop(self);
00049         return self;
00050         }
00051 
00056 void CSubtractor::RunL()
00057         {
00058         // Get the key code.
00059         TUint8 option = iConsole->KeyCode();
00060         // Print the selected option.
00061         _LIT(KTextFormat,"%c\n");
00062         iConsole->Printf(KTextFormat,option);
00063         // Stop the timer and the active scheduler.
00064         StopTimer();
00065         CActiveScheduler::Stop();
00066         }
00067 
00071 void CSubtractor::DoCancel()
00072         {
00073         if(IsActive())
00074                 {
00075                 // Cancel any outstanding read requests.
00076                 iConsole->ReadCancel();
00077                 }
00078         }
00079 
00083 CSubtractor::~CSubtractor()
00084         {
00085         // Cancel all outstanding requests.
00086         DoCancel();
00087         // Delete the timer object.
00088         iPeriodic->Cancel();
00089         delete iPeriodic;
00090         }
00091 
00095 CSubtractor::CSubtractor():CActive(EPriorityUserInput)
00096         {
00097         }
00098 
00104 void CSubtractor::ConstructL(CConsoleBase* aConsole)
00105         {
00106         // Open the global condition variable.
00107         User::LeaveIfError(iCondVar.OpenGlobal(KCondVarName));
00108         // Open the global chunk variable.
00109         User::LeaveIfError(iChunk.OpenGlobal(KChunkName,EFalse));
00110         // Open the global mutex variable.
00111         User::LeaveIfError(iMutex.OpenGlobal(KMutexName));
00112 
00113         // Create the CPeriodic object.
00114         iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00115         iConsole = aConsole;
00116 
00117         // Add the object to the active scheduler.
00118         CActiveScheduler::Add(this);
00119         }
00120 
00124 void CSubtractor::ReadFunction()
00125         {
00126         _LIT(KTextMessage,"Press a key to exit...\n");
00127         iConsole->Printf(KTextMessage);
00128         // Wait for a key press event.
00129         iConsole->Read(iStatus);
00130         SetActive();
00131         }
00132 
00137 void CSubtractor::StartTimer()
00138         {
00139         iPeriodic->Start(0,3000000,TCallBack(SubtractFunction,this));
00140         }
00141 
00145 void CSubtractor::StopTimer()
00146         {
00147         // Cancel the  outstanding request.
00148         iPeriodic->Cancel();
00149         }
00150 
00156 TInt CSubtractor::SubtractFunction(TAny* aPtr)
00157         {
00158         CSubtractor* ptr = static_cast<CSubtractor*> (aPtr);
00159         _LIT(KTxtPanic,"Unexpected datatype\n");
00160         __ASSERT_ALWAYS(ptr,User::Panic(KTxtPanic,-1));
00161         // Invoke the Subtract() function.
00162         ptr->Subtract();
00163         return KErrNone;
00164         }
00165 
00169 void CSubtractor::Subtract()
00170         {
00171         // Acquire the mutex.
00172         iMutex.Wait();
00173 
00174         // Get a random number.
00175         TInt randVal = Math::Random() % 10;
00176 
00177         // Get the address of the chunk.
00178         TUint8 *ptr = iChunk.Base();
00179 
00180         // Print the value of the chunk before subtraction.
00181         iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00182 
00183         // Subtract the random value from the shared memory variable.
00184         *ptr -= randVal;
00185 
00186         while(*ptr < KLowerThreshold)
00187                 {
00188                 // Wait on the condition variable if the result is lesser than 0.
00189                 _LIT(KBlockMessage,"Subtractor blocked by condVar until Adder signals that value has been increased.\nIntermediate value of the chunk = %d\n");
00190                 iConsole->Printf(KBlockMessage,*ptr);
00191                 iCondVar.Wait(iMutex);
00192                 }
00193         // Print the updated value of the chunk.
00194         iConsole->Printf(_L("Value of the shared memory decreased to : %d\n"),*ptr);
00195 
00196         // Signal the mutex and the condition variable.
00197         if(*ptr < KUpperThreshold)
00198                 {
00199                 // Signal that the level is safe for addition to (re)start.
00200                 iCondVar.Signal();
00201                 }
00202         iMutex.Signal();
00203         }
00204 
00205 LOCAL_D CConsoleBase* console;
00206 LOCAL_C void DoExampleL();
00207 LOCAL_C void callExampleL();
00208 
00209 LOCAL_C void DoExampleL()
00210         {
00211         // Create and install the active scheduler.
00212         CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00213         CleanupStack::PushL(scheduler);
00214         CActiveScheduler::Install(scheduler);
00215 
00216         // Create the CSubtractor object.
00217         CSubtractor* subtractor = CSubtractor::NewL(console);
00218         CleanupStack::PushL(subtractor);
00219 
00220         // Start the timer of the CSubtractor object.
00221         subtractor->StartTimer();
00222         // Issue an asynchronous read request.
00223         subtractor->ReadFunction();
00224         // Start the active scheduler.
00225         CActiveScheduler::Start();
00226 
00227         CleanupStack::PopAndDestroy(2,scheduler);
00228         }
00229 
00230 GLDEF_C TInt E32Main() // main function called by E32
00231     {
00232         __UHEAP_MARK;
00233         CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
00234         TRAPD(error,callExampleL()); // more initializations, then do example
00235         delete cleanup; // destroy clean-up stack
00236         __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00237         __UHEAP_MARKEND;
00238         return 0; // and return
00239     }
00240 
00241 LOCAL_C void callExampleL() // initialise and call example code under cleanup stack
00242     {
00243         console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00244         CleanupStack::PushL(console);
00245         TRAPD(error,DoExampleL()); // perform example function
00246         if (error)
00247                 console->Printf(KFormatFailed, error);
00248         else
00249                 console->Printf(KTxtOK);
00250         console->Printf(KTxtPressAnyKey);
00251         console->Getch(); // get and ignore character
00252         CleanupStack::PopAndDestroy(); // close console
00253     }

Generated by  doxygen 1.6.2