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 "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
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 CSubtractor::DoCancel()
00072 {
00073 if(IsActive())
00074 {
00075
00076 iConsole->ReadCancel();
00077 }
00078 }
00079
00083 CSubtractor::~CSubtractor()
00084 {
00085
00086 DoCancel();
00087
00088 iPeriodic->Cancel();
00089 delete iPeriodic;
00090 }
00091
00095 CSubtractor::CSubtractor():CActive(EPriorityUserInput)
00096 {
00097 }
00098
00104 void CSubtractor::ConstructL(CConsoleBase* aConsole)
00105 {
00106
00107 User::LeaveIfError(iCondVar.OpenGlobal(KCondVarName));
00108
00109 User::LeaveIfError(iChunk.OpenGlobal(KChunkName,EFalse));
00110
00111 User::LeaveIfError(iMutex.OpenGlobal(KMutexName));
00112
00113
00114 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00115 iConsole = aConsole;
00116
00117
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
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
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
00162 ptr->Subtract();
00163 return KErrNone;
00164 }
00165
00169 void CSubtractor::Subtract()
00170 {
00171
00172 iMutex.Wait();
00173
00174
00175 TInt randVal = Math::Random() % 10;
00176
00177
00178 TUint8 *ptr = iChunk.Base();
00179
00180
00181 iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00182
00183
00184 *ptr -= randVal;
00185
00186 while(*ptr < KLowerThreshold)
00187 {
00188
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
00194 iConsole->Printf(_L("Value of the shared memory decreased to : %d\n"),*ptr);
00195
00196
00197 if(*ptr < KUpperThreshold)
00198 {
00199
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
00212 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00213 CleanupStack::PushL(scheduler);
00214 CActiveScheduler::Install(scheduler);
00215
00216
00217 CSubtractor* subtractor = CSubtractor::NewL(console);
00218 CleanupStack::PushL(subtractor);
00219
00220
00221 subtractor->StartTimer();
00222
00223 subtractor->ReadFunction();
00224
00225 CActiveScheduler::Start();
00226
00227 CleanupStack::PopAndDestroy(2,scheduler);
00228 }
00229
00230 GLDEF_C TInt E32Main()
00231 {
00232 __UHEAP_MARK;
00233 CTrapCleanup* cleanup=CTrapCleanup::New();
00234 TRAPD(error,callExampleL());
00235 delete cleanup;
00236 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00237 __UHEAP_MARKEND;
00238 return 0;
00239 }
00240
00241 LOCAL_C void callExampleL()
00242 {
00243 console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00244 CleanupStack::PushL(console);
00245 TRAPD(error,DoExampleL());
00246 if (error)
00247 console->Printf(KFormatFailed, error);
00248 else
00249 console->Printf(KTxtOK);
00250 console->Printf(KTxtPressAnyKey);
00251 console->Getch();
00252 CleanupStack::PopAndDestroy();
00253 }