nss: upgrade to release 3.73
[LibreOffice.git] / sal / qa / osl / process / osl_Thread.cxx
blobd551f471d9893bdd20a6a595e3f22b9b770e4f7d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <algorithm>
21 #ifdef _WIN32
22 #if !defined WIN32_LEAN_AND_MEAN
23 # define WIN32_LEAN_AND_MEAN
24 #endif
25 #include <windows.h>
26 #else
27 #include <unistd.h>
28 #include <time.h>
29 #endif
31 // include files
33 #include <sal/types.h>
34 #include <rtl/string.hxx>
35 #include <rtl/strbuf.hxx>
36 #include <osl/thread.hxx>
37 #include <osl/mutex.hxx>
38 #include <osl/time.h>
40 #include <string.h>
41 #include <memory>
43 #include <cppunit/TestFixture.h>
44 #include <cppunit/extensions/HelperMacros.h>
45 #include <cppunit/plugin/TestPlugIn.h>
47 #define t_print printf
49 using namespace osl;
51 namespace {
53 // Small stopwatch
54 class StopWatch {
55 TimeValue t1,t2; // Start and stoptime
57 protected:
58 sal_Int32 m_nNanoSec;
59 sal_Int32 m_nSeconds;
61 bool m_bIsValid; // TRUE, when started and stopped
62 bool m_bIsRunning; // TRUE, when started
64 public:
65 StopWatch();
67 void start(); // Starts time
68 void stop(); // Stops time
70 double getSeconds() const;
71 double getTenthSec() const;
76 // ================================= Stop Watch =================================
78 // A small stopwatch for internal use
79 // (c) Lars Langhans 29.12.1996 22:10
81 StopWatch::StopWatch()
82 : m_nNanoSec(0)
83 , m_nSeconds(0)
84 , m_bIsValid(false)
85 , m_bIsRunning(false)
87 t1.Seconds = 0;
88 t1.Nanosec = 0;
89 t2.Seconds = 0;
90 t2.Nanosec = 0;
93 void StopWatch::start()
95 // pre: %
96 // post: Start Timer
98 m_bIsValid = false;
99 m_bIsRunning = true;
100 osl_getSystemTime( &t1 );
101 t_print("# %u %u nsecs\n", static_cast<unsigned>(t1.Seconds), static_cast<unsigned>(t1.Nanosec));
102 // gettimeofday(&t1, 0);
105 void StopWatch::stop()
107 // pre: Timer should be started
108 // post: Timer will stopped
110 osl_getSystemTime( &t2 );
111 t_print("# %u %u nsecs\n", static_cast<unsigned>(t2.Seconds), static_cast<unsigned>(t2.Nanosec));
113 if (m_bIsRunning)
114 { // check if started.
115 m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
116 if ( t2.Nanosec > t1.Nanosec )
117 m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
118 else
120 m_nNanoSec = 1000000000 + static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
121 m_nSeconds -= 1;
123 t_print("# %u %u nsecs\n", static_cast<unsigned>(m_nSeconds), static_cast<unsigned>(m_nNanoSec) );
124 m_bIsValid = true;
125 m_bIsRunning = false;
129 double StopWatch::getSeconds() const
131 // pre: valid = TRUE
132 // BACK: time in seconds
134 double nValue = 0.0;
135 if (m_bIsValid)
137 nValue = double(m_nNanoSec) / 1000000000.0 + m_nSeconds; // milli micro nano
139 return nValue;
142 double StopWatch::getTenthSec() const
144 double nValue = 0.0;
145 if (m_bIsValid)
147 nValue = double(m_nNanoSec) / 100000000.0 + m_nSeconds * 10;
149 return nValue ;
152 namespace {
154 template <class T>
155 class ThreadSafeValue
157 T m_nFlag;
158 Mutex m_aMutex;
159 public:
160 explicit ThreadSafeValue(T n = 0): m_nFlag(n) {}
161 T getValue()
163 //block if already acquired by another thread.
164 osl::MutexGuard g(m_aMutex);
165 return m_nFlag;
167 void incValue()
169 //only one thread operate on the flag.
170 osl::MutexGuard g(m_aMutex);
171 m_nFlag++;
173 void acquire() {m_aMutex.acquire();}
174 void release() {m_aMutex.release();}
179 namespace ThreadHelper
181 static void thread_sleep_tenth_sec(sal_Int32 _nTenthSec)
183 osl::Thread::wait(std::chrono::milliseconds(_nTenthSec * 100));
186 static void outputPriority(oslThreadPriority const& _aPriority)
188 // LLA: output the priority
189 if (_aPriority == osl_Thread_PriorityHighest)
191 t_print("Prio is High\n");
193 else if (_aPriority == osl_Thread_PriorityAboveNormal)
195 t_print("Prio is above normal\n");
197 else if (_aPriority == osl_Thread_PriorityNormal)
199 t_print("Prio is normal\n");
201 else if (_aPriority == osl_Thread_PriorityBelowNormal)
203 t_print("Prio is below normal\n");
205 else if (_aPriority == osl_Thread_PriorityLowest)
207 t_print("Prio is lowest\n");
209 else
211 t_print("Prio is unknown\n");
216 namespace {
218 /** Simple thread for testing Thread-create.
220 Just add 1 of value 0, and after running, result is 1.
222 class myThread : public Thread
224 ThreadSafeValue<sal_Int32> m_aFlag;
225 public:
226 sal_Int32 getValue() { return m_aFlag.getValue(); }
227 protected:
228 /** guarded value which initialized 0
230 @see ThreadSafeValue
232 void SAL_CALL run() override
234 while(schedule())
236 m_aFlag.incValue();
237 ThreadHelper::thread_sleep_tenth_sec(1);
241 public:
243 virtual void SAL_CALL suspend() override
245 m_aFlag.acquire();
246 ::osl::Thread::suspend();
247 m_aFlag.release();
250 virtual ~myThread() override
252 if (isRunning())
254 t_print("error: not terminated.\n");
260 /** Thread which has a flag add 1 every second until 20
262 class OCountThread : public Thread
264 ThreadSafeValue<sal_Int32> m_aFlag;
265 public:
266 OCountThread() : m_nWaitSec(0)
268 t_print("new OCountThread thread %u!\n", static_cast<unsigned>(getIdentifier()));
270 sal_Int32 getValue() { return m_aFlag.getValue(); }
272 void setWait(sal_Int32 nSec)
274 m_nWaitSec = nSec;
275 //m_bWait = sal_True;
278 virtual void SAL_CALL suspend() override
280 m_aFlag.acquire();
281 ::osl::Thread::suspend();
282 m_aFlag.release();
285 protected:
286 //sal_Bool m_bWait;
287 sal_Int32 m_nWaitSec;
289 void SAL_CALL run() override
291 /// if the thread should terminate, schedule return false
292 while (m_aFlag.getValue() < 20 && schedule())
294 m_aFlag.incValue();
295 ThreadHelper::thread_sleep_tenth_sec(1);
297 if (m_nWaitSec != 0)
299 TimeValue nTV;
300 nTV.Seconds = m_nWaitSec / 10 ;
301 nTV.Nanosec = ( m_nWaitSec%10 ) * 100000000 ;
302 wait( nTV );
303 m_nWaitSec = 0;
307 void SAL_CALL onTerminated() override
309 t_print("normally terminate this thread %u!\n", static_cast<unsigned>(getIdentifier()));
311 public:
313 virtual ~OCountThread() override
315 if (isRunning())
317 t_print("error: not terminated.\n");
323 /** no call schedule in the run method
325 class ONoScheduleThread : public Thread
327 ThreadSafeValue<sal_Int32> m_aFlag;
328 public:
329 sal_Int32 getValue() { return m_aFlag.getValue(); }
331 virtual void SAL_CALL suspend() override
333 m_aFlag.acquire();
334 ::osl::Thread::suspend();
335 m_aFlag.release();
337 protected:
338 void SAL_CALL run() override
340 while (m_aFlag.getValue() < 10)
342 m_aFlag.incValue();
343 ThreadHelper::thread_sleep_tenth_sec(1);
346 void SAL_CALL onTerminated() override
348 t_print("normally terminate this thread %u!\n", static_cast<unsigned>(getIdentifier()));
350 public:
351 ONoScheduleThread()
353 t_print("new thread id %u!\n", static_cast<unsigned>(getIdentifier()));
355 virtual ~ONoScheduleThread() override
357 if (isRunning())
359 t_print("error: not terminated.\n");
366 class OAddThread : public Thread
368 ThreadSafeValue<sal_Int32> m_aFlag;
369 public:
370 //oslThreadIdentifier m_id, m_CurId;
371 OAddThread(){}
372 sal_Int32 getValue() { return m_aFlag.getValue(); }
374 virtual void SAL_CALL suspend() override
376 m_aFlag.acquire();
377 ::osl::Thread::suspend();
378 m_aFlag.release();
380 protected:
381 void SAL_CALL run() override
383 //if the thread should terminate, schedule return false
384 while (schedule())
386 m_aFlag.incValue();
389 void SAL_CALL onTerminated() override
391 // t_print("normally terminate this thread %d!\n", getIdentifier());
393 public:
395 virtual ~OAddThread() override
397 if (isRunning())
399 // t_print("error: not terminated.\n");
407 namespace osl_Thread
410 static void resumeAndWaitThread(Thread* _pThread)
412 // This function starts a thread, wait a second and suspends the thread
413 // Due to the fact, that a suspend and never run thread never really exists.
415 // Note: on UNX, after createSuspended, and then terminate the thread, it performs well;
416 // while on Windows, after createSuspended, the thread can not terminate, wait endlessly,
417 // so here call resume at first, then call terminate.
418 #ifdef _WIN32
419 t_print("resumeAndWaitThread\n");
420 _pThread->resume();
421 ThreadHelper::thread_sleep_tenth_sec(1);
422 #else
423 _pThread->resume();
424 #endif
427 // kill a running thread and join it, if it has terminated, do nothing
428 static void termAndJoinThread(Thread* _pThread)
430 _pThread->terminate();
432 // LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up
433 #ifdef _WIN32
434 _pThread->resume();
435 ThreadHelper::thread_sleep_tenth_sec(1);
436 #endif
437 t_print("#wait for join.\n");
438 _pThread->join();
440 /** Test of the osl::Thread::create method
443 class create : public CppUnit::TestFixture
445 public:
446 /** Simple create a thread.
448 Create a simple thread, it just does add 1 to value(which initialized 0),
449 if the thread run, the value should be 1.
451 void create_001()
453 myThread* newthread = new myThread;
454 bool bRes = newthread->create();
455 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!\n", bRes);
457 ThreadHelper::thread_sleep_tenth_sec(1); // wait short
458 bool isRunning = newthread->isRunning(); // check if thread is running
459 /// wait for the new thread to assure it has run
460 ThreadHelper::thread_sleep_tenth_sec(3);
461 sal_Int32 nValue = newthread->getValue();
462 /// to assure the new thread has terminated
463 termAndJoinThread(newthread);
464 delete newthread;
466 t_print(" nValue = %d\n", static_cast<int>(nValue));
467 t_print("isRunning = %s\n", isRunning ? "true" : "false");
469 CPPUNIT_ASSERT_MESSAGE(
470 "Creates a new thread",
471 nValue >= 1
473 CPPUNIT_ASSERT_MESSAGE(
474 "Creates a new thread",
475 isRunning
480 /** only one running thread per instance, return false if create secondly
482 void create_002()
484 myThread* newthread = new myThread;
485 bool res1 = newthread->create();
486 bool res2 = newthread->create();
487 t_print("In non pro, an assertion should occurred. This behaviour is right.\n");
488 termAndJoinThread(newthread);
489 delete newthread;
491 CPPUNIT_ASSERT_MESSAGE(
492 "Creates a new thread: can not create two threads per instance",
493 res1
495 CPPUNIT_ASSERT_MESSAGE(
496 "Creates a new thread: can not create two threads per instance",
497 !res2
502 CPPUNIT_TEST_SUITE(create);
503 CPPUNIT_TEST(create_001);
504 CPPUNIT_TEST(create_002);
505 CPPUNIT_TEST_SUITE_END();
506 }; // class create
508 /** Test of the osl::Thread::createSuspended method
510 class createSuspended : public CppUnit::TestFixture
512 public:
513 /** Create a suspended thread, use the same class as create_001
515 after create, wait enough time, check the value, if it's still the initial value, pass
517 void createSuspended_001()
519 myThread* newthread = new myThread;
520 bool bRes = newthread->createSuspended();
521 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!", bRes);
523 ThreadHelper::thread_sleep_tenth_sec(1);
524 bool isRunning = newthread->isRunning();
525 ThreadHelper::thread_sleep_tenth_sec(3);
526 sal_Int32 nValue = newthread->getValue();
528 resumeAndWaitThread(newthread);
530 termAndJoinThread(newthread);
531 delete newthread;
533 CPPUNIT_ASSERT_EQUAL_MESSAGE(
534 "Creates a new suspended thread",
535 sal_Int32(0), nValue
537 CPPUNIT_ASSERT_MESSAGE(
538 "Creates a new suspended thread",
539 isRunning
543 void createSuspended_002()
545 myThread* newthread = new myThread;
546 bool res1 = newthread->createSuspended();
547 bool res2 = newthread->createSuspended();
549 resumeAndWaitThread(newthread);
551 termAndJoinThread(newthread);
553 delete newthread;
555 CPPUNIT_ASSERT_MESSAGE(
556 "Creates a new thread: can not create two threads per instance",
557 res1
559 CPPUNIT_ASSERT_MESSAGE(
560 "Creates a new thread: can not create two threads per instance",
561 !res2
565 CPPUNIT_TEST_SUITE(createSuspended);
566 CPPUNIT_TEST(createSuspended_001);
567 // LLA: Deadlocked!!!
568 CPPUNIT_TEST(createSuspended_002);
569 CPPUNIT_TEST_SUITE_END();
570 }; // class createSuspended
572 /** when the count value equal to or more than 3, suspend the thread.
574 static void suspendCountThread(OCountThread* _pCountThread)
576 sal_Int32 nValue = 0;
577 while (true)
579 nValue = _pCountThread->getValue();
580 if (nValue >= 3)
582 _pCountThread->suspend();
583 break;
588 /** Test of the osl::Thread::suspend method
590 class suspend : public CppUnit::TestFixture
592 public:
593 /** Use a thread which has a flag added 1 every second
595 ALGORITHM:
596 create the thread, after running special time, record value of flag, then suspend it,
597 wait a long time, check the flag, if it remains unchanged during suspending
599 void suspend_001()
601 OCountThread* aCountThread = new OCountThread();
602 bool bRes = aCountThread->create();
603 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
604 // the thread run for some seconds, but not terminate
605 suspendCountThread( aCountThread );
607 // the value just after calling suspend
608 sal_Int32 nValue = aCountThread->getValue(); // (2)
610 ThreadHelper::thread_sleep_tenth_sec(3);
612 // the value after waiting 3 seconds
613 sal_Int32 nLaterValue = aCountThread->getValue(); // (3)
615 resumeAndWaitThread(aCountThread);
616 termAndJoinThread(aCountThread);
617 delete aCountThread;
619 CPPUNIT_ASSERT_MESSAGE(
620 "Suspend the thread",
621 bRes
623 CPPUNIT_ASSERT_EQUAL_MESSAGE(
624 "Suspend the thread",
625 nValue, nLaterValue
630 CPPUNIT_TEST_SUITE(suspend);
631 CPPUNIT_TEST(suspend_001);
632 // LLA: Deadlocked!!!
633 // CPPUNIT_TEST(createSuspended_002);
634 CPPUNIT_TEST_SUITE_END();
635 }; // class suspend
637 /** Test of the osl::Thread::resume method
639 class resume : public CppUnit::TestFixture
641 public:
642 /** check if the thread run samely as usual after suspend and resume
644 ALGORITHM:
645 compare the values before and after suspend, they should be same,
646 then compare values before and after resume, the difference should be same as the sleep seconds number
648 void resume_001()
650 OCountThread* pCountThread = new OCountThread();
651 bool bRes = pCountThread->create();
652 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
654 suspendCountThread(pCountThread);
656 sal_Int32 nSuspendValue = pCountThread->getValue(); // (2)
657 // suspend for 3 seconds
658 ThreadHelper::thread_sleep_tenth_sec(3);
659 pCountThread->resume();
661 ThreadHelper::thread_sleep_tenth_sec(3);
662 sal_Int32 nResumeValue = pCountThread->getValue();
664 ThreadHelper::thread_sleep_tenth_sec(3);
665 sal_Int32 nLaterValue = pCountThread->getValue();
667 termAndJoinThread(pCountThread);
668 delete pCountThread;
670 t_print("SuspendValue: %d\n", static_cast<int>(nSuspendValue));
671 t_print("ResumeValue: %d\n", static_cast<int>(nResumeValue));
672 t_print("LaterValue: %d\n", static_cast<int>(nLaterValue));
674 /* LLA: this assumption is no longer relevant: nResumeValue == nSuspendValue && */
675 CPPUNIT_ASSERT_MESSAGE(
676 "Suspend then resume the thread",
677 nLaterValue >= 9
679 CPPUNIT_ASSERT_MESSAGE(
680 "Suspend then resume the thread",
681 nResumeValue > nSuspendValue
683 CPPUNIT_ASSERT_MESSAGE(
684 "Suspend then resume the thread",
685 nLaterValue > nResumeValue
690 /** Create a suspended thread then resume, check if the thread has run
692 void resume_002()
694 myThread* newthread = new myThread;
695 bool bRes = newthread->createSuspended();
696 CPPUNIT_ASSERT_MESSAGE ( "Can't create thread!", bRes );
698 newthread->resume();
699 ThreadHelper::thread_sleep_tenth_sec(2);
700 sal_Int32 nValue = newthread->getValue();
702 termAndJoinThread(newthread);
703 delete newthread;
705 t_print(" nValue = %d\n", static_cast<int>(nValue));
707 CPPUNIT_ASSERT_MESSAGE(
708 "Creates a suspended thread, then resume",
709 nValue >= 1
713 CPPUNIT_TEST_SUITE(resume);
714 CPPUNIT_TEST(resume_001);
715 CPPUNIT_TEST(resume_002);
716 CPPUNIT_TEST_SUITE_END();
717 }; // class resume
719 /** Test of the osl::Thread::terminate method
721 class terminate : public CppUnit::TestFixture
723 public:
724 /** Check after call terminate if the running thread running go on executing
726 ALGORITHM:
727 before and after call terminate, the values should be the same
729 void terminate_001()
731 OCountThread* aCountThread = new OCountThread();
732 bool bRes = aCountThread->create();
733 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
735 ThreadHelper::thread_sleep_tenth_sec(2);
736 sal_Int32 nValue = aCountThread->getValue();
737 aCountThread->terminate();
738 ThreadHelper::thread_sleep_tenth_sec(2);
739 sal_Int32 nLaterValue = aCountThread->getValue();
741 // isRunning should be false after terminate
742 bool isRunning = aCountThread->isRunning();
743 aCountThread->join();
744 delete aCountThread;
746 t_print(" nValue = %d\n", static_cast<int>(nValue));
747 t_print("nLaterValue = %d\n", static_cast<int>(nLaterValue));
749 CPPUNIT_ASSERT_MESSAGE(
750 "Terminate the thread",
751 !isRunning
753 CPPUNIT_ASSERT_MESSAGE(
754 "Terminate the thread",
755 nLaterValue >= nValue
758 /** Check if a suspended thread will terminate after call terminate, different on w32 and on UNX
760 void terminate_002()
762 OCountThread* aCountThread = new OCountThread();
763 bool bRes = aCountThread->create();
764 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
766 ThreadHelper::thread_sleep_tenth_sec(1);
767 suspendCountThread(aCountThread);
768 sal_Int32 nValue = aCountThread->getValue();
770 // seems a suspended thread can not be terminated on W32, while on Solaris can
771 resumeAndWaitThread(aCountThread);
773 ThreadHelper::thread_sleep_tenth_sec(2);
775 termAndJoinThread(aCountThread);
776 sal_Int32 nLaterValue = aCountThread->getValue();
777 delete aCountThread;
779 t_print(" nValue = %d\n", static_cast<int>(nValue));
780 t_print("nLaterValue = %d\n", static_cast<int>(nLaterValue));
782 CPPUNIT_ASSERT_MESSAGE(
783 "Suspend then resume the thread",
784 nLaterValue > nValue );
787 CPPUNIT_TEST_SUITE(terminate);
788 CPPUNIT_TEST(terminate_001);
789 CPPUNIT_TEST(terminate_002);
790 CPPUNIT_TEST_SUITE_END();
791 }; // class terminate
793 /** Test of the osl::Thread::join method
795 class join : public CppUnit::TestFixture
797 public:
798 /** Check after call terminate if the thread running function will not go on executing
800 the next statement after join will not exec before the thread terminates
801 ALGORITHM:
802 recode system time at the beginning of the thread run, call join, then record system time again,
803 the difference of the two times should be equal or more than 20 seconds, the CountThread normally terminates
805 void join_001()
807 OCountThread *aCountThread = new OCountThread();
808 bool bRes = aCountThread->create();
809 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
811 StopWatch aStopWatch;
812 aStopWatch.start();
813 // TimeValue aTimeVal_befor;
814 // osl_getSystemTime( &aTimeVal_befor );
815 //t_print("#join:the system time is %d,%d\n", pTimeVal_befor->Seconds,pTimeVal_befor->Nanosec);
817 aCountThread->join();
819 //the below line will be executed after aCountThread terminate
820 // TimeValue aTimeVal_after;
821 // osl_getSystemTime( &aTimeVal_after );
822 aStopWatch.stop();
823 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
824 double nSec = aStopWatch.getSeconds();
825 t_print("join_001 nSec=%f\n", nSec);
826 delete aCountThread;
828 CPPUNIT_ASSERT_MESSAGE(
829 "Join the thread: after the thread terminate",
830 nSec >= 2
834 /** after terminated by another thread, join exited immediately
836 ALGORITHM:
837 terminate the thread when value>=3, call join, check the beginning time and time after join,
838 the difference should be 3 seconds, join costs little time
840 void join_002()
842 OCountThread *aCountThread = new OCountThread();
843 bool bRes = aCountThread->create();
844 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
846 //record the time when the running begin
847 // TimeValue aTimeVal_befor;
848 // osl_getSystemTime( &aTimeVal_befor );
849 StopWatch aStopWatch;
850 aStopWatch.start();
852 ThreadHelper::thread_sleep_tenth_sec(10);
853 termAndJoinThread(aCountThread);
855 //the below line will be executed after aCountThread terminate
856 // TimeValue aTimeVal_after;
857 // osl_getSystemTime( &aTimeVal_after );
858 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
859 aStopWatch.stop();
860 double nSec = aStopWatch.getSeconds();
861 t_print("join_002 nSec=%f\n", nSec);
863 delete aCountThread;
864 CPPUNIT_ASSERT_MESSAGE(
865 "Join the thread: after thread terminate by another thread",
866 nSec >= 1
870 CPPUNIT_TEST_SUITE(join);
871 CPPUNIT_TEST(join_001);
872 CPPUNIT_TEST(join_002);
873 CPPUNIT_TEST_SUITE_END();
874 }; // class join
876 /** Test of the osl::Thread::isRunning method
878 class isRunning : public CppUnit::TestFixture
880 public:
881 void isRunning_001()
883 OCountThread *aCountThread = new OCountThread();
884 bool bRes = aCountThread->create();
885 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
887 bool bRun = aCountThread->isRunning();
889 ThreadHelper::thread_sleep_tenth_sec(2);
890 termAndJoinThread(aCountThread);
891 bool bTer = aCountThread->isRunning();
892 delete aCountThread;
894 CPPUNIT_ASSERT_MESSAGE(
895 "Test isRunning",
896 bRun
898 CPPUNIT_ASSERT_MESSAGE(
899 "Test isRunning",
900 !bTer
903 /** check the value of isRunning when suspending and after resume
905 void isRunning_002()
907 OCountThread *aCountThread = new OCountThread();
908 bool bRes = aCountThread->create();
909 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
911 // sal_Bool bRunning = aCountThread->isRunning();
912 // sal_Int32 nValue = 0;
913 suspendCountThread(aCountThread);
915 bool bRunning_sup = aCountThread->isRunning();
916 ThreadHelper::thread_sleep_tenth_sec(2);
917 aCountThread->resume();
918 ThreadHelper::thread_sleep_tenth_sec(2);
919 bool bRunning_res = aCountThread->isRunning();
920 termAndJoinThread(aCountThread);
921 bool bRunning_ter = aCountThread->isRunning();
922 delete aCountThread;
924 CPPUNIT_ASSERT_MESSAGE(
925 "Test isRunning",
926 bRes && bRunning_sup );
927 CPPUNIT_ASSERT_MESSAGE(
928 "Test isRunning",
929 bRunning_res );
930 CPPUNIT_ASSERT_MESSAGE(
931 "Test isRunning",
932 !bRunning_ter );
936 CPPUNIT_TEST_SUITE(isRunning);
937 CPPUNIT_TEST(isRunning_001);
938 CPPUNIT_TEST(isRunning_002);
939 CPPUNIT_TEST_SUITE_END();
940 }; // class isRunning
942 /// check osl::Thread::setPriority
943 class setPriority : public CppUnit::TestFixture
945 public:
946 // insert your test code here.
947 OString getPrioName(oslThreadPriority _aPriority)
949 OString sPrioStr;
950 switch (_aPriority)
952 case osl_Thread_PriorityHighest:
953 sPrioStr = "Highest";
954 break;
956 case osl_Thread_PriorityAboveNormal:
957 sPrioStr = "AboveNormal";
958 break;
960 case osl_Thread_PriorityNormal:
961 sPrioStr = "Normal";
962 break;
964 case osl_Thread_PriorityBelowNormal:
965 sPrioStr = "BelowNormal";
966 break;
968 case osl_Thread_PriorityLowest:
969 sPrioStr = "Lowest";
970 break;
971 default:
972 sPrioStr = "unknown";
974 return sPrioStr;
977 /** check 2 threads.
979 ALGORITHM:
980 Here the function should show, that 2 different threads,
981 which only increase a value, should run at the same time with same prio.
982 The test fails, if the difference between the two values is more than 5%
983 but IMHO this isn't a failure, it's only a feature of the OS.
986 void check2Threads(oslThreadPriority _aPriority)
988 // initial 5 threads with different priorities
989 OAddThread* pThread = new OAddThread();
990 OAddThread* p2Thread = new OAddThread();
992 //Create them and start running at the same time
993 pThread->create();
994 pThread->setPriority(_aPriority);
995 p2Thread->create();
996 p2Thread->setPriority(_aPriority);
998 ThreadHelper::thread_sleep_tenth_sec(5);
1000 pThread->terminate();
1001 p2Thread->terminate();
1003 sal_Int32 nValueNormal = pThread->getValue();
1005 sal_Int32 nValueNormal2 = p2Thread->getValue();
1007 OString sPrio = getPrioName(_aPriority);
1008 t_print("After 10 tenth seconds\n");
1010 t_print("nValue in %s Prio Thread is %d\n",sPrio.getStr(), static_cast<int>(nValueNormal));
1011 t_print("nValue in %s Prio Thread is %d\n", sPrio.getStr(), static_cast<int>(nValueNormal2));
1013 // ThreadHelper::thread_sleep_tenth_sec(1);
1014 pThread->join();
1015 p2Thread->join();
1017 delete pThread;
1018 delete p2Thread;
1020 sal_Int32 nDelta = abs(nValueNormal - nValueNormal2);
1021 double nQuotient = std::max(nValueNormal, nValueNormal2);
1022 CPPUNIT_ASSERT_MESSAGE(
1023 "Quotient is zero, which means, there exist no right values.",
1024 nQuotient != 0
1026 double nDeltaPercent = nDelta / nQuotient * 100;
1028 t_print("Delta value %d, percent %f\n", static_cast<int>(nDelta), nDeltaPercent);
1030 // LLA: it's not a bug if the current OS is not able to handle thread scheduling right and good.
1031 // like Windows XP
1032 // LLA: CPPUNIT_ASSERT_MESSAGE(
1033 // LLA: "Run 2 normal threads, the count diff more than 5 percent.",
1034 // LLA: nDeltaPercent <= 5
1035 // LLA: );
1038 void setPriority_001_1()
1040 check2Threads(osl_Thread_PriorityHighest);
1042 void setPriority_001_2()
1044 check2Threads(osl_Thread_PriorityAboveNormal);
1046 void setPriority_001_3()
1048 check2Threads(osl_Thread_PriorityNormal);
1050 void setPriority_001_4()
1052 check2Threads(osl_Thread_PriorityBelowNormal);
1054 void setPriority_001_5()
1056 check2Threads(osl_Thread_PriorityLowest);
1059 void setPriority_002()
1061 // initial 5 threads with different priorities
1063 OAddThread aHighestThread;
1064 OAddThread aAboveNormalThread;
1065 OAddThread aNormalThread;
1066 //OAddThread *aBelowNormalThread = new OAddThread();
1067 //OAddThread *aLowestThread = new OAddThread();
1069 //Create them and start running at the same time
1070 aHighestThread.createSuspended();
1071 aHighestThread.setPriority(osl_Thread_PriorityHighest);
1073 aAboveNormalThread.createSuspended();
1074 aAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1076 aNormalThread.createSuspended();
1077 aNormalThread.setPriority(osl_Thread_PriorityNormal);
1078 /*aBelowNormalThread->create();
1079 aBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1080 aLowestThread->create();
1081 aLowestThread->setPriority(osl_Thread_PriorityLowest);
1084 aHighestThread.resume();
1085 aAboveNormalThread.resume();
1086 aNormalThread.resume();
1088 ThreadHelper::thread_sleep_tenth_sec(5);
1090 aHighestThread.suspend();
1091 aAboveNormalThread.suspend();
1092 aNormalThread.suspend();
1094 termAndJoinThread(&aNormalThread);
1095 termAndJoinThread(&aAboveNormalThread);
1096 termAndJoinThread(&aHighestThread);
1097 //aBelowNormalThread->terminate();
1098 //aLowestThread->terminate();
1100 sal_Int32 nValueHighest = aHighestThread.getValue();
1102 sal_Int32 nValueAboveNormal = aAboveNormalThread.getValue();
1104 sal_Int32 nValueNormal = aNormalThread.getValue();
1106 t_print("After 10 tenth seconds\n");
1107 t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
1108 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1109 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1111 #ifndef _WIN32
1112 CPPUNIT_ASSERT_MESSAGE(
1113 "SetPriority",
1114 nValueHighest > 0
1116 CPPUNIT_ASSERT_MESSAGE(
1117 "SetPriority",
1118 nValueAboveNormal > 0
1120 CPPUNIT_ASSERT_MESSAGE(
1121 "SetPriority",
1122 nValueNormal > 0
1124 #endif
1127 void setPriority_003()
1129 // initial 5 threads with different priorities
1130 OAddThread pHighestThread;
1131 OAddThread pAboveNormalThread;
1132 OAddThread pNormalThread;
1133 OAddThread pBelowNormalThread;
1134 OAddThread pLowestThread;
1136 //Create them and start running at the same time
1137 pHighestThread.createSuspended();
1138 pHighestThread.setPriority(osl_Thread_PriorityHighest);
1140 pAboveNormalThread.createSuspended();
1141 pAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1143 pNormalThread.createSuspended();
1144 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1146 pBelowNormalThread.createSuspended();
1147 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1149 pLowestThread.createSuspended();
1150 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1152 pHighestThread.resume();
1153 pAboveNormalThread.resume();
1154 pNormalThread.resume();
1155 pBelowNormalThread.resume();
1156 pLowestThread.resume();
1158 ThreadHelper::thread_sleep_tenth_sec(5);
1160 pHighestThread.suspend();
1161 pAboveNormalThread.suspend();
1162 pNormalThread.suspend();
1163 pBelowNormalThread.suspend();
1164 pLowestThread.suspend();
1166 termAndJoinThread(&pHighestThread);
1167 termAndJoinThread(&pAboveNormalThread);
1168 termAndJoinThread(&pNormalThread);
1169 termAndJoinThread(&pBelowNormalThread);
1170 termAndJoinThread(&pLowestThread);
1172 sal_Int32 nValueHighest = pHighestThread.getValue();
1174 sal_Int32 nValueAboveNormal = pAboveNormalThread.getValue();
1176 sal_Int32 nValueNormal = pNormalThread.getValue();
1178 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1180 sal_Int32 nValueLowest = pLowestThread.getValue();
1182 t_print("After 10 tenth seconds\n");
1183 t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
1184 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1185 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1186 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1187 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1189 #ifndef _WIN32
1190 CPPUNIT_ASSERT_MESSAGE(
1191 "SetPriority",
1192 nValueHighest > 0 &&
1193 nValueAboveNormal > 0 &&
1194 nValueNormal > 0
1196 CPPUNIT_ASSERT_MESSAGE(
1197 "SetPriority",
1198 nValueBelowNormal > 0
1200 CPPUNIT_ASSERT_MESSAGE(
1201 "SetPriority",
1202 nValueLowest > 0
1204 #endif
1207 void setPriority_004()
1209 // initial 5 threads with different priorities
1210 // OAddThread *pHighestThread = new OAddThread();
1211 OAddThread pAboveNormalThread;
1212 OAddThread pNormalThread;
1213 OAddThread pBelowNormalThread;
1214 OAddThread pLowestThread;
1216 //Create them and start running at the same time
1217 // pHighestThread->createSuspended();
1218 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1220 pAboveNormalThread.createSuspended();
1221 pAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1223 pNormalThread.createSuspended();
1224 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1226 pBelowNormalThread.createSuspended();
1227 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1229 pLowestThread.createSuspended();
1230 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1232 // pHighestThread->resume();
1233 pAboveNormalThread.resume();
1234 pNormalThread.resume();
1235 pBelowNormalThread.resume();
1236 pLowestThread.resume();
1238 ThreadHelper::thread_sleep_tenth_sec(5);
1240 // pHighestThread->suspend();
1241 pAboveNormalThread.suspend();
1242 pNormalThread.suspend();
1243 pBelowNormalThread.suspend();
1244 pLowestThread.suspend();
1246 // termAndJoinThread(pHighestThread);
1247 termAndJoinThread(&pAboveNormalThread);
1248 termAndJoinThread(&pNormalThread);
1249 termAndJoinThread(&pBelowNormalThread);
1250 termAndJoinThread(&pLowestThread);
1252 // sal_Int32 nValueHighest = 0;
1253 // nValueHighest = pHighestThread->getValue();
1255 sal_Int32 nValueAboveNormal = pAboveNormalThread.getValue();
1257 sal_Int32 nValueNormal = pNormalThread.getValue();
1259 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1261 sal_Int32 nValueLowest = pLowestThread.getValue();
1263 t_print("After 5 tenth seconds\n");
1264 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1265 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1266 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1267 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1269 // delete pHighestThread;
1271 #ifndef _WIN32
1272 CPPUNIT_ASSERT_MESSAGE(
1273 "SetPriority",
1274 /* nValueHighest > 0 && */
1275 nValueAboveNormal > 0 &&
1276 nValueNormal > 0
1278 CPPUNIT_ASSERT_MESSAGE(
1279 "SetPriority",
1280 nValueBelowNormal > 0
1282 CPPUNIT_ASSERT_MESSAGE(
1283 "SetPriority",
1284 nValueLowest > 0
1286 #endif
1288 void setPriority_005()
1290 // initial 5 threads with different priorities
1291 // OAddThread *pHighestThread = new OAddThread();
1292 // OAddThread *pAboveNormalThread = new OAddThread();
1293 OAddThread pNormalThread;
1294 OAddThread pBelowNormalThread;
1295 OAddThread pLowestThread;
1297 //Create them and start running at the same time
1298 // pHighestThread->createSuspended();
1299 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1301 // pAboveNormalThread->createSuspended();
1302 // pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
1304 pNormalThread.createSuspended();
1305 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1307 pBelowNormalThread.createSuspended();
1308 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1310 pLowestThread.createSuspended();
1311 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1313 // pHighestThread->resume();
1314 // pAboveNormalThread->resume();
1315 pNormalThread.resume();
1316 pBelowNormalThread.resume();
1317 pLowestThread.resume();
1319 ThreadHelper::thread_sleep_tenth_sec(5);
1321 // pHighestThread->suspend();
1322 // pAboveNormalThread->suspend();
1323 pNormalThread.suspend();
1324 pBelowNormalThread.suspend();
1325 pLowestThread.suspend();
1327 // termAndJoinThread(pHighestThread);
1328 // termAndJoinThread(pAboveNormalThread);
1329 termAndJoinThread(&pNormalThread);
1330 termAndJoinThread(&pBelowNormalThread);
1331 termAndJoinThread(&pLowestThread);
1333 // sal_Int32 nValueHighest = 0;
1334 // nValueHighest = pHighestThread->getValue();
1336 // sal_Int32 nValueAboveNormal = 0;
1337 // nValueAboveNormal = pAboveNormalThread->getValue();
1339 sal_Int32 nValueNormal = pNormalThread.getValue();
1341 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1343 sal_Int32 nValueLowest = pLowestThread.getValue();
1345 t_print("After 5 tenth seconds\n");
1346 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1347 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1348 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1350 #ifndef _WIN32
1351 CPPUNIT_ASSERT_MESSAGE(
1352 "SetPriority",
1353 /* nValueHighest > 0 && */
1354 /* nValueAboveNormal > 0 && */
1355 nValueNormal > 0
1357 CPPUNIT_ASSERT_MESSAGE(
1358 "SetPriority",
1359 nValueBelowNormal > 0
1361 CPPUNIT_ASSERT_MESSAGE(
1362 "SetPriority",
1363 nValueLowest > 0
1365 #endif
1368 CPPUNIT_TEST_SUITE(setPriority);
1369 #ifndef __sun
1370 CPPUNIT_TEST(setPriority_002);
1371 CPPUNIT_TEST(setPriority_003);
1372 CPPUNIT_TEST(setPriority_004);
1373 CPPUNIT_TEST(setPriority_005);
1374 #endif
1375 CPPUNIT_TEST(setPriority_001_1);
1376 CPPUNIT_TEST(setPriority_001_2);
1377 CPPUNIT_TEST(setPriority_001_3);
1378 CPPUNIT_TEST(setPriority_001_4);
1379 CPPUNIT_TEST(setPriority_001_5);
1380 CPPUNIT_TEST_SUITE_END();
1381 }; // class setPriority
1383 /** Test of the osl::Thread::getPriority method
1385 class getPriority : public CppUnit::TestFixture
1387 public:
1388 // insert your test code here.
1389 void getPriority_001()
1391 OAddThread *pHighestThread = new OAddThread();
1393 //Create them and start running at the same time
1394 pHighestThread->create();
1395 pHighestThread->setPriority(osl_Thread_PriorityHighest);
1397 oslThreadPriority aPriority = pHighestThread->getPriority();
1398 termAndJoinThread(pHighestThread);
1399 delete pHighestThread;
1401 ThreadHelper::outputPriority(aPriority);
1403 // LLA: Priority settings may not work within some OS versions.
1404 #if defined(_WIN32) || defined(__sun)
1405 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1406 "getPriority",
1407 osl_Thread_PriorityHighest, aPriority
1409 #else
1410 // LLA: Linux
1411 // NO_PTHREAD_PRIORITY ???
1412 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1413 "getPriority",
1414 osl_Thread_PriorityNormal, aPriority
1416 #endif
1419 CPPUNIT_TEST_SUITE(getPriority);
1420 CPPUNIT_TEST(getPriority_001);
1421 CPPUNIT_TEST_SUITE_END();
1422 }; // class getPriority
1424 class getIdentifier : public CppUnit::TestFixture
1426 public:
1427 // initialise your test code values here.
1429 void getIdentifier_001()
1431 // insert your test code here.
1434 CPPUNIT_TEST_SUITE(getIdentifier);
1435 CPPUNIT_TEST(getIdentifier_001);
1436 CPPUNIT_TEST_SUITE_END();
1437 }; // class getIdentifier
1439 /** Test of the osl::Thread::getCurrentIdentifier method
1441 class getCurrentIdentifier : public CppUnit::TestFixture
1443 public:
1444 void getCurrentIdentifier_001()
1446 oslThreadIdentifier oId;
1447 OCountThread* pCountThread = new OCountThread;
1448 pCountThread->create();
1449 pCountThread->setWait(3);
1450 oId = Thread::getCurrentIdentifier();
1451 oslThreadIdentifier oIdChild = pCountThread->getIdentifier();
1452 termAndJoinThread(pCountThread);
1453 delete pCountThread;
1455 CPPUNIT_ASSERT_MESSAGE(
1456 "Get the identifier for the current active thread.",
1457 oId != oIdChild);
1460 CPPUNIT_TEST_SUITE(getCurrentIdentifier);
1461 CPPUNIT_TEST(getCurrentIdentifier_001);
1462 CPPUNIT_TEST_SUITE_END();
1463 }; // class getCurrentIdentifier
1465 /** Test of the osl::Thread::wait method
1467 class waittest : public CppUnit::TestFixture
1469 public:
1470 /** call wait in the run method
1472 ALGORITHM:
1473 tested thread wait nWaitSec seconds, main thread sleep (2) seconds,
1474 then terminate the tested thread, due to the fact that the thread do a sleep(1) + wait(5)
1475 it's finish after 6 seconds.
1477 void wait_001()
1479 OCountThread *aCountThread = new OCountThread();
1480 sal_Int32 nWaitSec = 5;
1481 aCountThread->setWait(nWaitSec);
1482 // thread runs at least 5 seconds.
1483 bool bRes = aCountThread->create();
1484 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1486 //record the time when the running begin
1487 StopWatch aStopWatch;
1488 aStopWatch.start();
1490 // wait a little bit, to let the thread the time, to start
1491 ThreadHelper::thread_sleep_tenth_sec( 4 );
1493 // if wait works,
1494 // this function returns, after 4 sec. later
1495 termAndJoinThread(aCountThread);
1497 // value should be one.
1498 sal_Int32 nValue = aCountThread->getValue();
1500 aStopWatch.stop();
1502 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
1503 double nTenthSec = aStopWatch.getTenthSec();
1504 double nSec = aStopWatch.getSeconds();
1505 delete aCountThread;
1506 t_print("nTenthSec = %f \n", nTenthSec);
1507 t_print("nSec = %f \n", nSec);
1508 t_print("nValue = %d \n", static_cast<int>(nValue));
1510 CPPUNIT_ASSERT_MESSAGE(
1511 "Wait: Blocks the calling thread for the given number of time.",
1512 nTenthSec >= 5
1514 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1515 "Wait: Blocks the calling thread for the given number of time.",
1516 sal_Int32(1), nValue
1521 CPPUNIT_TEST_SUITE(waittest);
1522 CPPUNIT_TEST(wait_001);
1523 CPPUNIT_TEST_SUITE_END();
1524 }; // class waittest
1526 /** osl::Thread::yield method: can not design good test scenario to test up to now
1528 class yield : public CppUnit::TestFixture
1530 public:
1531 void yield_001()
1533 // insert your test code here.
1536 CPPUNIT_TEST_SUITE(yield);
1537 CPPUNIT_TEST(yield_001);
1538 CPPUNIT_TEST_SUITE_END();
1539 }; // class yield
1541 /** Test of the osl::Thread::schedule method
1543 class schedule : public CppUnit::TestFixture
1545 public:
1547 /** The requested thread will get terminate the next time schedule() is called.
1549 Note: on UNX, if call suspend thread is not the to be suspended thread, the to be
1550 suspended thread will get suspended the next time schedule() is called,
1551 while on w32, it's nothing with schedule.
1553 check if suspend and terminate work well via schedule
1555 void schedule_001()
1557 OAddThread* aThread = new OAddThread();
1558 bool bRes = aThread->create();
1559 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1561 ThreadHelper::thread_sleep_tenth_sec(2);
1562 aThread->suspend();
1563 ThreadHelper::thread_sleep_tenth_sec(1);
1564 sal_Int32 nValue = aThread->getValue();
1565 ThreadHelper::thread_sleep_tenth_sec(3);
1566 sal_Int32 nLaterValue = aThread->getValue();
1567 // resumeAndWaitThread(aThread);
1568 t_print(" value = %d\n", static_cast<int>(nValue));
1569 t_print("later value = %d\n", static_cast<int>(nLaterValue));
1570 // if value and latervalue not equal, then the thread would not suspended
1572 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1573 "Schedule: suspend works.",
1574 nValue, nLaterValue
1577 aThread->resume();
1578 ThreadHelper::thread_sleep_tenth_sec(2);
1580 aThread->terminate();
1581 sal_Int32 nValue_term = aThread->getValue();
1583 aThread->join();
1584 sal_Int32 nValue_join = aThread->getValue();
1586 t_print("value after term = %d\n", static_cast<int>(nValue_term));
1587 t_print("value after join = %d\n", static_cast<int>(nValue_join));
1589 // nValue_term and nValue_join should be the same
1590 // but should be differ from nValue
1592 delete aThread;
1593 //check if thread really terminate after call terminate, if join immediately return
1594 CPPUNIT_ASSERT_MESSAGE(
1595 "Schedule: Returns False if the thread should terminate.",
1596 nValue_join - nValue_term <= 1
1598 CPPUNIT_ASSERT_MESSAGE(
1599 "Schedule: Returns False if the thread should terminate.",
1600 nValue_join - nValue_term >= 0
1605 /** design a thread that has not call schedule in the workfunction--run method
1607 void schedule_002()
1609 ONoScheduleThread aThread; // this thread runs 10 sec. (no schedule() used)
1610 bool bRes = aThread.create();
1611 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1613 ThreadHelper::thread_sleep_tenth_sec(2);
1614 aThread.suspend();
1615 sal_Int32 nValue = aThread.getValue();
1617 ThreadHelper::thread_sleep_tenth_sec(3);
1618 sal_Int32 nLaterValue = aThread.getValue();
1619 ThreadHelper::thread_sleep_tenth_sec(5);
1621 resumeAndWaitThread(&aThread);
1623 t_print(" value = %d\n", static_cast<int>(nValue));
1624 t_print("later value = %d\n", static_cast<int>(nLaterValue));
1626 //On windows, suspend works, so the values are same
1627 #ifdef _WIN32
1628 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1629 "Schedule: don't schedule in thread run method, suspend works.",
1630 nValue, nLaterValue
1632 #endif
1634 //On UNX, suspend does not work, so the difference of the values equals to sleep seconds number
1635 #ifdef UNX
1636 aThread.resume();
1637 CPPUNIT_ASSERT_MESSAGE(
1638 "Schedule: don't schedule in thread run method, suspend does not work too.",
1639 nLaterValue > nValue
1641 #endif
1643 // terminate will not work if no schedule in thread's work function
1644 termAndJoinThread(&aThread);
1645 sal_Int32 nValue_term = aThread.getValue();
1647 t_print(" value term = %d\n", static_cast<int>(nValue_term));
1649 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1650 "Schedule: don't schedule in thread run method, terminate failed.",
1651 static_cast<sal_Int32>(10), nValue_term
1655 CPPUNIT_TEST_SUITE(schedule);
1656 CPPUNIT_TEST(schedule_001);
1657 CPPUNIT_TEST(schedule_002);
1658 CPPUNIT_TEST_SUITE_END();
1659 }; // class schedule
1661 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::create, "osl_Thread");
1662 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::createSuspended, "osl_Thread");
1663 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::suspend, "osl_Thread");
1664 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::resume, "osl_Thread");
1665 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::terminate, "osl_Thread");
1666 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::join, "osl_Thread");
1667 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::isRunning, "osl_Thread");
1668 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::setPriority, "osl_Thread");
1669 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getPriority, "osl_Thread");
1670 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getIdentifier, "osl_Thread");
1671 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getCurrentIdentifier, "osl_Thread");
1672 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::waittest, "osl_Thread");
1673 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::yield, "osl_Thread");
1674 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::schedule, "osl_Thread");
1675 } // namespace osl_Thread
1677 // destroy function when the binding thread terminate
1678 static void destroyCallback(void * data)
1680 delete[] static_cast<char *>(data);
1683 static ThreadData myThreadData(destroyCallback);
1685 namespace {
1687 class myKeyThread : public Thread
1689 public:
1690 // a public char member for test result checking
1691 char m_Char_Test;
1692 // for pass thread-special data to thread
1693 explicit myKeyThread(const char cData)
1694 : m_Char_Test(0)
1696 m_nData = cData;
1698 private:
1699 char m_nData;
1701 void SAL_CALL run() override
1703 char * pc = new char[2];
1704 // strcpy(pc, &m_nData);
1705 memcpy(pc, &m_nData, 1);
1706 pc[1] = '\0';
1708 myThreadData.setData(pc);
1709 char* pData = static_cast<char*>(myThreadData.getData());
1710 m_Char_Test = *pData;
1711 // wait for long time to check the data value in main thread
1712 ThreadHelper::thread_sleep_tenth_sec(3);
1714 public:
1715 virtual ~myKeyThread() override
1717 if (isRunning())
1719 t_print("error: not terminated.\n");
1726 static ThreadData idData;
1728 namespace {
1730 class idThread: public Thread
1732 public:
1733 oslThreadIdentifier m_Id;
1734 private:
1735 void SAL_CALL run() override
1737 std::unique_ptr<oslThreadIdentifier> pId( new oslThreadIdentifier );
1738 *pId = getIdentifier();
1739 idData.setData(pId.get());
1740 oslThreadIdentifier* pIdData = static_cast<oslThreadIdentifier*>(idData.getData());
1741 //t_print("Thread %d has Data %d\n", getIdentifier(), *pIdData);
1742 m_Id = *pIdData;
1745 public:
1746 virtual ~idThread() override
1748 if (isRunning())
1750 t_print("error: not terminated.\n");
1757 namespace osl_ThreadData
1760 class ctors : public CppUnit::TestFixture
1762 public:
1764 // insert your test code here.
1765 void ctor_001()
1770 CPPUNIT_TEST_SUITE(ctors);
1771 CPPUNIT_TEST(ctor_001);
1772 CPPUNIT_TEST_SUITE_END();
1773 }; // class ctors
1775 class setData : public CppUnit::TestFixture
1777 public:
1779 /** the same instance of the class can have different values in different threads
1781 void setData_001()
1783 idThread aThread1;
1784 aThread1.create();
1785 idThread aThread2;
1786 aThread2.create();
1788 aThread1.join();
1789 aThread2.join();
1791 oslThreadIdentifier aThreadId1 = aThread1.getIdentifier();
1792 oslThreadIdentifier aThreadId2 = aThread2.getIdentifier();
1794 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1795 "ThreadData setData: ",
1796 aThread1.m_Id, aThreadId1
1798 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1799 "ThreadData setData: ",
1800 aThread2.m_Id, aThreadId2
1805 void setData_002()
1807 // at first, set the data a value
1808 char* pc = new char[2];
1809 char nData = 'm';
1810 pc[0] = nData;
1811 pc[1] = '\0';
1813 myThreadData.setData(pc);
1815 myKeyThread aThread1('a');
1816 aThread1.create();
1817 myKeyThread aThread2('b');
1818 aThread2.create();
1819 // aThread1 and aThread2 should have not terminated yet, check current data, not 'a' 'b'
1820 char* pChar = static_cast<char*>(myThreadData.getData());
1821 char aChar = *pChar;
1823 aThread1.join();
1824 aThread2.join();
1826 // the saved thread data of aThread1 & aThread2, different
1827 char cData1 = aThread1.m_Char_Test;
1828 char cData2 = aThread2.m_Char_Test;
1830 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1831 "ThreadData setData: ",
1832 'a', cData1
1834 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1835 "ThreadData setData: ",
1836 'b', cData2
1838 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1839 "ThreadData setData: ",
1840 'm', aChar
1844 /** setData the second time, and then getData
1846 void setData_003()
1848 // at first, set the data a value
1849 char* pc = new char[2];
1850 char nData = 'm';
1851 memcpy(pc, &nData, 1);
1852 pc[1] = '\0';
1853 myThreadData.setData(pc);
1855 myKeyThread aThread1('a');
1856 aThread1.create();
1857 myKeyThread aThread2('b');
1858 aThread2.create();
1859 // aThread1 and aThread2 should have not terminated yet
1860 // setData the second time
1861 char* pc2 = new char[2];
1862 nData = 'o';
1863 memcpy(pc2, &nData, 1);
1864 pc2[1] = '\0';
1866 myThreadData.setData(pc2);
1867 char* pChar = static_cast<char*>(myThreadData.getData());
1868 char aChar = *pChar;
1870 aThread1.join();
1871 aThread2.join();
1873 // the saved thread data of aThread1 & aThread2, different
1874 char cData1 = aThread1.m_Char_Test;
1875 char cData2 = aThread2.m_Char_Test;
1877 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1878 "ThreadData setData: ",
1879 'a', cData1
1881 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1882 "ThreadData setData: ",
1883 'b', cData2
1885 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1886 "ThreadData setData: ",
1887 'o', aChar
1891 CPPUNIT_TEST_SUITE(setData);
1892 CPPUNIT_TEST(setData_001);
1893 CPPUNIT_TEST(setData_002);
1894 CPPUNIT_TEST(setData_003);
1895 CPPUNIT_TEST_SUITE_END();
1896 }; // class setData
1898 class getData : public CppUnit::TestFixture
1900 public:
1902 // After setData in child threads, get Data in the main thread, should be independent
1903 void getData_001()
1905 char* pc = new char[2];
1906 strcpy(pc, "i");
1907 myThreadData.setData(pc);
1909 myKeyThread aThread1('c');
1910 aThread1.create();
1911 myKeyThread aThread2('d');
1912 aThread2.create();
1914 aThread1.join();
1915 aThread2.join();
1917 char cData1 = aThread1.m_Char_Test;
1918 char cData2 = aThread2.m_Char_Test;
1920 char* pChar = static_cast<char*>(myThreadData.getData());
1921 char aChar = *pChar;
1923 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1924 "ThreadData setData: ",
1925 'c', cData1
1927 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1928 "ThreadData setData: ",
1929 'd', cData2
1931 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1932 "ThreadData setData: ",
1933 'i', aChar
1937 // setData then change the value in the address data pointer points,
1938 // and then getData, should get the new value
1939 void getData_002()
1941 char* pc = new char[2];
1942 char nData = 'i';
1943 memcpy(pc, &nData, 1);
1944 pc[1] = '\0';
1946 myThreadData.setData(pc);
1948 myKeyThread aThread1('a');
1949 aThread1.create();
1950 myKeyThread aThread2('b');
1951 aThread2.create();
1953 // change the value which pc points
1954 char nData2 = 'j';
1955 memcpy(pc, &nData2, 1);
1956 pc[1] = '\0';
1958 void* pChar = myThreadData.getData();
1959 char aChar = *static_cast<char*>(pChar);
1961 aThread1.join();
1962 aThread2.join();
1964 char cData1 = aThread1.m_Char_Test;
1965 char cData2 = aThread2.m_Char_Test;
1967 CPPUNIT_ASSERT_MESSAGE(
1968 "ThreadData setData: ",
1969 cData1 == 'a' && cData2 == 'b'
1971 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1972 "ThreadData setData: ",
1973 'j', aChar
1978 CPPUNIT_TEST_SUITE(getData);
1979 CPPUNIT_TEST(getData_001);
1980 CPPUNIT_TEST(getData_002);
1981 CPPUNIT_TEST_SUITE_END();
1982 }; // class getData
1984 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::ctors);
1985 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::setData);
1986 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::getData);
1987 } // namespace osl_ThreadData
1989 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */