00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00035 #include "sharedmem.h"
00036 #include "adder.h"
00037
00043 CAdder* CAdder::NewL(CConsoleBase* aConsole)
00044 {
00045 CAdder* self = new (ELeave) CAdder;
00046 CleanupStack::PushL(self);
00047 self->ConstructL(aConsole);
00048 CleanupStack::Pop(self);
00049 return self;
00050 }
00051
00056 void CAdder::RunL()
00057 {
00058
00059 TUint8 option = iConsole->KeyCode();
00060
00061 _LIT(KTextFormat,"%c\n");
00062 iConsole->Printf(KTextFormat,option);
00063
00064 StopTimer();
00065 CActiveScheduler::Stop();
00066 }
00067
00071 void CAdder::DoCancel()
00072 {
00073 if(IsActive())
00074 {
00075
00076 iConsole->ReadCancel();
00077 }
00078 }
00079
00083 CAdder::~CAdder()
00084 {
00085
00086 DoCancel();
00087
00088
00089 iPeriodic->Cancel();
00090 delete iPeriodic;
00091
00092
00093 iChunk.Close();
00094 iMutex.Close();
00095 iCondVar.Close();
00096 }
00097
00101 CAdder::CAdder():CActive(EPriorityUserInput)
00102 {
00103 }
00104
00114 void CAdder::ConstructL(CConsoleBase* aConsole)
00115 {
00116
00117 User::LeaveIfError(iCondVar.CreateGlobal(KCondVarName));
00118
00119 User::LeaveIfError(iChunk.CreateGlobal(KChunkName,KChunkSize,KChunkSize));
00120
00121 User::LeaveIfError(iMutex.CreateGlobal(KMutexName));
00122
00123
00124 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00125 iConsole = aConsole;
00126
00127
00128 TUint8 *ptr = iChunk.Base();
00129
00130 *ptr = 0;
00131
00132
00133 CActiveScheduler::Add(this);
00134 }
00135
00139 void CAdder::ReadFunction()
00140 {
00141 _LIT(KTextMessage,"Press a key to exit...\n");
00142 iConsole->Printf(KTextMessage);
00143
00144 iConsole->Read(iStatus);
00145 SetActive();
00146 }
00147
00152 void CAdder::StartTimer()
00153 {
00154
00155 iPeriodic->Start(0,3000000,TCallBack(AddFunction,this));
00156 }
00157
00161 void CAdder::StopTimer()
00162 {
00163
00164 iPeriodic->Cancel();
00165 }
00166
00172 TInt CAdder::AddFunction(TAny* aPtr)
00173 {
00174 CAdder* ptr = static_cast<CAdder*> (aPtr);
00175 _LIT(KTxtPanic,"Pointer is NULL");
00176 __ASSERT_ALWAYS(ptr,User::Panic(KTxtPanic,-1));
00177
00178 ptr->Add();
00179 return KErrNone;
00180 }
00181
00185 void CAdder::Add()
00186 {
00187
00188 iMutex.Wait();
00189
00190
00191 TInt randVal = Math::Random() % 10;
00192
00193
00194 TUint8 *ptr = iChunk.Base();
00195
00196
00197 iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00198
00199
00200 *ptr += randVal;
00201
00202 while(*ptr > KUpperThreshold)
00203 {
00204
00205 _LIT(KBlockMessage,"Adder blocked by condVar until Subtractor signals that value has been decreased.\nIntermediate value of the chunk = %d\n");
00206 iConsole->Printf(KBlockMessage,*ptr);
00207 iCondVar.Wait(iMutex);
00208 }
00209
00210 iConsole->Printf(_L("Value of the shared memory increased to : %d\n"),*ptr);
00211
00212
00213 if(*ptr > KLowerThreshold)
00214 {
00215
00216 iCondVar.Signal();
00217 }
00218 iMutex.Signal();
00219 }
00220
00221 LOCAL_D CConsoleBase* console;
00222 LOCAL_C void DoExampleL();
00223 LOCAL_C void callExampleL();
00224
00225 LOCAL_C void DoExampleL()
00226 {
00227
00228 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00229 CleanupStack::PushL(scheduler);
00230 CActiveScheduler::Install(scheduler);
00231
00232
00233 CAdder* adder = CAdder::NewL(console);
00234 CleanupStack::PushL(adder);
00235
00236
00237 adder->StartTimer();
00238
00239 adder->ReadFunction();
00240
00241 CActiveScheduler::Start();
00242
00243 CleanupStack::PopAndDestroy(2,scheduler);
00244 }
00245
00246 GLDEF_C TInt E32Main()
00247 {
00248 __UHEAP_MARK;
00249 CTrapCleanup* cleanup=CTrapCleanup::New();
00250 TRAPD(error,callExampleL());
00251 delete cleanup;
00252 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00253 __UHEAP_MARKEND;
00254 return 0;
00255 }
00256
00257 LOCAL_C void callExampleL()
00258 {
00259 console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00260 CleanupStack::PushL(console);
00261 TRAPD(error,DoExampleL());
00262 if (error)
00263 console->Printf(KFormatFailed, error);
00264 else
00265 console->Printf(KTxtOK);
00266 console->Printf(KTxtPressAnyKey);
00267 console->Getch();
00268 CleanupStack::PopAndDestroy();
00269 }