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 "adder.h" 00024 00030 CAdder* CAdder::NewL(CConsoleBase* aConsole) 00031 { 00032 CAdder* self = new (ELeave) CAdder; 00033 CleanupStack::PushL(self); 00034 self->ConstructL(aConsole); 00035 CleanupStack::Pop(self); 00036 return self; 00037 } 00038 00043 void CAdder::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 CAdder::DoCancel() 00059 { 00060 if(IsActive()) 00061 { 00062 // Cancel any outstanding read requests. 00063 iConsole->ReadCancel(); 00064 } 00065 } 00066 00070 CAdder::~CAdder() 00071 { 00072 // Cancel all outstanding requests. 00073 DoCancel(); 00074 00075 // Delete the timer object. 00076 iPeriodic->Cancel(); 00077 delete iPeriodic; 00078 00079 // Close all resource handles. 00080 iChunk.Close(); 00081 iMutex.Close(); 00082 iCondVar.Close(); 00083 } 00084 00088 CAdder::CAdder():CActive(EPriorityUserInput) 00089 { 00090 } 00091 00101 void CAdder::ConstructL(CConsoleBase* aConsole) 00102 { 00103 // Create the global condition variable. 00104 User::LeaveIfError(iCondVar.CreateGlobal(KCondVarName)); 00105 // Create the global chunk. 00106 User::LeaveIfError(iChunk.CreateGlobal(KChunkName,KChunkSize,KChunkSize)); 00107 // Create the global mutex variable. 00108 User::LeaveIfError(iMutex.CreateGlobal(KMutexName)); 00109 00110 // Create the CPeriodic object. 00111 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput); 00112 iConsole = aConsole; 00113 00114 // Get the address of the chunk. 00115 TUint8 *ptr = iChunk.Base(); 00116 // Initialise the value of the chunk to 0. 00117 *ptr = 0; 00118 00119 // Add the object to the active scheduler. 00120 CActiveScheduler::Add(this); 00121 } 00122 00126 void CAdder::ReadFunction() 00127 { 00128 _LIT(KTextMessage,"Press a key to exit...\n"); 00129 iConsole->Printf(KTextMessage); 00130 // Wait for a key press event. 00131 iConsole->Read(iStatus); 00132 SetActive(); 00133 } 00134 00139 void CAdder::StartTimer() 00140 { 00141 // Start generating periodic events. 00142 iPeriodic->Start(0,3000000,TCallBack(AddFunction,this)); 00143 } 00144 00148 void CAdder::StopTimer() 00149 { 00150 // Cancel the outstanding request. 00151 iPeriodic->Cancel(); 00152 } 00153 00159 TInt CAdder::AddFunction(TAny* aPtr) 00160 { 00161 CAdder* ptr = static_cast<CAdder*> (aPtr); 00162 _LIT(KTxtPanic,"Pointer is NULL"); 00163 __ASSERT_ALWAYS(ptr,User::Panic(KTxtPanic,-1)); 00164 // Invoke the Add() function. 00165 ptr->Add(); 00166 return KErrNone; 00167 } 00168 00172 void CAdder::Add() 00173 { 00174 // Acquire the mutex. 00175 iMutex.Wait(); 00176 00177 // Get a random number. 00178 TInt randVal = Math::Random() % 10; 00179 00180 // Get the address of the chunk. 00181 TUint8 *ptr = iChunk.Base(); 00182 00183 // Print the value of the chunk before addition. 00184 iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr); 00185 00186 // Add the random value to the shared memory variable. 00187 *ptr += randVal; 00188 00189 while(*ptr > KUpperThreshold) 00190 { 00191 // Wait on the condition variable if the result is greater than 100. 00192 _LIT(KBlockMessage,"Adder blocked by condVar until Subtractor signals that value has been decreased.\nIntermediate value of the chunk = %d\n"); 00193 iConsole->Printf(KBlockMessage,*ptr); 00194 iCondVar.Wait(iMutex); 00195 } 00196 // Print the updated value of the chunk. 00197 iConsole->Printf(_L("Value of the shared memory increased to : %d\n"),*ptr); 00198 00199 // Signal the mutex and the condition variable. 00200 if(*ptr > KLowerThreshold) 00201 { 00202 // Signal that the level is safe for subtraction to (re)start. 00203 iCondVar.Signal(); 00204 } 00205 iMutex.Signal(); 00206 } 00207 00208 LOCAL_D CConsoleBase* console; 00209 LOCAL_C void DoExampleL(); 00210 LOCAL_C void callExampleL(); 00211 00212 LOCAL_C void DoExampleL() 00213 { 00214 // Create and install the active scheduler. 00215 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); 00216 CleanupStack::PushL(scheduler); 00217 CActiveScheduler::Install(scheduler); 00218 00219 // Create the CAdder object. 00220 CAdder* adder = CAdder::NewL(console); 00221 CleanupStack::PushL(adder); 00222 00223 // Start the timer of the CAdder object. 00224 adder->StartTimer(); 00225 // Issue an asynchronous read request. 00226 adder->ReadFunction(); 00227 // Start the active scheduler. 00228 CActiveScheduler::Start(); 00229 00230 CleanupStack::PopAndDestroy(2,scheduler); 00231 } 00232 00233 GLDEF_C TInt E32Main() // main function called by E32 00234 { 00235 __UHEAP_MARK; 00236 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack 00237 TRAPD(error,callExampleL()); // more initializations, then do example 00238 delete cleanup; // destroy clean-up stack 00239 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error)); 00240 __UHEAP_MARKEND; 00241 return 0; // and return 00242 } 00243 00244 LOCAL_C void callExampleL() // initialise and call example code under cleanup stack 00245 { 00246 console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen)); 00247 CleanupStack::PushL(console); 00248 TRAPD(error,DoExampleL()); // perform example function 00249 if (error) 00250 console->Printf(KFormatFailed, error); 00251 else 00252 console->Printf(KTxtOK); 00253 console->Printf(KTxtPressAnyKey); 00254 console->Getch(); // get and ignore character 00255 CleanupStack::PopAndDestroy(); // close console 00256 }
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.