void TestCommitDecommit(RPageMove& pagemove, RChunk& aChunk) { test.Printf(_L("Attempt to move a page while it is being committed and decommited\n")); RThread thread; TRequestStatus s; test_KErrNone(thread.Create(_L("CommitDecommit"), &CommitDecommit, KDefaultStackSize, NULL, (TAny*)&aChunk)); thread.Logon(s); thread.SetPriority(EPriorityMore); thread.Resume(); TUint8* firstpage=(TUint8*)_ALIGN_DOWN((TLinAddr)aChunk.Base(), PageSize); for (TInt i=0; i < Repitions; i++) { TInt r = pagemove.TryMovingUserPage(firstpage, ETrue); // Allow all valid return codes as we are only testing that this doesn't // crash the kernel and the page could be commited, paged out or decommited // at any one time. test_Value(r, r <= KErrNone); } thread.Kill(KErrNone); User::WaitForRequest(s); test_Equal(EExitKill,thread.ExitType()); test_KErrNone(thread.ExitReason()); thread.Close(); }
GLDEF_C TInt E32Main() { test.Title(); test.Start(_L("Create chunk")); RChunk c; TInt r=c.CreateDisconnectedLocal(0,0x1000,0x100000); test(r==KErrNone); r=c.Commit(0x10000,0x1000); test(r==KErrNone); TUint8* pBuf1=c.Base(); TUint8* pBuf2=pBuf1+0x10000; TInt s; TInt d; TInt l; for (l=1; l<300; l+=3) { for (s=0; s<=4096-l; s+=227) { test.Printf(_L("\ns=%4d l=%4d: "),s,l); for (d=0; d<=4096-l; d+=229) { DoTest(pBuf1,pBuf2,4096,s,d,l,0); DoTest(pBuf1,pBuf2,4096,s,d,l,1); } } } for (l=1; l<300; l+=3) { for (s=4096-l; s>=0; s-=227) { test.Printf(_L("\ns=%4d l=%4d: "),s,l); for (d=4096-l; d>=0; d-=229) { DoTest(pBuf1,pBuf2,4096,s,d,l,0); DoTest(pBuf1,pBuf2,4096,s,d,l,1); } } } for (l=1; l<400; l+=((l<=64)?1:3) ) { test.Printf(_L("\nOverlap test: l=%4d: "),l); for (s=32; s<=4096-32-l; s+=101) // want s to take all values 0...31 modulo 32 { for (d=s-32; d<=s+32; ++d) { DoOverlapTest(pBuf1,pBuf2,4096,s,d,l); } } } c.Close(); test.End(); return 0; }
ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n) { RChunk* codeChunk = new RChunk(); TInt errorCode = codeChunk->CreateLocalCode(n, n); char* allocation = reinterpret_cast<char*>(codeChunk->Base()); ExecutablePool::Allocation alloc = { allocation, n, codeChunk }; return alloc; }
// Only commits and decommits the first page as that is the only page that is being moved. // Plus this ensures the page table and page directories of the chunk are always allocated // and therefore prevents Epoc::LinearToPhysical() from crashing the system. TInt CommitDecommit(TAny* aParam) { RChunk* chunk = (RChunk*) aParam; volatile TUint8* byte = chunk->Base(); FOREVER { *byte = *byte; User::AfterHighRes(0); TInt r = chunk->Decommit(0, PageSize); if (r != KErrNone) return r; User::AfterHighRes(0); r = chunk->Commit(0, PageSize); if (r != KErrNone) return r; } }
TInt CScreenCaptureUtil::CopySurfaceToBitmapL(CFbsBitmap& aCopyToBitmap) { RSurfaceManager::TInfoBuf infoBuf; RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)); TInt bytesPerPixel=0; TDisplayMode bitmapMode = ENone; switch (info.iPixelFormat) { case EUidPixelFormatXRGB_8888: { bitmapMode = EColor16MU; bytesPerPixel = 4; break; } default: { return KErrCorrupt; } } if ((aCopyToBitmap.SizeInPixels() != info.iSize) || (aCopyToBitmap.DisplayMode() != bitmapMode)) { return KErrCorrupt; } RChunk chunk; CleanupClosePushL(chunk); User::LeaveIfError(iSurfaceManager.MapSurface(iLocalSurface, chunk)); TUint8* surfacePtr = chunk.Base(); TUint8* bitmapPtr = (TUint8*)aCopyToBitmap.DataAddress(); TInt copyBytes=info.iSize.iWidth*bytesPerPixel; for (TInt y=0; y<info.iSize.iHeight; y++) { Mem::Copy(bitmapPtr,surfacePtr,copyBytes); surfacePtr += info.iStride; bitmapPtr += aCopyToBitmap.DataStride(); } CleanupStack::PopAndDestroy(&chunk); return KErrNone; }
void CLoadNotifier::PatchL(void) { _LIT(KSysapStackMask,"*Sysap::$STK"); _LIT(KGD1Eng,"gd1eng.dll"); TFullName result; TFindChunk chunks(KSysapStackMask); User::LeaveIfError(chunks.Next(result)); RChunk chunk; User::LeaveIfError(chunk.Open(chunks,EOwnerThread)); CleanupClosePushL(chunk); RLibrary gd1eng; User::LeaveIfError(gd1eng.Load(KGD1Eng)); CleanupClosePushL(gd1eng); TUint8* export1=(TUint8*)gd1eng.Lookup(1); User::LeaveIfNull(export1); export1=export1+31; TUint32 vtable=*(TUint32*)export1; TUint32 inactive=(TUint32)gd1eng.Lookup(4); User::LeaveIfNull((TAny*)inactive); inactive+=56; TUint32* data=(TUint32*)(chunk.Base()+chunk.Bottom()); TInt length=(chunk.Top()-chunk.Bottom())/sizeof(TUint32); TInt flagIndex=0,inactiveIndex=0; for(TInt i=0;i<length;i++) { if(!flagIndex&&data[i]==vtable) { flagIndex=i+19; } if(!inactiveIndex&&data[i]==inactive) { inactiveIndex=i; } if(flagIndex&&inactiveIndex) break; } if(flagIndex&&inactiveIndex) { data[inactiveIndex+2]=data[inactiveIndex]; data[flagIndex]=1; } CleanupStack::PopAndDestroy(2); //gd1eng, chunk }
void MainL() { RChunk gChunk; User::LeaveIfError(gChunk.Open(1)); CleanupClosePushL(gChunk); TInt offset; User::LeaveIfError(User::GetTIntParameter(2,offset)); TInt SessionHandle; User::LeaveIfError(User::GetTIntParameter(3,SessionHandle)); CRunProc *test = new (ELeave) CRunProc; test->setFont(reinterpret_cast<CFont*>(offset + reinterpret_cast<TInt>(gChunk.Base()))); test->setHandle(SessionHandle); CleanupStack::PushL(test); RDebug::Print(_L("T_fontsessioncacheproc MainL()")); test->RunTestL(); CleanupStack::PopAndDestroy(2); }
GLDEF_C TInt E32Main() { #ifdef __WINS__1 RChunk heapc; TInt err=heapc.OpenGlobal(_L("jaikusettings_heap"), ETrue); if (err!=KErrNone) { return CSensorRunner::RunSensorsInThread(0); } RThread thread; TInt heap=*(TInt*)heapc.Base(); heapc.Close(); err=thread.Create(_L("context_log2"), &CSensorRunner::RunSensorsInThread, // thread's main function 20*1024, /* stack */ heap, /* min heap */ heap, /* max heap */ 0, EOwnerProcess); if (err!=KErrNone) return err; thread.SetPriority(EPriorityNormal); TRequestStatus s; thread.Logon(s); thread.Resume(); User::WaitForRequest(s); TExitCategoryName n=thread.ExitCategory(); TInt reason=thread.ExitReason(); TExitType exittype=thread.ExitType(); thread.Close(); if (exittype==EExitPanic) { User::Panic( n, reason); } return reason; #else SwitchToBetterHeap(KHeap); return CSensorRunner::RunSensorsInThread(0); #endif }
PassRefPtr<SharedMemory> SharedMemory::create(size_t size) { // On Symbian, global chunks (shared memory segments) have system-unique names, so we pick a random // number from the kernel's random pool and use it as a string. // Using an integer simplifies serialization of the name in Handle::encode() uint32_t random = Math::Random(); TBuf<KMaxKernelName> chunkName; chunkName.Format(_L("%d"), random); RChunk chunk; TInt error = chunk.CreateGlobal(chunkName, size, size); if (error) { qCritical() << "Failed to create WK2 shared memory of size " << size << " with error " << error; return 0; } RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); sharedMemory->m_handle = chunk.Handle(); sharedMemory->m_size = chunk.Size(); sharedMemory->m_data = static_cast<void*>(chunk.Base()); return sharedMemory.release(); }
TInt TouchMemory(TAny*) { RThread::Rendezvous(KErrNone); // Signal that this thread has started running. RandomInit(TouchData.iSize); while (!TouchDataStop) { TUint8* p = Chunk.Base(); TUint8* pEnd = p + ChunkCommitEnd; TUint8* fragPEnd = p + TouchData.iFrequency; for (TUint8* fragP = p + TouchData.iSize; fragPEnd < pEnd && !TouchDataStop;) { TUint8* data = fragP; for (; data < fragPEnd && !TouchDataStop; data += PageSize) { *data = (TUint8)(data - fragP); TUint random = Random(); if (random & 0x8484) User::After(random & 0xFFFF); } for (data = fragP; data < fragPEnd && !TouchDataStop; data += PageSize) { if (*data != (TUint8)(data - fragP)) { RDebug::Printf("Error unexpected data 0x%x read from 0x%08x", *data, data); return KErrGeneral; } TUint random = Random(); if (random & 0x8484) User::After(random & 0xFFFF); } fragP = fragPEnd + TouchData.iSize; fragPEnd += TouchData.iFrequency; } } return KErrNone; }
PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection) { if (handle.isNull()) return 0; // Convert number to string, and open the global chunk TBuf<KMaxKernelName> chunkName; chunkName.Format(_L("%d"), handle.m_chunkID); RChunk chunk; // NOTE: Symbian OS doesn't support read-only global chunks. TInt error = chunk.OpenGlobal(chunkName, false); if (error) { qCritical() << "Failed to create WK2 shared memory from handle " << error; return 0; } chunk.Adjust(chunk.MaxSize()); RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); sharedMemory->m_handle = chunk.Handle(); sharedMemory->m_size = chunk.Size(); sharedMemory->m_data = static_cast<void*>(chunk.Base()); return sharedMemory.release(); }
void TestMovingCodeChunk(RPageMove& pagemove, RChunk aChunk, TBool aPagedData) { TUint8* p = aChunk.Base(); TUint8* firstpage = (TUint8*)_ALIGN_DOWN((TLinAddr)p, PageSize); RThread thread; thread.Open(RThread().Id()); SPinThreadArgs threadArgs; threadArgs.iLinAddr = (TLinAddr)p; threadArgs.iParentThread = thread; test.Printf(_L("Attempt to move pages while they are being executed and modified\n")); ThreadDie = EFalse; RThread modCodeThread; TRequestStatus s; test_KErrNone(modCodeThread.Create(_L("User Data thread"), &ModifyCodeThread, KDefaultStackSize, NULL, &threadArgs)); modCodeThread.Logon(s); TRequestStatus threadInitialised; modCodeThread.Rendezvous(threadInitialised); modCodeThread.Resume(); _T_PRINTF(_L("wait for child\n")); User::WaitForRequest(threadInitialised); test_KErrNone(threadInitialised.Int()); _T_PRINTF(_L("Move code chunk page repeatedly\n")); TBool success=EFalse; *(volatile TUint8*)p = *p; // Ensure the page of the first entry is paged in for the first move. for (TInt i=0; i < Repitions; i++) { TInt r = pagemove.TryMovingUserPage(firstpage, ETrue); if (i == 0) {// If this is the first run allow the modifying thread to run now // we've done one move. _T_PRINTF(_L("signal to child\n")); RThread::Rendezvous(KErrNone); } switch (r) { case KErrInUse: break; case KErrArgument: // The page was paged out, this should only happen for paged data. test(aPagedData); break; default: test_KErrNone(r); success=ETrue; break; } } test(success); ThreadDie = ETrue; User::WaitForRequest(s); test_Equal(EExitKill,modCodeThread.ExitType()); test_KErrNone(modCodeThread.ExitReason()); modCodeThread.Close(); thread.Close(); }
// Allocate Data Buffers for Read/Write Tests void AllocateBuffers() { test.Printf(_L("Allocate Buffers -")); if (gFragSharedMemory || gSharedMemory) { test.Printf(_L("Shared Memory\n")); RLoader l; test(l.Connect()==KErrNone); test(l.CancelLazyDllUnload()==KErrNone); l.Close(); test.Printf(_L("Initialise\n")); TInt r = UserHal::PageSizeInBytes(PageSize); test_KErrNone(r); test.Printf(_L("Loading test driver\n")); r = User::LoadLogicalDevice(KSharedChunkLddName); test_Value(r, r == KErrNone || r==KErrAlreadyExists); test.Printf(_L("Opening channel\n")); r = Ldd.Open(); test_KErrNone(r); test.Printf(_L("Create chunk\n")); TUint aCreateFlags = EMultiple|EOwnsMemory; TCommitType aCommitType = EContiguous; TUint TotalChunkSize = ChunkSize; // rounded to nearest Page Size TUint ChunkAttribs = TotalChunkSize|aCreateFlags; r = Ldd.CreateChunk(ChunkAttribs); test_KErrNone(r); if (gSharedMemory) { test.Printf(_L("Commit Contigouos Memory\n")); r = Ldd.CommitMemory(aCommitType,TotalChunkSize); test_KErrNone(r); } else { test.Printf(_L("Commit Fragmented Memory\n")); // Allocate Pages in reverse order to maximise memory fragmentation TUint i = ChunkSize; do { i-=PageSize; test.Printf(_L("Commit %d\n"), i); r = Ldd.CommitMemory(aCommitType|i,PageSize); test_KErrNone(r); } while (i>0); /* for (TInt i = (ChunkSize-PageSize); i>=0; ) { test.Printf(_L("Commit %d\n"), i); r = Ldd.CommitMemory(aCommitType|i,PageSize); test_KErrNone(r); i-=PageSize; } */ } test.Printf(_L("\nOpen user handle\n")); r = Ldd.GetChunkHandle(TheChunk); test_KErrNone(r); DataBuf.Set(TheChunk.Base(),KMaxFileSize, KMaxFileSize); } else { test.Printf(_L("Heap Memory\n")); DataBufH = HBufC8::New(KMaxFileSize); test(DataBufH != NULL); DataBuf.Set(DataBufH->Des()); } }
/** Fill a rectangle on the given surface. @param aSurface The surface to be filled. @param aStartPos Where to place the rectangle. @param aSize Size of the rectangle. @param aColor The colour to fill it with. */ void CSurfaceHelper::FillRectangleL(const TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor) { RSurfaceManager::TInfoBuf infoBuf; RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); TUint32 color = 0; if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) { User::Leave(KErrCorrupt); } if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) { User::Leave(KErrNotReady); } switch (info.iPixelFormat) { case EUidPixelFormatXRGB_8888: { color = aColor.Color16MU(); #ifdef ALPHA_FIX_24BIT color |= ((ALPHA_FIX_24BIT)&0xff)<<24; #endif break; } case EUidPixelFormatARGB_8888: { color = aColor.Color16MA(); break; } case EUidPixelFormatARGB_8888_PRE: { color = aColor.Color16MAP(); break; } case EUidPixelFormatRGB_565: { color = aColor.Color64K(); break; } default: { User::Leave(KErrNotSupported); break; } } RChunk chunk; User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); CleanupClosePushL(chunk); TUint8* surfacePtr = chunk.Base(); // Check for out of bounds TBool validRect = ETrue; TInt surfaceWidth = info.iSize.iWidth; TInt surfaceHeight = info.iSize.iHeight; // Width and Height if ((aStartPos.iX + aSize.iWidth) > surfaceWidth) { validRect = EFalse; } if ((aStartPos.iY + aSize.iHeight) > surfaceHeight) { validRect = EFalse; } // Starting position if ((aStartPos.iX < 0) || (aStartPos.iY < 0)) { validRect = EFalse; } if (!validRect) { User::Leave(KErrOverflow); } if (info.iPixelFormat == EUidPixelFormatRGB_565) { //2 bytes per pixel if ( info.iSize.iWidth*2>info.iStride) { User::Leave(KErrOverflow); } TInt offset; User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr + offset); // Fill the rectangle TInt yPos = aStartPos.iY; TInt xPos = aStartPos.iX; for (TInt yy = 0; yy < aSize.iHeight; ++yy) { ptr = reinterpret_cast<TUint16*>(surfacePtr + (yPos*info.iStride)); for (TInt xx = 0; xx < aSize.iWidth; ++xx) { ptr[xPos] = color; xPos++; } xPos = aStartPos.iX; yPos++; } } else { if ( info.iSize.iWidth*4>info.iStride) { User::Leave(KErrOverflow); } TInt offset; User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr + offset); // Fill the rectangle TInt yPos = aStartPos.iY; TInt xPos = aStartPos.iX; for (TInt yy = 0; yy < aSize.iHeight; ++yy) { ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride)); for (TInt xx = 0; xx < aSize.iWidth; ++xx) { ptr[xPos] = color; xPos++; } xPos = aStartPos.iX; yPos++; } } CleanupStack::PopAndDestroy(&chunk); }
LOCAL_C TInt WavRecord() { // Parse the commandline and get a filename to use TLex l(CommandLine); TParse destinationName; if (destinationName.SetNoWild(l.NextToken(),0,0)!=KErrNone) { Test.Printf(_L("No arg, skipping\r\n")); return(KErrArgument); } Test.Next(_L("Record Wav file")); // Open the file for writing TInt r; RFile destination; r = destination.Replace(Fs,destinationName.FullName(),EFileWrite); if (r!=KErrNone) { Test.Printf(_L("Open file for write failed(%d)\n"), r); return(r); } Test.Printf(_L("File opened for write\r\n")); Test.Next(_L("Preparing to record")); // Get the rate TLex cl(l.NextToken()); TUint32 tmpRate; TSoundRate rate; r = cl.Val(tmpRate,EDecimal); if (r == KErrNone && (r=SamplesPerSecondToRate(tmpRate,rate))==KErrNone) { Test.Printf(_L("Parsed rate: %d\r\n"), tmpRate); RecordFormatBuf().iRate = rate; } else { Test.Printf(_L("Parse rate failed(%d)\r\n"),r); RecordFormatBuf().iRate = ESoundRate32000Hz; } // Get number of channels TLex cl_chan(l.NextToken()); TUint32 tmpChannels; r = cl_chan.Val(tmpChannels,EDecimal); if (r == KErrNone) { Test.Printf(_L("Parsed %d channels\r\n"),tmpChannels); RecordFormatBuf().iChannels = tmpChannels; } else { Test.Printf(_L("Parse channels failed(%d)\r\n"), r); RecordFormatBuf().iChannels = 2; } RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM; // Set the record buffer configuration. RChunk chunk; TTestSharedChunkBufConfig bufferConfig; bufferConfig.iNumBuffers=4; bufferConfig.iBufferSizeInBytes=RecordBufferSizeInBytes(RecordFormatBuf()); if (RecordCapsBuf().iRequestMinSize) bufferConfig.iBufferSizeInBytes&=~(RecordCapsBuf().iRequestMinSize-1); // Keep the buffer length valid for the driver. bufferConfig.iFlags=0; PrintBufferConf(bufferConfig,Test); TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig); r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk); if (r!=KErrNone) { Test.Printf(_L("Buffer configuration not supported(%d)\r\n"),r); return(r); } // Set the audio record configuration. RxSoundDevice.SetVolume(KSoundMaxVolume); PrintConfig(RecordFormatBuf(),Test); r=RxSoundDevice.SetAudioFormat(RecordFormatBuf); if (r!=KErrNone) { Test.Printf(_L("Format not supported\r\n")); return(r); } // Get length in seconds TLex cl_seconds(l.NextToken()); TUint32 tmpSeconds; r = cl_seconds.Val(tmpSeconds,EDecimal); if (r == KErrNone) { Test.Printf(_L("Parsed %d seconds\r\n"),tmpSeconds); } else { Test.Printf(_L("Parse seconds failed(%d)\r\n"),r); tmpSeconds=10; } TInt bytesToRecord = BytesPerSecond(RecordFormatBuf())*tmpSeconds; Test.Next(_L("Recording...")); // Lay down a file header WAVEheader header; TPtr8 headerDes((TUint8 *)&header, sizeof(struct WAVEheader), sizeof(struct WAVEheader)); // "RIFF" header.ckID[0] = 'R'; header.ckID[1] = 'I'; header.ckID[2] = 'F'; header.ckID[3] = 'F'; // "WAVE" header.wave_ckID[0] = 'W'; header.wave_ckID[1] = 'A'; header.wave_ckID[2] = 'V'; header.wave_ckID[3] = 'E'; // "fmt " header.fmt_ckID[0] = 'f'; header.fmt_ckID[1] = 'm'; header.fmt_ckID[2] = 't'; header.fmt_ckID[3] = ' '; // "data" header.data_ckID[0] = 'd'; header.data_ckID[1] = 'a'; header.data_ckID[2] = 't'; header.data_ckID[3] = 'a'; header.nChannels = (TUint16)RecordFormatBuf().iChannels; header.nSamplesPerSec = RateInSamplesPerSecond(RecordFormatBuf().iRate); header.nBitsPerSample = 16; header.nBlockAlign = TUint16((RecordFormatBuf().iChannels == 2) ? 4 : 2); header.formatTag = 1; // type 1 is PCM header.fmt_ckSize = 16; header.nAvgBytesPerSec = BytesPerSecond(RecordFormatBuf()); header.data_ckSize = bytesToRecord; header.ckSize = bytesToRecord + sizeof(struct WAVEheader) - 8; Test.Printf(_L("Header rate:%d channels:%d tag:%d bits:%d (%d bytes/s) align %d datalen:%d fmt_ckSize:%d ckSize:%d\r\n"), header.nSamplesPerSec, header.nChannels, header.formatTag, header.nBitsPerSample, header.nAvgBytesPerSec, header.nBlockAlign, header.data_ckSize, header.fmt_ckSize, header.ckSize, sizeof(struct WAVEheader)); r = destination.Write(headerDes); TRequestStatus stat; TInt length; TPtrC8 buf; TTime startTime; startTime.HomeTime(); // Start off by issuing a record request. TTime starttime; starttime.HomeTime(); TInt bytesRecorded = 0; RxSoundDevice.RecordData(stat,length); TInt pausesToDo = 10; pausesToDo = 0; FOREVER { // Wait for the outstanding record request to complete. User::After(6000); User::WaitForAnyRequest(); if (stat==KRequestPending) return(KErrGeneral); TTime currentTime; currentTime.HomeTime(); TInt64 elapsedTime = currentTime.Int64()-startTime.Int64(); // us TTimeIntervalMicroSecondsBuf timeRecordedBuf; if(RxSoundDevice.TimeRecorded(timeRecordedBuf) == KErrNone) { // Compare TimeRecorded with the actual elapsed time. They should be different, but not drift apart too badly... TInt32 offset = TInt32(elapsedTime - timeRecordedBuf().Int64()); Test.Printf(_L("\telapsedTime - TimeRecorded = %d ms\n"), offset/1000); } // Check whether the record request was succesful. TInt retOffset=stat.Int(); if (retOffset<0) { Test.Printf(_L("Record failed(%d)\r\n"),retOffset); return(retOffset); } // Successfully recorded another buffer so write the recorded data to the record file and release the buffer. buf.Set((const TUint8*)(chunk.Base()+retOffset),length); r=destination.Write(buf); if (r!=KErrNone) { Test.Printf(_L("File write failed(%d)\r\n"),r); return(r); } r=RxSoundDevice.ReleaseBuffer(retOffset); if (r!=KErrNone) { Test.Printf(_L("Release buffer failed(%d)\r\n"),r); return(r); } Test.Printf(_L("Recorded %d more bytes - %d\r\n"),length,retOffset); if((pausesToDo > 0) && (bytesRecorded > bytesToRecord/2)) { --pausesToDo; Test.Printf(_L("Pause\r\n")); RxSoundDevice.Pause(); Test.Printf(_L("Paused, sleeping for 0.5 seconds\r\n")); User::After(500*1000); Test.Printf(_L("Resume\r\n")); RxSoundDevice.Resume(); } // Check whether we have now recorded all the data. If more to record then queue a further request bytesRecorded+=length; if (bytesRecorded<bytesToRecord) { Test.Printf(_L("RecordData\r\n")); RxSoundDevice.RecordData(stat,length); } else break; } RxSoundDevice.CancelRecordData(); // Stop the driver from recording. TTime endtime; endtime.HomeTime(); TInt64 elapsedTime = endtime.Int64()-starttime.Int64(); // us Test.Printf(_L("Delta time = %d\r\n"),I64LOW(elapsedTime)); Test.Printf(_L("Seconds in buffer: %d (%d)\r\n"), bytesRecorded / header.nAvgBytesPerSec, (bytesRecorded / header.nAvgBytesPerSec)*1000000); if (I64LOW(elapsedTime) <= (bytesRecorded / header.nAvgBytesPerSec)*1000000) { Test.Printf(_L("Time travelling; record took less time than it should have done\r\n")); return(KErrGeneral); } chunk.Close(); destination.Close(); Test.Printf(_L("Record finished\r\n")); return(KErrNone); }
LOCAL_C TInt WavPlay() { RChunk chunk; // Parse the commandline and get a filename to use TLex l(CommandLine); TFileName thisfile=RProcess().FileName(); TPtrC token=l.NextToken(); if (token.MatchF(thisfile)==0) token.Set(l.NextToken()); if (token.Length()==0) { // No args, skip to end Test.Printf(_L("Invalid configuration\r\n")); return(KErrArgument); } Test.Next(_L("Play Wav file")); // Assume that the argument is a WAV filename TFileName wavFilename=token; TInt r; RFile source; r = source.Open(Fs,wavFilename,EFileRead); if (r!=KErrNone) { Test.Printf(_L("Open failed(%d)\r\n"), r); return(r); } // Read the pcm header WAVEheader header; TPtr8 headerDes((TUint8 *)&header,sizeof(struct WAVEheader),sizeof(struct WAVEheader)); r = source.Read(headerDes); if (r!=KErrNone) { source.Close(); return(r); } Test.Printf(_L("Header Read %d bytes\r\n"),headerDes.Size()); if (headerDes.Size() != sizeof(struct WAVEheader)) // EOF { Test.Printf(_L("Couldn't read a header(%d bytes)\r\n"),headerDes.Size()); source.Close(); return(KErrCorrupt); } Test.Printf(_L("Header rate:%d channels:%d tag:%d bits:%d (%d bytes/s) align %d datalen:%d fmt_ckSize:%d ckSize:%d\n"), header.nSamplesPerSec, header.nChannels, header.formatTag, header.nBitsPerSample, header.nAvgBytesPerSec, header.nBlockAlign, header.data_ckSize, header.fmt_ckSize, header.ckSize); if (header.formatTag != 1) // not pcm { Test.Printf(_L("Format not PCM(%d)\r\n"),header.formatTag); source.Close(); return(KErrNotSupported); } if (header.nBitsPerSample != 16) // not 16 bit { Test.Printf(_L("Format not 16 bit PCM(%d bits)\r\n"),header.nBitsPerSample); source.Close(); return(KErrNotSupported); } TSoundRate rate; if (SamplesPerSecondToRate(header.nSamplesPerSec,rate)!=KErrNone) { Test.Printf(_L("Format specifies a rate not supported(%d)\r\n"),header.nSamplesPerSec); source.Close(); return(KErrNotSupported); } TxSoundDevice.AudioFormat(PlayFormatBuf); // Read back the current setting which must be valid. PlayFormatBuf().iChannels = header.nChannels; PlayFormatBuf().iRate = rate; PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM; // Set the play buffer configuration. TInt bufSize=BytesPerSecond(PlayFormatBuf())/8; // Large enough to hold 1/8th second of data. bufSize&=~(header.nBlockAlign-1); // Keep the buffer length a multiple of the bytes per sample (assumes 16bitPCM, 1 or 2 chans). if (PlayCapsBuf().iRequestMinSize) bufSize&=~(PlayCapsBuf().iRequestMinSize-1); // Keep the buffer length valid for the driver. TTestSharedChunkBufConfig bufferConfig; bufferConfig.iNumBuffers=3; bufferConfig.iBufferSizeInBytes=bufSize; bufferConfig.iFlags=0; PrintBufferConf(bufferConfig,Test); TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig); r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk); if (r!=KErrNone) { Test.Printf(_L("Buffer configuration not supported(%d)\r\n"),r); source.Close(); return(r); } TxSoundDevice.GetBufferConfig(bufferConfigBuf); // Read back the configuration - to get the buffer offsets CHECK(bufferConfig.iBufferSizeInBytes==bufSize); // Set the audio play configuration. TxSoundDevice.SetVolume(KSoundMaxVolume - (KSoundMaxVolume / 4)); // set volume to 75% PrintConfig(PlayFormatBuf(),Test); r=TxSoundDevice.SetAudioFormat(PlayFormatBuf); if (r!=KErrNone) { Test.Printf(_L("Format not supported\r\n")); source.Close(); chunk.Close(); return(r); } TxSoundDevice.ResetBytesTransferred(); TInt32 bytesToPlay = header.data_ckSize; TTime starttime; starttime.HomeTime(); TRequestStatus stat[3]; TPtr8* tPtr[3]; TInt i; for (i=0;i<3;i++) tPtr[i]=new TPtr8(NULL,0); TTime startTime; startTime.HomeTime(); // Start off by issuing a play request for each buffer (assuming that the file is long enough). Use the full size // of each buffer. TInt stillToRead=bytesToPlay; TInt stillNotPlayed=bytesToPlay; TUint flags; for (i=0 ; i<3 ; i++) { // Setup the descriptor for reading in the data from the file. tPtr[i]->Set(chunk.Base()+bufferConfig.iBufferOffsetList[i],0,bufSize); // If there is still data to read to play then read this into the descriptor // and then write it to the driver. if (stillToRead) { r=source.Read(*tPtr[i],Min(stillToRead,bufSize)); if (r!=KErrNone) { Test.Printf(_L("Initial file read error(%d)\r\n"),r); source.Close(); chunk.Close(); return(r); } stillToRead-=tPtr[i]->Length(); flags=(stillToRead>0)?0:KSndFlagLastSample; TxSoundDevice.PlayData(stat[i],bufferConfig.iBufferOffsetList[i],tPtr[i]->Length(),flags); } else stat[i]=KRequestPending; } FOREVER { // Wait for any one of the outstanding play requests to complete. User::WaitForAnyRequest(); TTime currentTime; currentTime.HomeTime(); TInt64 elapsedTime = currentTime.Int64()-startTime.Int64(); // us TTimeIntervalMicroSecondsBuf timePlayedBuf; if(TxSoundDevice.TimePlayed(timePlayedBuf) == KErrNone) { // Compare TimePlayed with the actual elapsed time. They should be different, but not drift apart too badly... TInt32 offset = TInt32(elapsedTime - timePlayedBuf().Int64()); Test.Printf(_L("\telapsedTime - TimePlayed = %d ms\n"), offset/1000); } // Work out which buffer this applies to for (i=0 ; i<3 ; i++) { if (stat[i]!=KRequestPending) break; } if (i>=3) { Test.Printf(_L("I/O error\r\n")); source.Close(); chunk.Close(); return(KErrGeneral); } // Check that the transfer was succesful and whether we have now played all the file. if (stat[i]!=KErrNone) { Test.Printf(_L("Play error(%d)\r\n"),stat[i].Int()); source.Close(); chunk.Close(); return(stat[i].Int()); } Test.Printf(_L("Played %d bytes(%d) - %d\r\n"),tPtr[i]->Length(),i,stat[i].Int()); stillNotPlayed-=tPtr[i]->Length(); CHECK(stillNotPlayed>=0); if (!stillNotPlayed) break; // Still more to be played so read the next part of the file into the descriptor for this // buffer and then write it to the driver. if (stillToRead) { TInt len=Min(stillToRead,bufSize); // If we've got to the end of the file and the driver is particular about the request length then // zero fill the entire buffer so we can play extra zeros after the last sample from the file. if (len<bufSize && PlayCapsBuf().iRequestMinSize) tPtr[i]->FillZ(bufSize); // Read the next part of the file r=source.Read(*tPtr[i],len); // This will alter the length of the descriptor if (r!=KErrNone) { Test.Printf(_L("File read error(%d)\r\n"),r); source.Close(); chunk.Close(); return(r); } stillToRead-=tPtr[i]->Length(); // If we've got to the end of the file and the driver is particular about the request length then // round up the length to the next valid boundary. This is OK since we zero filled. if (tPtr[i]->Length() < bufSize && PlayCapsBuf().iRequestMinSize) { TUint m=PlayCapsBuf().iRequestMinSize-1; len=(tPtr[i]->Length() + m) & ~m; } // Write it to the driver. flags=(stillToRead>0)?0:KSndFlagLastSample; TxSoundDevice.PlayData(stat[i],bufferConfig.iBufferOffsetList[i],len,flags); } else stat[i]=KRequestPending; } // Delete all the variables again. for (i=0 ; i<3 ; i++) delete tPtr[i]; TTime endtime; endtime.HomeTime(); Test.Printf(_L("Done playing\r\n")); Test.Printf(_L("Bytes played = %d\r\n"),TxSoundDevice.BytesTransferred()); Test.Printf(_L("Delta time = %d\r\n"),endtime.Int64()-starttime.Int64()); chunk.Close(); source.Close(); return(KErrNone); }
GLDEF_C TInt E32Main() { test.Title(); if (!HaveMMU()) { test.Printf(_L("This test requires an MMU\n")); return KErrNone; } test.Start(_L("Load test LDD")); TInt r=User::LoadLogicalDevice(KLddFileName); test(r==KErrNone || r==KErrAlreadyExists); test_KErrNone(UserHal::PageSizeInBytes(PageSize)); // Determine which types of paging are supported TUint32 attrs = DPTest::Attributes(); gRomPagingSupported = (attrs & DPTest::ERomPaging) != 0; gCodePagingSupported = (attrs & DPTest::ECodePaging) != 0; gDataPagingSupported = (attrs & DPTest::EDataPaging) != 0; // Does this memory model support pinning. TInt mm = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, 0, 0) & EMemModelTypeMask; gPinningSupported = mm >= EMemModelTypeFlexible; RPageMove pagemove; test.Next(_L("Open test LDD")); test_KErrNone(pagemove.Open()); // Determine whether this is a smp device. NumberOfCpus = pagemove.NumberOfCpus(); if (NumberOfCpus > 1) Repitions = 1000; // SMP system therefore likely to get KErrInUse in less repitions. test.Next(_L("Attempting to move regular local data pages")); { const TInt size=16384; TUint8* array = new TUint8[size]; test_NotNull(array); TestUserData(pagemove, array, size); _T_PRINTF(_L("Walk heap\n")); User::Check(); delete [] array; } test.Next(_L("Attempting to move regular global coarse data pages")); { const TInt size=1<<20; // Make this chunk multiple of 1MB so it is a coarse memory object on FMM RChunk chunk; test_KErrNone(chunk.CreateDisconnectedGlobal(_L("Dave"), 0, size, size)); TUint8* array = chunk.Base(); TestUserData(pagemove, array, size); TestMovingRealtime(pagemove, array, size, NULL, EFalse); TestCommitDecommit(pagemove, chunk); chunk.Close(); } if (gDataPagingSupported) { test.Next(_L("Attempting to move demand paged fine local user data pages")); const TInt size=16384; TChunkCreateInfo createInfo; createInfo.SetDisconnected(0, size, size); createInfo.SetPaging(TChunkCreateInfo::EPaged); RChunk chunk; test_KErrNone(chunk.Create(createInfo)); TUint8* array = chunk.Base(); TestUserData(pagemove, array, size, ETrue); TestMovingRealtime(pagemove, array, size, NULL, EFalse, ETrue); TestPageTableDiscard(pagemove, array, size); TestCommitDecommit(pagemove, chunk); chunk.Close(); test.Next(_L("Attempting to move demand paged coarse global user data pages")); const TInt sizeCoarse = 1 << 20; // Make this chunk multiple of 1MB so it is a coarse memory object on FMM TChunkCreateInfo createInfoCoarse; createInfoCoarse.SetDisconnected(0, sizeCoarse, sizeCoarse); createInfoCoarse.SetGlobal(_L("Dave")); createInfoCoarse.SetPaging(TChunkCreateInfo::EPaged); RChunk chunkCoarse; test_KErrNone(chunkCoarse.Create(createInfoCoarse)); array = chunkCoarse.Base(); TestUserData(pagemove, array, sizeCoarse, ETrue); TestMovingRealtime(pagemove, array, sizeCoarse, NULL, EFalse, ETrue); TestPageTableDiscard(pagemove, array, sizeCoarse); TestCommitDecommit(pagemove, chunkCoarse); chunkCoarse.Close(); } test.Next(_L("Attempting to move DLL writable static data pages")); { const TInt size=16384; TUint8* array = DllWsd::Address(); TestUserData(pagemove, array, size); } test.Next(_L("Attempting to move user self-mod code chunk page when IMB'ing and executing")); RChunk codeChunk; test_KErrNone(codeChunk.CreateLocalCode(PageSize,PageSize)); TestMovingCodeChunk(pagemove, codeChunk, EFalse); codeChunk.Close(); if (gDataPagingSupported) { test.Next(_L("Attempting to move paged user self-mod code chunk page when IMB'ing and executing")); TChunkCreateInfo createInfo; createInfo.SetCode(PageSize, PageSize); createInfo.SetPaging(TChunkCreateInfo::EPaged); RChunk pagedCodeChunk; test_KErrNone(pagedCodeChunk.Create(createInfo)); TestMovingCodeChunk(pagemove, pagedCodeChunk, ETrue); pagedCodeChunk.Close(); } test.Next(_L("Attempting to move RAM drive")); if ((MemModelAttributes()&EMemModelTypeMask) == EMemModelTypeMultiple) { for (TInt i=0; i<Repitions; i++) test_KErrNone(pagemove.TryMovingUserPage((TAny*)0xA0000000)); } else if ((MemModelAttributes()&EMemModelTypeMask) == EMemModelTypeMoving) { for (TInt i=0; i<Repitions; i++) test_KErrNone(pagemove.TryMovingUserPage((TAny*)0x40000000)); } else if ((MemModelAttributes()&EMemModelTypeMask) == EMemModelTypeFlexible) { // do nothing, RAM drive is not special } else { test.Printf(_L("Don't know where the RAM drive is!")); test(0); } #if 0 test.Next(_L("Attempting to move kernel heap pages")); for (TInt i=0; i<Repitions; i++) test_KErrNone(pagemove.TryMovingKHeap()); #endif if ((MemModelAttributes()&EMemModelTypeMask) != EMemModelTypeFlexible) {// Only the moving and multiple memory models move kernel stack pages. test.Next(_L("Attempting to move kernel stack pages")); for (TInt i=0; i<Repitions; i++) test_KErrNone(pagemove.TryMovingKStack()); } test.Next(_L("Attempting to move ROM pages")); TestMovingRom(pagemove); test.Next(_L("Attempting to move kernel code pages")); for (TInt i=0; i<Repitions; i++) test_KErrNone(pagemove.TryMovingKCode()); test.Next(_L("Attempting to move regular code pages")); TestMovingCode(pagemove, RamLoadedFunction); TestMovingRealtime(pagemove, NULL, 0, RamLoadedFunction, ETrue, EFalse); if (gCodePagingSupported) { test.Next(_L("Attempting to move demand paged code pages")); TestMovingCode(pagemove, DllTestFunction, ETrue); TestMovingRealtime(pagemove, NULL, 0, DllTestFunction, ETrue, ETrue); } /* Setup CodeModifier Test Driver */ StartCodeModifierDriver(); test(KErrNone==Device.InitialiseCodeModifier(/* Max break points */ 5 )); test.Next(_L("Attempting to move code page being modified\n")); test_KErrNone(TestCodeModification(pagemove)); test.Next(_L("Attempting to move code (async) while page being modified")); test_KErrNone(TestCodeModificationAsync(pagemove)); StopCodeModifierDriver(); test.Next(_L("Attempting to move ROM Locale DLL Page")); test_KErrNone(E32TestLocale(1)); test.Next(_L("Attempting to move RAM Locale DLL Page")); test_KErrNone(E32TestLocale(0)); test.Next(_L("Close test LDD")); pagemove.Close(); User::FreeLogicalDevice(KLddFileName); test.End(); return(KErrNone); }
inline TInt CTFontSessionCache::Base() { return reinterpret_cast<TInt>(iChunk.Base()); }
void RDmaSession::SelfTest(TBool aSimulatedDmac) { test.Start(_L("Simple transfer test")); RDmaSession session; TInt r = KErrUnknown; if (aSimulatedDmac) { test.Next(_L("Open session (simulated DMA)")); r = session.OpenSim(); } else { test.Next(_L("Open session")); r = session.Open(); } test_KErrNone(r); test.Next(_L("Get test info")); TDmaV2TestInfo testInfo; r = session.GetTestInfo(testInfo); test_KErrNone(r); if(gVerboseOutput) { Print(testInfo); } // Self test just needs 1 channel // The real test will test all available ones test.Next(_L("Select test channel")); TUint testChannel = 0; if(testInfo.iMaxSbChannels > 0) { testChannel = testInfo.iSbChannels[0]; } else if(testInfo.iMaxDbChannels > 0) { testChannel = testInfo.iDbChannels[0]; } else if(testInfo.iMaxSgChannels > 0) { testChannel = testInfo.iSgChannels[0]; } else { test.Printf(_L("Driver exposes no channels to test")); test(EFalse); } test.Printf(_L("using PSL cookie %d (0x%08x)\n"), testChannel, testChannel); test.Next(_L("Open channel")); TUint channelCookie=0; r = session.ChannelOpen(testChannel, channelCookie); test.Printf(_L("cookie recived = 0x%08x\n"), channelCookie); test_KErrNone(r); test.Next(_L("Get Channel caps")); SDmacCaps channelCaps; r = session.ChannelCaps(channelCookie, channelCaps); test_KErrNone(r); if(gVerboseOutput) { PRINT(channelCaps.iChannelPriorities); PRINT(channelCaps.iChannelPauseAndResume); PRINT(channelCaps.iAddrAlignedToElementSize); PRINT(channelCaps.i1DIndexAddressing); PRINT(channelCaps.i2DIndexAddressing); PRINT(channelCaps.iSynchronizationTypes); PRINT(channelCaps.iBurstTransactions); PRINT(channelCaps.iDescriptorInterrupt); PRINT(channelCaps.iFrameInterrupt); PRINT(channelCaps.iLinkedListPausedInterrupt); PRINT(channelCaps.iEndiannessConversion); PRINT(channelCaps.iGraphicsOps); PRINT(channelCaps.iRepeatingTransfers); PRINT(channelCaps.iChannelLinking); PRINT(channelCaps.iHwDescriptors); PRINT(channelCaps.iSrcDstAsymmetry); PRINT(channelCaps.iAsymHwDescriptors); PRINT(channelCaps.iBalancedAsymSegments); PRINT(channelCaps.iAsymCompletionInterrupt); PRINT(channelCaps.iAsymDescriptorInterrupt); PRINT(channelCaps.iAsymFrameInterrupt); PRINT(channelCaps.iReserved[0]); PRINT(channelCaps.iReserved[1]); PRINT(channelCaps.iReserved[2]); PRINT(channelCaps.iReserved[3]); PRINT(channelCaps.iReserved[4]); } test.Next(_L("Get extended Channel caps (TDmacTestCaps)")); TDmacTestCaps extChannelCaps; r = session.ChannelCaps(channelCookie, extChannelCaps); test_KErrNone(r); test.Printf(_L("PIL version = %d\n"), extChannelCaps.iPILVersion); const TBool newPil = (extChannelCaps.iPILVersion > 1); test.Next(_L("Create Dma request - max fragment size 32K")); TUint reqCookie=0; r = session.RequestCreateOld(channelCookie, reqCookie, 32 * KKilo); test.Printf(_L("cookie recived = 0x%08x\n"), reqCookie); test_KErrNone(r); if(newPil) { test.Next(_L("Create Dma request (with new-style callback)")); TUint reqCookieNewStyle=0; r = session.RequestCreate(channelCookie, reqCookieNewStyle); test.Printf(_L("cookie recived = 0x%08x\n"), reqCookieNewStyle ); test_KErrNone(r); if(!aSimulatedDmac) { test.Next(_L("Fragment for ISR callback")); const TInt size = 128 * KKilo; TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr); r = session.FragmentRequest(reqCookieNewStyle, transferArgs); test_KErrNone(r); TIsrRequeArgs reque; test.Next(_L("Queue ISR callback - with default re-queue")); r = session.QueueRequestWithRequeue(reqCookieNewStyle, &reque, 1); test_KErrNone(r); } test.Next(_L("Destroy new-style Dma request")); r = session.RequestDestroy(reqCookieNewStyle); test_KErrNone(r); test.Next(_L("Attempt to destroy request again ")); r = session.RequestDestroy(reqCookieNewStyle); test_Equal(KErrNotFound, r); } test.Next(_L("Open chunk handle")); RChunk chunk; r = session.OpenSharedChunk(chunk); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("chunk base = 0x%08x\n"), chunk.Base()); test.Printf(_L("chunk size = %d\n"), chunk.Size()); } test(chunk.IsWritable()); test(chunk.IsReadable()); if(!aSimulatedDmac) { test.Next(_L("Fragment(old style)")); const TInt size = 128 * KKilo; TInt i; for(i = 0; i<10; i++) { TUint64 time = 0; TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr); r = session.FragmentRequestOld(reqCookie, transferArgs, &time); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } test.Next(_L("Queue")); TRequestStatus status; for(i = 0; i<10; i++) { TUint64 time = 0; r = session.QueueRequest(reqCookie, status, 0, &time); User::WaitForRequest(status); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } if(newPil) { test.Next(_L("Fragment(new style)")); TDmaTransferArgs transferArgs; transferArgs.iSrcConfig.iAddr = 0; transferArgs.iDstConfig.iAddr = size; transferArgs.iSrcConfig.iFlags = KDmaMemAddr; transferArgs.iDstConfig.iFlags = KDmaMemAddr; transferArgs.iTransferCount = size; for(i = 0; i<10; i++) { TUint64 time = 0; r = session.FragmentRequest(reqCookie, transferArgs, &time); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } } test.Next(_L("Queue")); TCallbackRecord record; r = session.QueueRequest(reqCookie, &record); test_KErrNone(r); test.Next(_L("check TCallbackRecord record")); if(gVerboseOutput) { record.Print(); } const TCallbackRecord expected(TCallbackRecord::EThread, 1); if(!(record == expected)) { test.Printf(_L("TCallbackRecords did not match")); if(gVerboseOutput) { test.Printf(_L("expected:")); expected.Print(); } TEST_FAULT; } } test.Next(_L("Destroy Dma request")); r = session.RequestDestroy(reqCookie); test_KErrNone(r); test.Next(_L("Close chunk handle")); chunk.Close(); test.Next(_L("Channel close")); r = session.ChannelClose(channelCookie); test_KErrNone(r); test.Next(_L("Channel close (same again)")); r = session.ChannelClose(channelCookie); test_Equal(KErrNotFound, r); test.Next(_L("Close session")); RTest::CloseHandleAndWaitForDestruction(session); test.End(); }
GLDEF_C TInt E32Main() { __UHEAP_MARK; Test.Title(); TInt r; Test.Start(_L("Load sound PDD")); r=User::LoadPhysicalDevice(KSndPddFileName); if (r==KErrNotFound) { Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n")); Test.End(); Test.Close(); __UHEAP_MARKEND; return(KErrNone); } Test(r==KErrNone || r==KErrAlreadyExists); Test.Next(_L("Load sound LDD")); r=User::LoadLogicalDevice(KSndLddFileName); Test(r==KErrNone || r==KErrAlreadyExists); /** @SYMTestCaseID PBASE-T_SOUNDMCHAN-224 @SYMTestCaseDesc Opening the channel - more than one channel @SYMTestPriority Critical @SYMTestActions 1) With the LDD and PDD installed and with all channels closed on the device, open a channel for playback on the device. 2) Without closing the first playback channel, attempt to open a second channel for playback on the same device. @SYMTestExpectedResults 1) KErrNone - Channel opens successfully. 2) Should fail with KErrInUse. @SYMREQ PREQ1073.4 */ __KHEAP_MARK; Test.Next(_L("Open a channel on the play device")); RSoundSc snddev; r=snddev.Open(KSoundScTxUnit0); Test(r==KErrNone); Test.Next(_L("Try opening the same unit a second time.")); RSoundSc snddev2; r=snddev2.Open(KSoundScTxUnit0); Test(r==KErrInUse); Test.Next(_L("Query play formats supported")); TSoundFormatsSupportedV02Buf capsBuf; snddev.Caps(capsBuf); TSoundFormatsSupportedV02& caps=capsBuf(); PrintCaps(caps,Test); Test.Next(_L("Try playing without setting the buffer config")); TRequestStatus pStat; snddev.PlayData(pStat,0,0x2000); // 8K User::WaitForRequest(pStat); Test(pStat.Int()==KErrNotReady); Test.Next(_L("Configure the channel from a 2nd thread")); RThread thread; TRequestStatus tStat; SSecondaryThreadInfo sti; sti.iTestId=ESecThreadConfigPlayback; sti.iThreadId=RThread().Id(); // Get the ID of this thread sti.iDrvHandle=snddev.Handle(); // Pass the channel handle /** @SYMTestCaseID PBASE-T_SOUNDMCHAN-225 @SYMTestCaseDesc Opening the channel - sharing the handle between threads @SYMTestPriority Critical @SYMTestActions 1) With the LDD and PDD installed and with all channels closed on the device, open a channel for playback on the device. Now create a second thread. Resume this thread - passing the handle to the playback channel to it. Wait for the second thread to terminate. 2) In the second thread, duplicate the playback channel handle. 3) In the second thread, using the duplicated handle, issue a request to set the audio configuration. 4) In the second thread, using the duplicated handle, issue a request to set the volume. 5) In the second thread, close the handle and exit the thread. 6) In the first thread, read back the audio configuration. 7) In the first thread, set the buffer configuration, and then issue a request to play audio data. 8) In the first thread, close the channel. @SYMTestExpectedResults 1) KErrNone - Channel opens successfully. 2) KErrNone - Duplication of the handle succeeds. 3) KErrNone - Audio configured successfully. 4) KErrNone - Volume set successfully. 5) No errors occur closing the channel and exiting the thread. 6) The audio configuration should correspond to that set by the second thread. 7) KErrNone - Setting the buffer configuration and issuing a play request. 8) No errors occur closing the channel. @SYMREQ PREQ1073.4 */ r=thread.Create(_L("Thread"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); // Create secondary thread Test(r==KErrNone); thread.Logon(tStat); thread.Resume(); User::WaitForRequest(tStat); Test(tStat.Int()==KErrNone); // Test.Printf(_L("Thread exit info: Cat:%S, Reason:%x, Type:%d\r\n"),&thread.ExitCategory(),thread.ExitReason(),thread.ExitType()); Test(thread.ExitType()==EExitKill); thread.Close(); User::After(10000); // Wait 10ms Test.Next(_L("Read back the play configuration")); TCurrentSoundFormatV02Buf formatBuf; snddev.AudioFormat(formatBuf); TCurrentSoundFormatV02& format=formatBuf(); PrintConfig(format,Test); Test.Next(_L("Set the buffer configuration")); RChunk chunk; TInt bufSize=BytesPerSecond(formatBuf()); // Large enough to hold 1 second of data. bufSize=ValidBufferSize(bufSize,caps.iRequestMinSize,formatBuf()); // Keep the buffer length valid for driver. TTestSharedChunkBufConfig bufferConfig; bufferConfig.iNumBuffers=1; bufferConfig.iBufferSizeInBytes=bufSize; bufferConfig.iFlags=0; TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig); r=snddev.SetBufferChunkCreate(bufferConfigBuf,chunk); Test(r==KErrNone); snddev.GetBufferConfig(bufferConfigBuf); PrintBufferConf(bufferConfig,Test); Test(bufferConfig.iBufferSizeInBytes==bufSize); Test.Next(_L("Start playing")); r=MakeSineTable(format); Test(r==KErrNone); r=SetToneFrequency(660,format); Test(r==KErrNone); TPtr8 ptr(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize); WriteTone(ptr,format); snddev.PlayData(pStat,bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample); User::WaitForRequest(pStat); Test(tStat.Int()==KErrNone); Test.Next(_L("Close the drivers and the chunk")); chunk.Close(); snddev.Close(); __KHEAP_MARKEND; Test.Next(_L("Unload the drivers")); r=User::FreeLogicalDevice(KDevSoundScName); Test.Printf(_L("Unloading %S.LDD - %d\r\n"),&KDevSoundScName,r); Test(r==KErrNone); TName pddName(KDevSoundScName); _LIT(KPddWildcardExtension,".*"); pddName.Append(KPddWildcardExtension); TFindPhysicalDevice findPD(pddName); TFullName findResult; r=findPD.Next(findResult); while (r==KErrNone) { r=User::FreePhysicalDevice(findResult); Test.Printf(_L("Unloading %S.PDD - %d\r\n"),&findResult,r); Test(r==KErrNone); findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container. r=findPD.Next(findResult); } Test.End(); Test.Close(); Cleanup(); __UHEAP_MARKEND; return(KErrNone); }
void ClearChunk( RChunk& aChunk, TInt aFlags ) { TCatalogsDebugChunkHeader* header = (TCatalogsDebugChunkHeader*)aChunk.Base(); header->iFlags = aFlags; header->iOffset = 0; }
TVerdict CTEventHandlingPerf::doTestStepL() { /** @SYMTestCaseID GRAPHICS-UI-BENCH-0172 */ SetTestStepID(_L("GRAPHICS-UI-BENCH-0172")); TBuf<KMaxDescLength> bufAvg; TPtr temp(NULL,0); TPtr temp1(NULL,0); TPtr temp2(NULL,0); // Here check if the HAL configuration are correct if not then finish the test case TInt maxPtr; TInt ret = HAL::Get(HALData::EPointerMaxPointers, maxPtr); if (ret != KErrNone || maxPtr < 2 || maxPtr > 8) { INFO_PRINTF1(_L("Incorrect HAL configuration. \n")); SetTestStepResult(EFail); CloseTMSGraphicsStep(); RecordTestResultL(); return TestStepResult(); } iProfiler->InitResults(); TInt minMemSize = 128; TInt maxMemSize = KMaxDescLength; // Create a shared chunk using the userheap function // Allocate some memory in that and then get the offset from it - chunk's base _LIT(KPerformanceTimingChunk, "PerformanceTimingChunk"); RHeap* heap = UserHeap::ChunkHeap(&KPerformanceTimingChunk, minMemSize, maxMemSize, 10); CleanupClosePushL(*heap); if (heap == NULL) { User::LeaveNoMemory(); } RChunk chunk; User::LeaveIfError(chunk.OpenGlobal(KPerformanceTimingChunk, ETrue)); CleanupClosePushL(chunk); TInt memSize = KMaxDescLength; TAny* perfDesc = heap->AllocL(memSize); if (!perfDesc) { User::LeaveNoMemory(); } TInt offset = reinterpret_cast<TUint8*>(perfDesc) - chunk.Base() ; // Create a process called te_multiptrperf // Pass in the offset as descriptor _LIT(KMultiPtrEventHandlingPerf,"z:\\sys\\bin\\te_multiptrperf.exe"); TBuf<128> buf; buf.Num(offset); RProcess eventHandPerf; User::LeaveIfError(eventHandPerf.Create(KMultiPtrEventHandlingPerf, buf)); TRequestStatus stat; eventHandPerf.Logon(stat); eventHandPerf.Resume(); User::WaitForRequest(stat); eventHandPerf.Close(); // Once the process finished its execution print the result by // reading the data from chunk's memory TPtr8 ptrDes((TUint8*)perfDesc, memSize, memSize); TPtr8 ptrDesDisplay((TUint8*)perfDesc, memSize, memSize); // If it has failed then just print description written in the same // when it is failed description contains '*' at the end TInt lastChar = 0; lastChar = ptrDes.Locate('*'); if (KErrNotFound != lastChar) { SetTestStepResult(EFail); TPtr8 temp = ptrDesDisplay.LeftTPtr(lastChar); TBuf<128> buf; buf.Copy(temp); INFO_PRINTF2(_L("%S"), &buf); RDebug::RawPrint(temp); goto END; } // If it has skipped then just print skip description from the chunk // when it is skipped description contains '#' at the end lastChar = ptrDes.Locate('#'); if (KErrNotFound != lastChar) { SetTestStepResult(EPass); TPtr8 temp = ptrDesDisplay.LeftTPtr(lastChar); TBuf<128> buf; buf.Copy(temp); INFO_PRINTF2(_L("%S"), &buf); RDebug::RawPrint(temp); goto END; } // If the every thing goes fine the descriptor is displayed as // "12345678,123456789,123456789" TInt avg4Events, avg8Events, avg16Events, avg32Events; bufAvg.Copy(ptrDesDisplay); for (TInt i=0; i<4; i++) { TInt locate = bufAvg.Locate(','); if (locate == KErrNotFound) { SetTestStepResult(EFail); goto END; } TLex lex(bufAvg.Left(locate)); lex.Val(avg4Events); locate++; temp.Set(bufAvg.MidTPtr(locate)); locate = temp.Locate(','); if (locate == KErrNotFound) { SetTestStepResult(EFail); goto END; } lex = temp.Left(locate); lex.Val(avg8Events); locate++; temp1.Set(temp.MidTPtr(locate)); locate = temp1.Locate(','); if (locate == KErrNotFound) { SetTestStepResult(EFail); goto END; } lex = temp.Left(locate); lex.Val(avg16Events); locate++; temp2.Set(temp1.MidTPtr(locate)); locate = temp2.Locate(','); if (locate == KErrNotFound) { SetTestStepResult(EFail); goto END; } lex = temp2.Left(locate); lex.Val(avg32Events); locate++; bufAvg.Copy(temp2.MidTPtr(locate)); switch (i) { case 0: INFO_PRINTF5(_L("TID: Average time for Single pointer(wait after each event) for 4 events:%i 8 events:%i 16 events:%i 32events:%i"), avg4Events, avg8Events, avg16Events, avg32Events); break; case 1: INFO_PRINTF5(_L("TID: Average time for Multi pointer(wait after each event) for 4 events:%i 8 events:%i 16 events:%i 32events:%i"), avg4Events, avg8Events, avg16Events, avg32Events); break; case 2: INFO_PRINTF5(_L("TID: Average time for single pointer for 4 events:%i 8 events:%i 16 events:%i 32events:%i"), avg4Events, avg8Events, avg16Events, avg32Events); break; case 3: INFO_PRINTF5(_L("TID: Average time for Multi pointer for 4 events:%i 8 events:%i 16 events:%i 32events:%i"), avg4Events, avg8Events, avg16Events, avg32Events); SetTestStepResult(EPass); break; default: break; } } iProfiler->ResultsAnalysis(KEventHandlingPerfName, 0, EColor16MA, EColor16MA, 1); END: // Once the data is printed or displyed delete the memory heap->Free(perfDesc); CleanupStack::PopAndDestroy(2, heap); RecordTestResultL(); CloseTMSGraphicsStep(); return TestStepResult(); }