00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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 CSubtractor::DoCancel()
00059 {
00060 if(IsActive())
00061 {
00062
00063 iConsole->ReadCancel();
00064 }
00065 }
00066
00070 CSubtractor::~CSubtractor()
00071 {
00072
00073 DoCancel();
00074
00075 iPeriodic->Cancel();
00076 delete iPeriodic;
00077 }
00078
00082 CSubtractor::CSubtractor():CActive(EPriorityUserInput)
00083 {
00084 }
00085
00091 void CSubtractor::ConstructL(CConsoleBase* aConsole)
00092 {
00093
00094 User::LeaveIfError(iCondVar.OpenGlobal(KCondVarName));
00095
00096 User::LeaveIfError(iChunk.OpenGlobal(KChunkName,EFalse));
00097
00098 User::LeaveIfError(iMutex.OpenGlobal(KMutexName));
00099
00100
00101 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput);
00102 iConsole = aConsole;
00103
00104
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
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
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
00149 ptr->Subtract();
00150 return KErrNone;
00151 }
00152
00156 void CSubtractor::Subtract()
00157 {
00158
00159 iMutex.Wait();
00160
00161
00162 TInt randVal = Math::Random() % 10;
00163
00164
00165 TUint8 *ptr = iChunk.Base();
00166
00167
00168 iConsole->Printf(_L("Value read from the shared memory: %d\n"),*ptr);
00169
00170
00171 *ptr -= randVal;
00172
00173 while(*ptr < KLowerThreshold)
00174 {
00175
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
00181 iConsole->Printf(_L("Value of the shared memory decreased to : %d\n"),*ptr);
00182
00183
00184 if(*ptr < KUpperThreshold)
00185 {
00186
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
00199 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
00200 CleanupStack::PushL(scheduler);
00201 CActiveScheduler::Install(scheduler);
00202
00203
00204 CSubtractor* subtractor = CSubtractor::NewL(console);
00205 CleanupStack::PushL(subtractor);
00206
00207
00208 subtractor->StartTimer();
00209
00210 subtractor->ReadFunction();
00211
00212 CActiveScheduler::Start();
00213
00214 CleanupStack::PopAndDestroy(2,scheduler);
00215 }
00216
00217 GLDEF_C TInt E32Main()
00218 {
00219 __UHEAP_MARK;
00220 CTrapCleanup* cleanup=CTrapCleanup::New();
00221 TRAPD(error,callExampleL());
00222 delete cleanup;
00223 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
00224 __UHEAP_MARKEND;
00225 return 0;
00226 }
00227
00228 LOCAL_C void callExampleL()
00229 {
00230 console=Console::NewL(KTxtExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00231 CleanupStack::PushL(console);
00232 TRAPD(error,DoExampleL());
00233 if (error)
00234 console->Printf(KFormatFailed, error);
00235 else
00236 console->Printf(KTxtOK);
00237 console->Printf(KTxtPressAnyKey);
00238 console->Getch();
00239 CleanupStack::PopAndDestroy();
00240 }