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 }
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.