1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of the License "Eclipse Public License v1.0" |
4 // under the terms of the License "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
312 return(KThreadReturnValue); |
312 return(KThreadReturnValue); |
313 User::After(500000); |
313 User::After(500000); |
314 return(KErrNone); |
314 return(KErrNone); |
315 } |
315 } |
316 |
316 |
317 TInt StartInstructionThread(RThread& aT, const TDesC& aName, TInt aInstruction, TOwnerType aOwnerType, TRequestStatus* aL, TRequestStatus* aR) |
317 TInt StartInstructionThread(RThread& aT, const TDesC& aName, TInt aInstruction, RAllocator* aAllocator, TOwnerType aOwnerType, TRequestStatus* aL, TRequestStatus* aR) |
318 { |
318 { |
319 TInt r = aT.Create(aName, &InstructionThread, KDefaultStackSize, KHeapSize, KHeapSize, (TAny*)aInstruction, aOwnerType); |
319 TInt r; |
|
320 |
|
321 if (aAllocator == NULL) |
|
322 { |
|
323 r = aT.Create(aName, &InstructionThread, KDefaultStackSize, KHeapSize, KHeapSize, (TAny*)aInstruction, aOwnerType); |
|
324 } |
|
325 else |
|
326 { |
|
327 r = aT.Create(aName, &InstructionThread, KDefaultStackSize, aAllocator, (TAny*)aInstruction, aOwnerType); |
|
328 } |
|
329 |
320 if (r!=KErrNone) |
330 if (r!=KErrNone) |
321 return r; |
331 return r; |
|
332 |
322 if (aL) |
333 if (aL) |
323 { |
334 { |
324 aT.Logon(*aL); |
335 aT.Logon(*aL); |
325 TInt s = aL->Int(); |
336 TInt s = aL->Int(); |
326 test_Equal(s, KRequestPending); |
337 test_Equal(s, KRequestPending); |
327 } |
338 } |
|
339 |
328 if (aR) |
340 if (aR) |
329 { |
341 { |
330 aT.Rendezvous(*aR); |
342 aT.Rendezvous(*aR); |
331 TInt s = aR->Int(); |
343 TInt s = aR->Int(); |
332 test_Equal(s, KRequestPending); |
344 test_Equal(s, KRequestPending); |
333 aT.Resume(); |
345 aT.Resume(); |
334 User::WaitForRequest(*aR); |
346 User::WaitForRequest(*aR); |
335 s = aR->Int(); |
347 s = aR->Int(); |
336 test_KErrNone(s); |
348 test_KErrNone(s); |
337 } |
349 } |
|
350 |
338 return r; |
351 return r; |
339 } |
352 } |
340 |
353 |
341 |
354 |
342 LOCAL_D TInt test4Thread(TAny *aSem) |
355 LOCAL_D TInt test4Thread(TAny *aSem) |
402 |
415 |
403 test.Start(_L("Close without create")); |
416 test.Start(_L("Close without create")); |
404 thread.Close(); |
417 thread.Close(); |
405 |
418 |
406 test.Next(_L("Create ENormal")); |
419 test.Next(_L("Create ENormal")); |
407 r = StartInstructionThread(thread, _L("Thread"), ENormal, EOwnerProcess, 0, 0); |
420 r = StartInstructionThread(thread, _L("Thread"), ENormal, NULL, EOwnerProcess, 0, 0); |
408 test_KErrNone(r); |
421 test_KErrNone(r); |
409 |
422 |
410 test.Next(_L("Test priorities")); |
423 test.Next(_L("Test priorities")); |
411 test(thread.Priority()==EPriorityNormal); |
424 test(thread.Priority()==EPriorityNormal); |
412 thread.SetPriority(EPriorityRealTime); // WINS will commute this to EPriorityMuchMore |
425 thread.SetPriority(EPriorityRealTime); // WINS will commute this to EPriorityMuchMore |
545 |
558 |
546 test.Start(_L("Run thread 10 times")); |
559 test.Start(_L("Run thread 10 times")); |
547 for (TInt xx=0;xx<10;xx++) |
560 for (TInt xx=0;xx<10;xx++) |
548 { |
561 { |
549 test.Printf(_L("\r%02d"),xx); |
562 test.Printf(_L("\r%02d"),xx); |
550 r = StartInstructionThread(thread, _L("Thread1"), ENormal, anOwnerType, &stat, 0); |
563 r = StartInstructionThread(thread, _L("Thread1"), ENormal, NULL, anOwnerType, &stat, 0); |
551 test_KErrNone(r); |
564 test_KErrNone(r); |
552 thread.Resume(); |
565 thread.Resume(); |
553 User::WaitForRequest(stat); |
566 User::WaitForRequest(stat); |
554 CLOSE_AND_WAIT(thread); |
567 CLOSE_AND_WAIT(thread); |
555 } |
568 } |
556 test.Printf(_L("\n")); |
569 test.Printf(_L("\n")); |
557 |
570 |
558 test.Next(_L("Panic within thread")); |
571 test.Next(_L("Panic within thread")); |
559 r = StartInstructionThread(thread, _L("Thread2"), EInstrPanic, anOwnerType, &stat, 0); |
572 r = StartInstructionThread(thread, _L("Thread2"), EInstrPanic, NULL, anOwnerType, &stat, 0); |
560 test_KErrNone(r); |
573 test_KErrNone(r); |
561 test(thread.ExitType()==EExitPending); |
574 test(thread.ExitType()==EExitPending); |
562 thread.Resume(); |
575 thread.Resume(); |
563 User::WaitForRequest(stat); |
576 User::WaitForRequest(stat); |
564 test(thread.ExitCategory()==_L("Hello")); |
577 test(thread.ExitCategory()==_L("Hello")); |
568 |
581 |
569 test.Next(_L("Panic external to thread")); |
582 test.Next(_L("Panic external to thread")); |
570 TInt ijk; |
583 TInt ijk; |
571 TUint seed[2] = { 0xadf85458, 0 }; |
584 TUint seed[2] = { 0xadf85458, 0 }; |
572 TUint maxcount = 0; |
585 TUint maxcount = 0; |
|
586 RHeap* temporaryHeap = User::ChunkHeap(NULL, KHeapSize*8192, KHeapSize*8192); |
|
587 test(temporaryHeap != NULL); |
573 for (ijk=0; ijk<8192; ++ijk) |
588 for (ijk=0; ijk<8192; ++ijk) |
574 { |
589 { |
575 if (!(ijk&255)) |
590 if (!(ijk&255)) |
576 test.Printf(_L("%d\n"), ijk); |
591 test.Printf(_L("%d\n"), ijk); |
577 r = StartInstructionThread(thread, _L("Thread3"), EWait, anOwnerType, &stat, 0); |
592 |
|
593 // |
|
594 // For this test we need to use a temporary heap created in advance as we |
|
595 // will be panicking the thread at any point during its creation and since |
|
596 // the heap would have been allocated by the user side thread, it is |
|
597 // possible that if we let it allocate its own heap, the kernel may not |
|
598 // be able to close it in the temporary states of creation or when |
|
599 // TLocalThreadData::DllSetTls() grabs a temporary handle on the heap. |
|
600 // In those cases RTest::CloseHandleAndWaitForDestruction() would timeout |
|
601 // and the test would fail. |
|
602 // |
|
603 // In addition, if we shared the creating thread's heap allocations may |
|
604 // be left behind and cause the heap mark test to fail on this thread. |
|
605 // |
|
606 r = StartInstructionThread(thread, _L("Thread3"), EWait, temporaryHeap, anOwnerType, &stat, 0); |
578 test_KErrNone(r); |
607 test_KErrNone(r); |
579 __e32_atomic_store_ord32(&IFLAG, 0); |
608 __e32_atomic_store_ord32(&IFLAG, 0); |
580 thread.Resume(); |
609 thread.Resume(); |
581 thread.SetPriority(EPriorityMore); |
610 thread.SetPriority(EPriorityMore); |
582 if (maxcount==0) |
611 if (maxcount==0) |
602 test(thread.ExitReason()==123); |
631 test(thread.ExitReason()==123); |
603 test(thread.ExitType()==EExitPanic); |
632 test(thread.ExitType()==EExitPanic); |
604 r = RTest::CloseHandleAndWaitForDestruction(thread); |
633 r = RTest::CloseHandleAndWaitForDestruction(thread); |
605 test_KErrNone(r); |
634 test_KErrNone(r); |
606 } |
635 } |
|
636 temporaryHeap->Close(); |
607 |
637 |
608 test.Next(_L("Internal exit")); |
638 test.Next(_L("Internal exit")); |
609 r = StartInstructionThread(thread, _L("Thread4"), ENormal, anOwnerType, &stat, 0); |
639 r = StartInstructionThread(thread, _L("Thread4"), ENormal, NULL, anOwnerType, &stat, 0); |
610 test_KErrNone(r); |
640 test_KErrNone(r); |
611 test(thread.ExitType()==EExitPending); |
641 test(thread.ExitType()==EExitPending); |
612 thread.Resume(); |
642 thread.Resume(); |
613 User::WaitForRequest(stat); |
643 User::WaitForRequest(stat); |
614 test(thread.ExitCategory()==_L("Kill")); |
644 test(thread.ExitCategory()==_L("Kill")); |
615 test(thread.ExitReason()==KThreadReturnValue); |
645 test(thread.ExitReason()==KThreadReturnValue); |
616 test(thread.ExitType()==EExitKill); |
646 test(thread.ExitType()==EExitKill); |
617 CLOSE_AND_WAIT(thread); |
647 CLOSE_AND_WAIT(thread); |
618 |
648 |
619 test.Next(_L("External terminate")); |
649 test.Next(_L("External terminate")); |
620 r = StartInstructionThread(thread, _L("Thread5"), EWait, anOwnerType, &stat, &rstat); |
650 r = StartInstructionThread(thread, _L("Thread5"), EWait, NULL, anOwnerType, &stat, &rstat); |
621 test_KErrNone(r); |
651 test_KErrNone(r); |
622 test.Next(_L("Terminate")); |
652 test.Next(_L("Terminate")); |
623 thread.Terminate(KTerminationReason); |
653 thread.Terminate(KTerminationReason); |
624 test.Next(_L("Wait")); |
654 test.Next(_L("Wait")); |
625 User::WaitForRequest(stat); |
655 User::WaitForRequest(stat); |
628 test(thread.ExitType()==EExitTerminate); |
658 test(thread.ExitType()==EExitTerminate); |
629 test.Next(_L("Close")); |
659 test.Next(_L("Close")); |
630 CLOSE_AND_WAIT(thread); |
660 CLOSE_AND_WAIT(thread); |
631 |
661 |
632 test.Next(_L("External kill")); |
662 test.Next(_L("External kill")); |
633 r = StartInstructionThread(thread, _L("Thread6"), EWait, anOwnerType, &stat, &rstat); |
663 r = StartInstructionThread(thread, _L("Thread6"), EWait, NULL, anOwnerType, &stat, &rstat); |
634 test_KErrNone(r); |
664 test_KErrNone(r); |
635 thread.Suspend(); |
665 thread.Suspend(); |
636 thread.Resume(); |
666 thread.Resume(); |
637 thread.Kill(KKillReason); |
667 thread.Kill(KKillReason); |
638 User::WaitForRequest(stat); |
668 User::WaitForRequest(stat); |