00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00046 TUint8 option = iConsole->KeyCode();
00047
00048 _LIT(KTextFormat,"%c\n");
00049 iConsole->Printf(KTextFormat,option);
00050
00051 StopTimer();
00052 CActiveScheduler::Stop();
00053 }
00054
00058 void CAdder::DoCancel()
00059 {
00060 if(IsActive())
00061 {
00062
00063 iConsole->ReadCancel();
00064 }
00065 }
00066
00070 CAdder::~CAdder()
00071 {
00072
00073 DoCancel();
00074
00075
00076 iPeriodic->Cancel();
00077 delete iPeriodic;
00078
00079
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
00104 User::LeaveIfError(iCondVar.CreateGlobal(KCondVarName));
00105
00106 User::LeaveIfError(iChunk.CreateGlobal(KChunkName,KChunkSize,KChunkSize));
00107
00108 User::LeaveIfError(iMutex.CreateGlobal(KMutexName));
00109
00110
00111 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00112 iConsole = aConsole;
00113
00114
00115 TUint8 *ptr = iChunk.Base();
00116
00117 *ptr = 0;
00118
00119
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
00131 iConsole->Read(iStatus);
00132 SetActive();
00133 }
00134
00139 void CAdder::StartTimer()
00140 {
00141
00142 iPeriodic->Start(0,3000000,TCallBack(AddFunction,this));
00143 }
00144
00148 void CAdder::StopTimer()
00149 {
00150
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
00165 ptr->Add();
00166 return KErrNone;
00167 }
00168
00172 void CAdder::Add()
00173 {
00174
00175 iMutex.Wait();
00176
00177
00178 TInt randVal = Math::Random() % 10;
00179
00180
00181 TUint8 *ptr = iChunk.Base();
00182
00183
00184 iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00185
00186
00187 *ptr += randVal;
00188
00189 while(*ptr > KUpperThreshold)
00190 {
00191
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
00197 iConsole->Printf(_L("Value of the shared memory increased to : %d\n"),*ptr);
00198
00199
00200 if(*ptr > KLowerThreshold)
00201 {
00202
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
00215 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00216 CleanupStack::PushL(scheduler);
00217 CActiveScheduler::Install(scheduler);
00218
00219
00220 CAdder* adder = CAdder::NewL(console);
00221 CleanupStack::PushL(adder);
00222
00223
00224 adder->StartTimer();
00225
00226 adder->ReadFunction();
00227
00228 CActiveScheduler::Start();
00229
00230 CleanupStack::PopAndDestroy(2,scheduler);
00231 }
00232
00233 GLDEF_C TInt E32Main()
00234 {
00235 __UHEAP_MARK;
00236 CTrapCleanup* cleanup=CTrapCleanup::New();
00237 TRAPD(error,callExampleL());
00238 delete cleanup;
00239 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00240 __UHEAP_MARKEND;
00241 return 0;
00242 }
00243
00244 LOCAL_C void callExampleL()
00245 {
00246 console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00247 CleanupStack::PushL(console);
00248 TRAPD(error,DoExampleL());
00249 if (error)
00250 console->Printf(KFormatFailed, error);
00251 else
00252 console->Printf(KTxtOK);
00253 console->Printf(KTxtPressAnyKey);
00254 console->Getch();
00255 CleanupStack::PopAndDestroy();
00256 }