1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sal.hxx" 26 //------------------------------------------------------------------------ 27 // include files 28 //------------------------------------------------------------------------ 29 #include <sal/types.h> 30 31 #ifndef _RTL_USTRING_HXX_ 32 #include <rtl/string.hxx> 33 #endif 34 35 #ifndef _RTL_USTRING_HXX_ 36 #include <rtl/strbuf.hxx> 37 #endif 38 39 #ifndef _OSL_THREAD_HXX 40 #include <osl/thread.hxx> 41 #endif 42 43 #ifndef _OSL_MUTEX_HXX 44 #include <osl/mutex.hxx> 45 #endif 46 #include <osl/time.h> 47 48 #include "gtest/gtest.h" 49 50 using namespace osl; 51 using namespace rtl; 52 53 #ifdef UNX 54 #include <unistd.h> 55 #include <time.h> 56 #endif 57 // ----------------------------------------------------------------------------- 58 // Kleine Stopuhr 59 class StopWatch { 60 TimeValue t1,t2; // Start und Stopzeit 61 62 protected: 63 sal_Int32 m_nNanoSec; 64 sal_Int32 m_nSeconds; 65 66 bool m_bIsValid; // TRUE, wenn gestartet und gestoppt 67 bool m_bIsRunning; // TRUE, wenn gestartet. 68 69 public: 70 StopWatch(); 71 ~StopWatch() {} 72 73 void start(); // Startet Timer 74 void stop(); // Stoppt Timer 75 76 double getSeconds() const; 77 double getTenthSec() const; 78 }; 79 80 // ================================= Stop Watch ================================= 81 82 // Eine kleine Stop-Uhr fuer den internen Gebrauch. 83 // (c) Lars Langhans 29.12.1996 22:10 84 85 StopWatch::StopWatch():m_bIsValid(false),m_bIsRunning(false) {} 86 87 void StopWatch::start() 88 { 89 // pre: % 90 // post: Start Timer 91 92 m_bIsValid = false; 93 m_bIsRunning = true; 94 osl_getSystemTime( &t1 ); 95 printf("# %d %d nsecs\n", t1.Seconds, t1.Nanosec); 96 // gettimeofday(&t1, 0); 97 } 98 99 void StopWatch::stop() 100 { 101 // pre: Timer should be started 102 // post: Timer will stopped 103 104 // gettimeofday(&t2, 0); // Timer ausfragen 105 osl_getSystemTime( &t2 ); 106 printf("# %d %d nsecs\n", t2.Seconds, t2.Nanosec); 107 108 if (m_bIsRunning) 109 { // check ob gestartet. 110 // LLA: old m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec); 111 // LLA: old m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds); 112 // LLA: old if (m_nNanoSec < 0) 113 // LLA: old { 114 // LLA: old m_nNanoSec += 1000000000; 115 // LLA: old m_nSeconds -= 1; 116 // LLA: old } 117 //m_nNanoSec = t2.Nanosec - t1.Nanosec; 118 m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds); 119 if ( t2.Nanosec > t1.Nanosec ) 120 m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec); 121 else 122 { 123 m_nNanoSec = 1000000000 + static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec); 124 m_nSeconds -= 1; 125 } 126 printf("# %d %d nsecs\n", m_nSeconds, m_nNanoSec ); 127 //if (m_nNanoSec < 0) 128 //{ 129 //m_nNanoSec += 1000000000; 130 //m_nSeconds -= 1; 131 //} 132 m_bIsValid = true; 133 m_bIsRunning = false; 134 } 135 } 136 137 double StopWatch::getSeconds() const 138 { 139 // pre: gueltig = TRUE 140 // BACK: Zeit in Sekunden. 141 142 double nValue = 0.0; 143 if (m_bIsValid) 144 { 145 nValue = double(m_nNanoSec) / 1000000000.0 + m_nSeconds; // milli micro nano 146 } 147 return nValue; 148 } 149 150 double StopWatch::getTenthSec() const 151 { 152 double nValue = 0.0; 153 if (m_bIsValid) 154 { 155 nValue = double(m_nNanoSec) / 100000000.0 + m_nSeconds * 10; 156 } 157 return nValue ; 158 } 159 160 // ----------------------------------------------------------------------------- 161 template <class T> 162 class ThreadSafeValue 163 { 164 T m_nFlag; 165 Mutex m_aMutex; 166 public: 167 ThreadSafeValue(T n = 0): m_nFlag(n) {} 168 T getValue() 169 { 170 //block if already acquired by another thread. 171 osl::MutexGuard g(m_aMutex); 172 return m_nFlag; 173 } 174 void addValue(T n) 175 { 176 //only one thread operate on the flag. 177 osl::MutexGuard g(m_aMutex); 178 m_nFlag += n; 179 } 180 void acquire() {m_aMutex.acquire();} 181 void release() {m_aMutex.release();} 182 }; 183 184 // ----------------------------------------------------------------------------- 185 namespace ThreadHelper 186 { 187 // typedef enum { 188 // QUIET=1, 189 // VERBOSE 190 // } eSleepVerboseMode; 191 192 void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/) 193 { 194 // if (nVerbose == VERBOSE) 195 // { 196 // printf("wait %d tenth seconds. ", _nTenthSec ); 197 // fflush(stdout); 198 // } 199 #ifdef WNT //Windows 200 Sleep(_nTenthSec * 100 ); 201 #endif 202 #if ( defined UNX ) || ( defined OS2 ) //Unix 203 TimeValue nTV; 204 nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 ); 205 nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 ); 206 osl_waitThread(&nTV); 207 #endif 208 // if (nVerbose == VERBOSE) 209 // { 210 // printf("done\n"); 211 // } 212 } 213 214 void outputPriority(oslThreadPriority const& _aPriority) 215 { 216 // LLA: output the priority 217 if (_aPriority == osl_Thread_PriorityHighest) 218 { 219 printf("Prio is High\n"); 220 } 221 else if (_aPriority == osl_Thread_PriorityAboveNormal) 222 { 223 printf("Prio is above normal\n"); 224 } 225 else if (_aPriority == osl_Thread_PriorityNormal) 226 { 227 printf("Prio is normal\n"); 228 } 229 else if (_aPriority == osl_Thread_PriorityBelowNormal) 230 { 231 printf("Prio is below normal\n"); 232 } 233 else if (_aPriority == osl_Thread_PriorityLowest) 234 { 235 printf("Prio is lowest\n"); 236 } 237 else 238 { 239 printf("Prio is unknown\n"); 240 } 241 } 242 } 243 244 /** Simple thread for testing Thread-create. 245 246 Just add 1 of value 0, and after running, result is 1. 247 */ 248 class myThread : public Thread 249 { 250 ThreadSafeValue<sal_Int32> m_aFlag; 251 public: 252 sal_Int32 getValue() { return m_aFlag.getValue(); } 253 protected: 254 /** guarded value which initialized 0 255 256 @see ThreadSafeValue 257 */ 258 void SAL_CALL run() 259 { 260 while(schedule()) 261 { 262 m_aFlag.addValue(1); 263 ThreadHelper::thread_sleep_tenth_sec(1); 264 } 265 } 266 267 public: 268 269 virtual void SAL_CALL suspend() 270 { 271 m_aFlag.acquire(); 272 ::osl::Thread::suspend(); 273 m_aFlag.release(); 274 } 275 276 ~myThread() 277 { 278 if (isRunning()) 279 { 280 printf("error: not terminated.\n"); 281 } 282 } 283 284 }; 285 286 // ----------------------------------------------------------------------------- 287 /** Thread which has a flag add 1 every second until 20 288 */ 289 class OCountThread : public Thread 290 { 291 ThreadSafeValue<sal_Int32> m_aFlag; 292 public: 293 OCountThread() 294 { 295 m_nWaitSec = 0; 296 printf("new OCountThread thread %d!\n", getIdentifier()); 297 } 298 sal_Int32 getValue() { return m_aFlag.getValue(); } 299 300 void setWait(sal_Int32 nSec) 301 { 302 m_nWaitSec = nSec; 303 //m_bWait = sal_True; 304 } 305 306 virtual void SAL_CALL suspend() 307 { 308 m_aFlag.acquire(); 309 ::osl::Thread::suspend(); 310 m_aFlag.release(); 311 } 312 313 protected: 314 //sal_Bool m_bWait; 315 sal_Int32 m_nWaitSec; 316 317 void SAL_CALL run() 318 { 319 /// if the thread should terminate, schedule return false 320 while (m_aFlag.getValue() < 20 && schedule() == sal_True) 321 { 322 m_aFlag.addValue(1); 323 ThreadHelper::thread_sleep_tenth_sec(1); 324 // TimeValue nTV; 325 // nTV.Seconds = 1; 326 // nTV.Nanosec = 0; 327 // wait(nTV); 328 329 if (m_nWaitSec != 0) 330 { 331 //ThreadHelper::thread_sleep_tenth_sec(m_nWaitSec * 10); 332 TimeValue nTV; 333 nTV.Seconds = m_nWaitSec / 10 ; 334 nTV.Nanosec = ( m_nWaitSec%10 ) * 100000000 ; 335 wait( nTV ); 336 m_nWaitSec = 0; 337 } 338 } 339 } 340 void SAL_CALL onTerminated() 341 { 342 printf("normally terminate this thread %d!\n", getIdentifier()); 343 } 344 public: 345 346 ~OCountThread() 347 { 348 if (isRunning()) 349 { 350 printf("error: not terminated.\n"); 351 } 352 } 353 354 }; 355 356 /** call suspend in the run method 357 */ 358 class OSuspendThread : public Thread 359 { 360 ThreadSafeValue<sal_Int32> m_aFlag; 361 public: 362 OSuspendThread(){ m_bSuspend = sal_False; } 363 sal_Int32 getValue() { return m_aFlag.getValue(); } 364 void setSuspend() 365 { 366 m_bSuspend = sal_True; 367 } 368 virtual void SAL_CALL suspend() 369 { 370 m_aFlag.acquire(); 371 ::osl::Thread::suspend(); 372 m_aFlag.release(); 373 } 374 protected: 375 sal_Bool m_bSuspend; 376 void SAL_CALL run() 377 { 378 //if the thread should terminate, schedule return false 379 while (schedule() == sal_True) 380 { 381 m_aFlag.addValue(1); 382 383 ThreadHelper::thread_sleep_tenth_sec(1); 384 // m_bWait = sal_False; 385 // TimeValue nTV; 386 // nTV.Seconds = 1; 387 // nTV.Nanosec = 0; 388 // wait(nTV); 389 if (m_bSuspend == sal_True) 390 { 391 suspend(); 392 m_bSuspend = sal_False; 393 } 394 } 395 } 396 public: 397 398 ~OSuspendThread() 399 { 400 if (isRunning()) 401 { 402 printf("error: not terminated.\n"); 403 } 404 } 405 406 }; 407 408 /** no call schedule in the run method 409 */ 410 class ONoScheduleThread : public Thread 411 { 412 ThreadSafeValue<sal_Int32> m_aFlag; 413 public: 414 sal_Int32 getValue() { return m_aFlag.getValue(); } 415 416 virtual void SAL_CALL suspend() 417 { 418 m_aFlag.acquire(); 419 ::osl::Thread::suspend(); 420 m_aFlag.release(); 421 } 422 protected: 423 void SAL_CALL run() 424 { 425 while (m_aFlag.getValue() < 10) 426 { 427 m_aFlag.addValue(1); 428 ThreadHelper::thread_sleep_tenth_sec(1); 429 // TimeValue nTV; 430 // nTV.Seconds = 1; 431 // nTV.Nanosec = 0; 432 // wait(nTV); 433 } 434 } 435 void SAL_CALL onTerminated() 436 { 437 printf("normally terminate this thread %d!\n", getIdentifier()); 438 } 439 public: 440 ONoScheduleThread() 441 { 442 printf("new thread id %d!\n", getIdentifier()); 443 } 444 ~ONoScheduleThread() 445 { 446 if (isRunning()) 447 { 448 printf("error: not terminated.\n"); 449 } 450 } 451 452 }; 453 454 /** 455 */ 456 class OAddThread : public Thread 457 { 458 ThreadSafeValue<sal_Int32> m_aFlag; 459 public: 460 //oslThreadIdentifier m_id, m_CurId; 461 OAddThread(){} 462 sal_Int32 getValue() { return m_aFlag.getValue(); } 463 464 virtual void SAL_CALL suspend() 465 { 466 m_aFlag.acquire(); 467 ::osl::Thread::suspend(); 468 m_aFlag.release(); 469 } 470 protected: 471 void SAL_CALL run() 472 { 473 //if the thread should terminate, schedule return false 474 while (schedule() == sal_True) 475 { 476 m_aFlag.addValue(1); 477 } 478 } 479 void SAL_CALL onTerminated() 480 { 481 // printf("normally terminate this thread %d!\n", getIdentifier()); 482 } 483 public: 484 485 ~OAddThread() 486 { 487 if (isRunning()) 488 { 489 // printf("error: not terminated.\n"); 490 } 491 } 492 493 }; 494 495 namespace osl_Thread 496 { 497 498 void resumeAndWaitThread(Thread* _pThread) 499 { 500 // This functions starts a thread, wait a second and suspends the thread 501 // Due to the fact, that a suspend and never run thread never really exists. 502 503 // Note: on UNX, after createSuspended, and then terminate the thread, it performs well; 504 // while on Windows, after createSuspended, the thread can not terminate, wait endlessly, 505 // so here call resume at first, then call terminate. 506 #ifdef WNT 507 printf("resumeAndWaitThread\n"); 508 _pThread->resume(); 509 ThreadHelper::thread_sleep_tenth_sec(1); 510 #else 511 _pThread->resume(); 512 #endif 513 // ThreadHelper::thread_sleep_tenth_sec(1); 514 // _pThread->suspend(); 515 // ThreadHelper::thread_sleep_tenth_sec(1); 516 } 517 518 // kill a running thread and join it, if it has terminated, do nothing 519 void termAndJoinThread(Thread* _pThread) 520 { 521 _pThread->terminate(); 522 523 // LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up 524 #ifdef WNT 525 _pThread->resume(); 526 ThreadHelper::thread_sleep_tenth_sec(1); 527 #endif 528 printf("#wait for join.\n"); 529 _pThread->join(); 530 } 531 /** Test of the osl::Thread::create method 532 */ 533 534 class create : public ::testing::Test 535 { 536 public: 537 538 // initialise your test code values here. 539 void SetUp() 540 { 541 } 542 543 void TearDown() 544 { 545 } 546 }; // class create 547 548 549 /** Simple create a thread. 550 551 Create a simple thread, it just does add 1 to value(which initialized 0), 552 if the thread run, the value should be 1. 553 */ 554 TEST_F(create, create_001) 555 { 556 myThread* newthread = new myThread(); 557 sal_Bool bRes = newthread->create(); 558 ASSERT_TRUE(bRes == sal_True) << "Can not creates a new thread!\n"; 559 560 ThreadHelper::thread_sleep_tenth_sec(1); // wait short 561 sal_Bool isRunning = newthread->isRunning(); // check if thread is running 562 /// wait for the new thread to assure it has run 563 ThreadHelper::thread_sleep_tenth_sec(3); 564 sal_Int32 nValue = newthread->getValue(); 565 /// to assure the new thread has terminated 566 termAndJoinThread(newthread); 567 delete newthread; 568 569 printf(" nValue = %d\n", nValue); 570 printf("isRunning = %d\n", isRunning); 571 572 ASSERT_TRUE(nValue >= 1 && isRunning == sal_True) << "Creates a new thread"; 573 574 } 575 576 /** only one running thread per instance, return false if create secondly 577 */ 578 TEST_F(create, create_002) 579 { 580 myThread* newthread = new myThread(); 581 sal_Bool res1 = newthread->create(); 582 sal_Bool res2 = newthread->create(); 583 printf("In non pro, an assertion should occured. This behaviour is right.\n"); 584 termAndJoinThread(newthread); 585 delete newthread; 586 587 ASSERT_TRUE(res1 && !res2) << "Creates a new thread: can not create two threads per instance"; 588 589 } 590 591 592 /** Test of the osl::Thread::createSuspended method 593 */ 594 class createSuspended : public ::testing::Test 595 { 596 public: 597 // initialise your test code values here. 598 void SetUp() 599 { 600 } 601 602 void TearDown() 603 { 604 } 605 }; // class createSuspended 606 607 /** Create a suspended thread, use the same class as create_001 608 609 after create, wait enough time, check the value, if it's still the initial value, pass 610 */ 611 TEST_F(createSuspended, createSuspended_001) 612 { 613 myThread* newthread = new myThread(); 614 sal_Bool bRes = newthread->createSuspended(); 615 ASSERT_TRUE(bRes == sal_True) << "Can not creates a new thread!"; 616 617 ThreadHelper::thread_sleep_tenth_sec(1); 618 sal_Bool isRunning = newthread->isRunning(); 619 ThreadHelper::thread_sleep_tenth_sec(3); 620 sal_Int32 nValue = newthread->getValue(); 621 622 resumeAndWaitThread(newthread); 623 624 termAndJoinThread(newthread); 625 delete newthread; 626 627 ASSERT_TRUE(nValue == 0 && isRunning) << "Creates a new suspended thread"; 628 } 629 // LLA: Deadlocked!!! 630 TEST_F(createSuspended, createSuspended_002) 631 { 632 myThread* newthread = new myThread(); 633 sal_Bool res1 = newthread->createSuspended(); 634 sal_Bool res2 = newthread->createSuspended(); 635 636 resumeAndWaitThread(newthread); 637 638 termAndJoinThread(newthread); 639 640 delete newthread; 641 642 ASSERT_TRUE(res1 && !res2) << "Creates a new thread: can not create two threads per instance"; 643 } 644 645 646 /** when the count value equal to or more than 3, suspend the thread. 647 */ 648 void suspendCountThread(OCountThread* _pCountThread) 649 { 650 sal_Int32 nValue = 0; 651 while (1) 652 { 653 nValue = _pCountThread->getValue(); 654 if (nValue >= 3) 655 { 656 _pCountThread->suspend(); 657 break; 658 } 659 } 660 } 661 662 /** Test of the osl::Thread::suspend method 663 */ 664 class suspend : public ::testing::Test 665 { 666 public: 667 // initialise your test code values here. 668 void SetUp() 669 { 670 } 671 672 void TearDown() 673 { 674 } 675 }; // class suspend 676 677 /** Use a thread which has a flag added 1 every second 678 679 ALGORITHM: 680 create the thread, after running special time, record value of flag, then suspend it, 681 wait a long time, check the flag, if it remains unchanged during suspending 682 */ 683 TEST_F(suspend, suspend_001) 684 { 685 OCountThread* aCountThread = new OCountThread(); 686 sal_Bool bRes = aCountThread->create(); 687 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 688 // the thread run for some seconds, but not terminate 689 suspendCountThread( aCountThread ); 690 691 // the value just after calling suspend 692 sal_Int32 nValue = aCountThread->getValue(); // (2) 693 694 ThreadHelper::thread_sleep_tenth_sec(3); 695 696 // the value after waiting 3 seconds 697 sal_Int32 nLaterValue = aCountThread->getValue(); // (3) 698 699 resumeAndWaitThread(aCountThread); 700 termAndJoinThread(aCountThread); 701 delete aCountThread; 702 703 ASSERT_TRUE(bRes == sal_True && nValue == nLaterValue) << "Suspend the thread"; 704 705 } 706 /** suspend a thread in it's worker-function, the ALGORITHM is same as suspend_001 707 reason of deadlocked I think: no schedule can schedule other threads to go on excuting 708 */ 709 TEST_F(suspend, suspend_002) 710 { 711 #if 0 712 OSuspendThread* aThread = new OSuspendThread(); 713 sal_Bool bRes = aThread->create(); 714 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 715 // first the thread run for some seconds, but not terminate 716 sal_Int32 nValue = 0; 717 //while (1) 718 //{ 719 ThreadHelper::thread_sleep_tenth_sec(3); 720 nValue = aThread->getValue(); // (1) 721 printf(" getValue is %d !", nValue ); 722 if (nValue >= 2) 723 { 724 aThread->setSuspend(); 725 //break; 726 } 727 //} 728 printf(" after while!"); 729 // the value just after calling suspend 730 nValue = aThread->getValue(); // (2) 731 732 ThreadHelper::thread_sleep_tenth_sec(3); 733 printf(" after sleep!"); 734 // the value after waiting 3 seconds 735 sal_Int32 nLaterValue = aThread->getValue(); // (3) 736 737 //resumeAndWaitThread(aThread); 738 aThread->resume(); 739 termAndJoinThread(aThread); 740 delete aThread; 741 742 ASSERT_TRUE(bRes == sal_True && nValue == nLaterValue) << "Suspend the thread"; 743 #endif 744 } 745 746 747 /** Test of the osl::Thread::resume method 748 */ 749 class resume : public ::testing::Test 750 { 751 public: 752 // initialise your test code values here. 753 void SetUp() 754 { 755 } 756 757 void TearDown() 758 { 759 } 760 }; // class resume 761 762 /** check if the thread run samely as usual after suspend and resume 763 764 ALGORITHM: 765 compare the values before and after suspend, they should be same, 766 then compare values before and after resume, the difference should be same as the sleep seconds number 767 */ 768 TEST_F(resume, resume_001) 769 { 770 OCountThread* pCountThread = new OCountThread(); 771 sal_Bool bRes = pCountThread->create(); 772 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 773 774 suspendCountThread(pCountThread); 775 776 sal_Int32 nSuspendValue = pCountThread->getValue(); // (2) 777 // suspend for 3 seconds 778 ThreadHelper::thread_sleep_tenth_sec(3); 779 pCountThread->resume(); 780 781 ThreadHelper::thread_sleep_tenth_sec(3); 782 sal_Int32 nResumeValue = pCountThread->getValue(); 783 784 ThreadHelper::thread_sleep_tenth_sec(3); 785 sal_Int32 nLaterValue = pCountThread->getValue(); 786 787 termAndJoinThread(pCountThread); 788 delete pCountThread; 789 790 printf("SuspendValue: %d\n", nSuspendValue); 791 printf("ResumeValue: %d\n", nResumeValue); 792 printf("LaterValue: %d\n", nLaterValue); 793 794 /* LLA: this assumption is no longer relevant: nResumeValue == nSuspendValue && */ 795 ASSERT_TRUE(nLaterValue >= 9 && 796 nResumeValue > nSuspendValue && 797 nLaterValue > nResumeValue) << "Suspend then resume the thread"; 798 799 } 800 801 /** Create a suspended thread then resume, check if the thread has run 802 */ 803 TEST_F(resume, resume_002) 804 { 805 myThread* newthread = new myThread(); 806 sal_Bool bRes = newthread->createSuspended(); 807 ASSERT_TRUE(bRes == sal_True) << "Can't create thread!"; 808 809 newthread->resume(); 810 ThreadHelper::thread_sleep_tenth_sec(2); 811 sal_Int32 nValue = newthread->getValue(); 812 813 termAndJoinThread(newthread); 814 delete newthread; 815 816 printf(" nValue = %d\n", nValue); 817 818 ASSERT_TRUE(nValue >= 1) << "Creates a suspended thread, then resume"; 819 } 820 821 /** Test of the osl::Thread::terminate method 822 */ 823 class terminate : public ::testing::Test 824 { 825 public: 826 // initialise your test code values here. 827 void SetUp() 828 { 829 } 830 831 void TearDown() 832 { 833 } 834 }; // class terminate 835 836 /** Check after call terminate if the running thread running go on executing 837 838 ALGORITHM: 839 before and after call terminate, the values should be the same 840 */ 841 TEST_F(terminate, terminate_001) 842 { 843 OCountThread* aCountThread = new OCountThread(); 844 sal_Bool bRes = aCountThread->create(); 845 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 846 847 ThreadHelper::thread_sleep_tenth_sec(2); 848 sal_Int32 nValue = aCountThread->getValue(); 849 aCountThread->terminate(); 850 ThreadHelper::thread_sleep_tenth_sec(2); 851 sal_Int32 nLaterValue = aCountThread->getValue(); 852 853 // isRunning should be false after terminate 854 sal_Bool isRunning = aCountThread->isRunning(); 855 aCountThread->join(); 856 delete aCountThread; 857 858 printf(" nValue = %d\n", nValue); 859 printf("nLaterValue = %d\n", nLaterValue); 860 861 ASSERT_TRUE(isRunning == sal_False && nLaterValue >= nValue) << "Terminate the thread"; 862 } 863 /** Check if a suspended thread will terminate after call terminate, different on w32 and on UNX 864 */ 865 TEST_F(terminate, terminate_002) 866 { 867 OCountThread* aCountThread = new OCountThread(); 868 sal_Bool bRes = aCountThread->create(); 869 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 870 871 ThreadHelper::thread_sleep_tenth_sec(1); 872 suspendCountThread(aCountThread); 873 sal_Int32 nValue = aCountThread->getValue(); 874 875 // seems a suspended thread can not be terminated on W32, while on Solaris can 876 resumeAndWaitThread(aCountThread); 877 878 ThreadHelper::thread_sleep_tenth_sec(2); 879 880 termAndJoinThread(aCountThread); 881 sal_Int32 nLaterValue = aCountThread->getValue(); 882 delete aCountThread; 883 884 printf(" nValue = %d\n", nValue); 885 printf("nLaterValue = %d\n", nLaterValue); 886 887 ASSERT_TRUE(nLaterValue > nValue) << "Suspend then resume the thread"; 888 } 889 890 891 /** Test of the osl::Thread::join method 892 */ 893 class join : public ::testing::Test 894 { 895 public: 896 // initialise your test code values here. 897 void SetUp() 898 { 899 } 900 901 void TearDown() 902 { 903 } 904 }; // class join 905 906 /** Check after call terminate if the thread running function will not go on executing 907 908 the next statement after join will not exec before the thread terminate 909 ALGORITHM: 910 recode system time at the beginning of the thread run, call join, then record system time again, 911 the difference of the two time should be equal or more than 20 seconds, the CountThead normally terminate 912 */ 913 TEST_F(join, join_001) 914 { 915 OCountThread *aCountThread = new OCountThread(); 916 sal_Bool bRes = aCountThread->create(); 917 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 918 919 StopWatch aStopWatch; 920 aStopWatch.start(); 921 // TimeValue aTimeVal_befor; 922 // osl_getSystemTime( &aTimeVal_befor ); 923 //printf("#join:the system time is %d,%d\n", pTimeVal_befor->Seconds,pTimeVal_befor->Nanosec); 924 925 aCountThread->join(); 926 927 //the below line will be executed after aCountThread terminate 928 // TimeValue aTimeVal_after; 929 // osl_getSystemTime( &aTimeVal_after ); 930 aStopWatch.stop(); 931 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds; 932 double nSec = aStopWatch.getSeconds(); 933 printf("join_001 nSec=%f\n", nSec); 934 delete aCountThread; 935 936 ASSERT_TRUE(nSec >= 2) << "Join the thread: after the thread terminate"; 937 938 } 939 /** after terminated by another thread, join exited immediately 940 941 ALGORITHM: 942 terminate the thread when value>=3, call join, check the beginning time and time after join, 943 the difference should be 3 seconds, join costs little time 944 */ 945 TEST_F(join, join_002) 946 { 947 OCountThread *aCountThread = new OCountThread(); 948 sal_Bool bRes = aCountThread->create(); 949 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 950 951 //record the time when the running begin 952 // TimeValue aTimeVal_befor; 953 // osl_getSystemTime( &aTimeVal_befor ); 954 StopWatch aStopWatch; 955 aStopWatch.start(); 956 957 ThreadHelper::thread_sleep_tenth_sec(10); 958 termAndJoinThread(aCountThread); 959 960 //the below line will be executed after aCountThread terminate 961 // TimeValue aTimeVal_after; 962 // osl_getSystemTime( &aTimeVal_after ); 963 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds; 964 aStopWatch.stop(); 965 double nSec = aStopWatch.getSeconds(); 966 printf("join_002 nSec=%f\n", nSec); 967 968 delete aCountThread; 969 ASSERT_TRUE(nSec >= 1) << "Join the thread: after thread terminate by another thread"; 970 } 971 972 /** Test of the osl::Thread::isRunning method 973 */ 974 class isRunning : public ::testing::Test 975 { 976 public: 977 // initialise your test code values here. 978 void SetUp() 979 { 980 } 981 982 void TearDown() 983 { 984 } 985 }; // class isRunning 986 987 /** 988 */ 989 TEST_F(isRunning, isRunning_001) 990 { 991 OCountThread *aCountThread = new OCountThread(); 992 sal_Bool bRes = aCountThread->create(); 993 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 994 995 sal_Bool bRun = aCountThread->isRunning(); 996 997 ThreadHelper::thread_sleep_tenth_sec(2); 998 termAndJoinThread(aCountThread); 999 sal_Bool bTer = aCountThread->isRunning(); 1000 delete aCountThread; 1001 1002 ASSERT_TRUE(bRun == sal_True && bTer == sal_False) << "Test isRunning"; 1003 } 1004 /** check the value of isRunning when suspending and after resume 1005 */ 1006 TEST_F(isRunning, isRunning_002) 1007 { 1008 OCountThread *aCountThread = new OCountThread(); 1009 sal_Bool bRes = aCountThread->create(); 1010 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 1011 1012 // sal_Bool bRunning = aCountThread->isRunning(); 1013 // sal_Int32 nValue = 0; 1014 suspendCountThread(aCountThread); 1015 1016 sal_Bool bRunning_sup = aCountThread->isRunning(); 1017 ThreadHelper::thread_sleep_tenth_sec(2); 1018 aCountThread->resume(); 1019 ThreadHelper::thread_sleep_tenth_sec(2); 1020 sal_Bool bRunning_res = aCountThread->isRunning(); 1021 termAndJoinThread(aCountThread); 1022 sal_Bool bRunning_ter = aCountThread->isRunning(); 1023 delete aCountThread; 1024 1025 ASSERT_TRUE(bRes == sal_True && 1026 bRunning_sup == sal_True && 1027 bRunning_res == sal_True && 1028 bRunning_ter == sal_False) << "Test isRunning"; 1029 1030 } 1031 1032 /// check osl::Thread::setPriority 1033 class setPriority : public ::testing::Test 1034 { 1035 public: 1036 // initialise your test code values here. 1037 void SetUp() 1038 { 1039 } 1040 1041 void TearDown() 1042 { 1043 } 1044 1045 // insert your test code here. 1046 rtl::OString getPrioName(oslThreadPriority _aPriority) 1047 { 1048 rtl::OString sPrioStr; 1049 switch (_aPriority) 1050 { 1051 case osl_Thread_PriorityHighest: 1052 sPrioStr = "Highest"; 1053 break; 1054 1055 case osl_Thread_PriorityAboveNormal: 1056 sPrioStr = "AboveNormal"; 1057 1058 case osl_Thread_PriorityNormal: 1059 sPrioStr = "Normal"; 1060 1061 case osl_Thread_PriorityBelowNormal: 1062 sPrioStr = "BelowNormal"; 1063 break; 1064 1065 case osl_Thread_PriorityLowest: 1066 sPrioStr = "Lowest"; 1067 break; 1068 default: 1069 sPrioStr = "unknown"; 1070 } 1071 return sPrioStr; 1072 } 1073 1074 1075 /** check 2 threads. 1076 1077 ALGORITHM: 1078 Here the function should show, that 2 different threads, 1079 which only increase a value, should run at the same time with same prio. 1080 The test fails, if the difference between the two values is more than 5% 1081 but IMHO this isn't a failure, it's only a feature of the OS. 1082 */ 1083 1084 void check2Threads(oslThreadPriority _aPriority) 1085 { 1086 // initial 5 threads with different priorities 1087 OAddThread* pThread = new OAddThread(); 1088 OAddThread* p2Thread = new OAddThread(); 1089 1090 //Create them and start running at the same time 1091 pThread->create(); 1092 pThread->setPriority(_aPriority); 1093 p2Thread->create(); 1094 p2Thread->setPriority(_aPriority); 1095 1096 ThreadHelper::thread_sleep_tenth_sec(5); 1097 1098 pThread->terminate(); 1099 p2Thread->terminate(); 1100 1101 sal_Int32 nValueNormal = 0; 1102 nValueNormal = pThread->getValue(); 1103 1104 sal_Int32 nValueNormal2 = 0; 1105 nValueNormal2 = p2Thread->getValue(); 1106 1107 rtl::OString sPrio = getPrioName(_aPriority); 1108 printf("After 10 tenth seconds\n"); 1109 1110 printf("nValue in %s Prio Thread is %d\n",sPrio.getStr(), nValueNormal); 1111 printf("nValue in %s Prio Thread is %d\n", sPrio.getStr(), nValueNormal2); 1112 1113 // ThreadHelper::thread_sleep_tenth_sec(1); 1114 pThread->join(); 1115 p2Thread->join(); 1116 1117 delete pThread; 1118 delete p2Thread; 1119 1120 sal_Int32 nDelta = abs(nValueNormal - nValueNormal2); 1121 double nQuotient = std::max(nValueNormal, nValueNormal2); 1122 ASSERT_TRUE(nQuotient != 0) << "Quotient is zero, which means, there exist no right values."; 1123 double nDeltaPercent = nDelta / nQuotient * 100; 1124 1125 printf("Delta value %d, percent %f\n",nDelta, nDeltaPercent); 1126 1127 // LLA: it's not a bug if the current OS is not able to handle thread scheduling right and good. 1128 // like Windows XP 1129 // LLA: ASSERT_TRUE(// LLA: nDeltaPercent <= 5 1130 // LLA:) << // LLA: "Run 2 normal threads, the count diff more than 5 percent."; 1131 } 1132 }; // class setPriority 1133 1134 TEST_F(setPriority, setPriority_001_1) 1135 { 1136 check2Threads(osl_Thread_PriorityHighest); 1137 } 1138 TEST_F(setPriority, setPriority_001_2) 1139 { 1140 check2Threads(osl_Thread_PriorityAboveNormal); 1141 } 1142 TEST_F(setPriority, setPriority_001_3) 1143 { 1144 check2Threads(osl_Thread_PriorityNormal); 1145 } 1146 TEST_F(setPriority, setPriority_001_4) 1147 { 1148 check2Threads(osl_Thread_PriorityBelowNormal); 1149 } 1150 TEST_F(setPriority, setPriority_001_5) 1151 { 1152 check2Threads(osl_Thread_PriorityLowest); 1153 } 1154 1155 #ifndef SOLARIS 1156 TEST_F(setPriority, setPriority_002) 1157 { 1158 // initial 5 threads with different priorities 1159 1160 OAddThread aHighestThread; 1161 OAddThread aAboveNormalThread; 1162 OAddThread aNormalThread; 1163 //OAddThread *aBelowNormalThread = new OAddThread(); 1164 //OAddThread *aLowestThread = new OAddThread(); 1165 1166 //Create them and start running at the same time 1167 aHighestThread.createSuspended(); 1168 aHighestThread.setPriority(osl_Thread_PriorityHighest); 1169 1170 aAboveNormalThread.createSuspended(); 1171 aAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal); 1172 1173 aNormalThread.createSuspended(); 1174 aNormalThread.setPriority(osl_Thread_PriorityNormal); 1175 /*aBelowNormalThread->create(); 1176 aBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal); 1177 aLowestThread->create(); 1178 aLowestThread->setPriority(osl_Thread_PriorityLowest); 1179 */ 1180 1181 aHighestThread.resume(); 1182 aAboveNormalThread.resume(); 1183 aNormalThread.resume(); 1184 1185 ThreadHelper::thread_sleep_tenth_sec(5); 1186 1187 aHighestThread.suspend(); 1188 aAboveNormalThread.suspend(); 1189 aNormalThread.suspend(); 1190 1191 termAndJoinThread(&aNormalThread); 1192 termAndJoinThread(&aAboveNormalThread); 1193 termAndJoinThread(&aHighestThread); 1194 //aBelowNormalThread->terminate(); 1195 //aLowestThread->terminate(); 1196 1197 sal_Int32 nValueHighest = 0; 1198 nValueHighest = aHighestThread.getValue(); 1199 1200 sal_Int32 nValueAboveNormal = 0; 1201 nValueAboveNormal = aAboveNormalThread.getValue(); 1202 1203 sal_Int32 nValueNormal = 0; 1204 nValueNormal = aNormalThread.getValue(); 1205 1206 // sal_Int32 nValueBelowNormal = 0; 1207 //nValueBelowNormal = aBelowNormalThread->getValue(); 1208 // sal_Int32 nValueLowest = 0; 1209 //nValueLowest = aLowestThread->getValue(); 1210 printf("After 10 tenth seconds\n"); 1211 printf("nValue in Highest Prio Thread is %d\n",nValueHighest); 1212 printf("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal); 1213 printf("nValue in Normal Prio Thread is %d\n",nValueNormal); 1214 1215 // LLA: this is not a save test, so we only check if all values not zero 1216 // LLA: ASSERT_TRUE(// LLA: nValueHighest >= nValueAboveNormal && 1217 // LLA: nValueAboveNormal >= nValueNormal && 1218 // LLA: nValueNormal > 0 1219 // LLA:) << // LLA: "SetPriority"; 1220 1221 // LLA: windows let starve threads with lower priority 1222 #ifndef WNT 1223 ASSERT_TRUE(nValueHighest > 0 && 1224 nValueAboveNormal > 0 && 1225 nValueNormal > 0) << "SetPriority"; 1226 #endif 1227 } 1228 1229 TEST_F(setPriority, setPriority_003) 1230 { 1231 // initial 5 threads with different priorities 1232 OAddThread *pHighestThread = new OAddThread(); 1233 OAddThread *pAboveNormalThread = new OAddThread(); 1234 OAddThread *pNormalThread = new OAddThread(); 1235 OAddThread *pBelowNormalThread = new OAddThread(); 1236 OAddThread *pLowestThread = new OAddThread(); 1237 1238 //Create them and start running at the same time 1239 pHighestThread->createSuspended(); 1240 pHighestThread->setPriority(osl_Thread_PriorityHighest); 1241 1242 pAboveNormalThread->createSuspended(); 1243 pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal); 1244 1245 pNormalThread->createSuspended(); 1246 pNormalThread->setPriority(osl_Thread_PriorityNormal); 1247 1248 pBelowNormalThread->createSuspended(); 1249 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal); 1250 1251 pLowestThread->createSuspended(); 1252 pLowestThread->setPriority(osl_Thread_PriorityLowest); 1253 1254 pHighestThread->resume(); 1255 pAboveNormalThread->resume(); 1256 pNormalThread->resume(); 1257 pBelowNormalThread->resume(); 1258 pLowestThread->resume(); 1259 1260 ThreadHelper::thread_sleep_tenth_sec(5); 1261 1262 pHighestThread->suspend(); 1263 pAboveNormalThread->suspend(); 1264 pNormalThread->suspend(); 1265 pBelowNormalThread->suspend(); 1266 pLowestThread->suspend(); 1267 1268 termAndJoinThread(pHighestThread); 1269 termAndJoinThread(pAboveNormalThread); 1270 termAndJoinThread(pNormalThread); 1271 termAndJoinThread(pBelowNormalThread); 1272 termAndJoinThread(pLowestThread); 1273 1274 sal_Int32 nValueHighest = 0; 1275 nValueHighest = pHighestThread->getValue(); 1276 1277 sal_Int32 nValueAboveNormal = 0; 1278 nValueAboveNormal = pAboveNormalThread->getValue(); 1279 1280 sal_Int32 nValueNormal = 0; 1281 nValueNormal = pNormalThread->getValue(); 1282 1283 sal_Int32 nValueBelowNormal = 0; 1284 nValueBelowNormal = pBelowNormalThread->getValue(); 1285 1286 sal_Int32 nValueLowest = 0; 1287 nValueLowest = pLowestThread->getValue(); 1288 1289 printf("After 10 tenth seconds\n"); 1290 printf("nValue in Highest Prio Thread is %d\n",nValueHighest); 1291 printf("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal); 1292 printf("nValue in Normal Prio Thread is %d\n",nValueNormal); 1293 printf("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal); 1294 printf("nValue in Lowest Prio Thread is %d\n",nValueLowest); 1295 1296 delete pHighestThread; 1297 delete pAboveNormalThread; 1298 delete pNormalThread; 1299 delete pBelowNormalThread; 1300 delete pLowestThread; 1301 1302 // LLA: this is not a save test, so we only check if all values not zero 1303 // LLA: ASSERT_TRUE(// LLA: nValueHighest > nValueAboveNormal && 1304 // LLA: nValueAboveNormal > nValueNormal && 1305 // LLA: nValueNormal > nValueBelowNormal && 1306 // LLA: nValueBelowNormal > nValueLowest && 1307 // LLA: nValueLowest > 0 1308 // LLA:) << // LLA: "SetPriority"; 1309 1310 // LLA: windows let starve threads with lower priority 1311 #ifndef WNT 1312 ASSERT_TRUE(nValueHighest > 0 && 1313 nValueAboveNormal > 0 && 1314 nValueNormal > 0 && 1315 nValueBelowNormal > 0 && 1316 nValueLowest > 0) << "SetPriority"; 1317 #endif 1318 } 1319 1320 TEST_F(setPriority, setPriority_004) 1321 { 1322 // initial 5 threads with different priorities 1323 // OAddThread *pHighestThread = new OAddThread(); 1324 OAddThread *pAboveNormalThread = new OAddThread(); 1325 OAddThread *pNormalThread = new OAddThread(); 1326 OAddThread *pBelowNormalThread = new OAddThread(); 1327 OAddThread *pLowestThread = new OAddThread(); 1328 1329 //Create them and start running at the same time 1330 // pHighestThread->createSuspended(); 1331 // pHighestThread->setPriority(osl_Thread_PriorityHighest); 1332 1333 pAboveNormalThread->createSuspended(); 1334 pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal); 1335 1336 pNormalThread->createSuspended(); 1337 pNormalThread->setPriority(osl_Thread_PriorityNormal); 1338 1339 pBelowNormalThread->createSuspended(); 1340 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal); 1341 1342 pLowestThread->createSuspended(); 1343 pLowestThread->setPriority(osl_Thread_PriorityLowest); 1344 1345 // pHighestThread->resume(); 1346 pAboveNormalThread->resume(); 1347 pNormalThread->resume(); 1348 pBelowNormalThread->resume(); 1349 pLowestThread->resume(); 1350 1351 ThreadHelper::thread_sleep_tenth_sec(5); 1352 1353 // pHighestThread->suspend(); 1354 pAboveNormalThread->suspend(); 1355 pNormalThread->suspend(); 1356 pBelowNormalThread->suspend(); 1357 pLowestThread->suspend(); 1358 1359 // termAndJoinThread(pHighestThread); 1360 termAndJoinThread(pAboveNormalThread); 1361 termAndJoinThread(pNormalThread); 1362 termAndJoinThread(pBelowNormalThread); 1363 termAndJoinThread(pLowestThread); 1364 1365 // sal_Int32 nValueHighest = 0; 1366 // nValueHighest = pHighestThread->getValue(); 1367 1368 sal_Int32 nValueAboveNormal = 0; 1369 nValueAboveNormal = pAboveNormalThread->getValue(); 1370 1371 sal_Int32 nValueNormal = 0; 1372 nValueNormal = pNormalThread->getValue(); 1373 1374 sal_Int32 nValueBelowNormal = 0; 1375 nValueBelowNormal = pBelowNormalThread->getValue(); 1376 1377 sal_Int32 nValueLowest = 0; 1378 nValueLowest = pLowestThread->getValue(); 1379 1380 printf("After 5 tenth seconds\n"); 1381 // printf("nValue in Highest Prio Thread is %d\n",nValueHighest); 1382 printf("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal); 1383 printf("nValue in Normal Prio Thread is %d\n",nValueNormal); 1384 printf("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal); 1385 printf("nValue in Lowest Prio Thread is %d\n",nValueLowest); 1386 1387 // delete pHighestThread; 1388 delete pAboveNormalThread; 1389 delete pNormalThread; 1390 delete pBelowNormalThread; 1391 delete pLowestThread; 1392 1393 // LLA: this is not a save test, so we only check if all values not zero 1394 // LLA: ASSERT_TRUE(// LLA: nValueHighest > nValueAboveNormal && 1395 // LLA: nValueAboveNormal > nValueNormal && 1396 // LLA: nValueNormal > nValueBelowNormal && 1397 // LLA: nValueBelowNormal > nValueLowest && 1398 // LLA: nValueLowest > 0 1399 // LLA:) << // LLA: "SetPriority"; 1400 1401 // LLA: windows let starve threads with lower priority 1402 #ifndef WNT 1403 ASSERT_TRUE(/* nValueHighest > 0 && */ 1404 nValueAboveNormal > 0 && 1405 nValueNormal > 0 && 1406 nValueBelowNormal > 0 && 1407 nValueLowest > 0) << "SetPriority"; 1408 #endif 1409 } 1410 TEST_F(setPriority, setPriority_005) 1411 { 1412 // initial 5 threads with different priorities 1413 // OAddThread *pHighestThread = new OAddThread(); 1414 // OAddThread *pAboveNormalThread = new OAddThread(); 1415 OAddThread *pNormalThread = new OAddThread(); 1416 OAddThread *pBelowNormalThread = new OAddThread(); 1417 OAddThread *pLowestThread = new OAddThread(); 1418 1419 //Create them and start running at the same time 1420 // pHighestThread->createSuspended(); 1421 // pHighestThread->setPriority(osl_Thread_PriorityHighest); 1422 1423 // pAboveNormalThread->createSuspended(); 1424 // pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal); 1425 1426 pNormalThread->createSuspended(); 1427 pNormalThread->setPriority(osl_Thread_PriorityNormal); 1428 1429 pBelowNormalThread->createSuspended(); 1430 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal); 1431 1432 pLowestThread->createSuspended(); 1433 pLowestThread->setPriority(osl_Thread_PriorityLowest); 1434 1435 // pHighestThread->resume(); 1436 // pAboveNormalThread->resume(); 1437 pNormalThread->resume(); 1438 pBelowNormalThread->resume(); 1439 pLowestThread->resume(); 1440 1441 ThreadHelper::thread_sleep_tenth_sec(5); 1442 1443 // pHighestThread->suspend(); 1444 // pAboveNormalThread->suspend(); 1445 pNormalThread->suspend(); 1446 pBelowNormalThread->suspend(); 1447 pLowestThread->suspend(); 1448 1449 // termAndJoinThread(pHighestThread); 1450 // termAndJoinThread(pAboveNormalThread); 1451 termAndJoinThread(pNormalThread); 1452 termAndJoinThread(pBelowNormalThread); 1453 termAndJoinThread(pLowestThread); 1454 1455 // sal_Int32 nValueHighest = 0; 1456 // nValueHighest = pHighestThread->getValue(); 1457 1458 // sal_Int32 nValueAboveNormal = 0; 1459 // nValueAboveNormal = pAboveNormalThread->getValue(); 1460 1461 sal_Int32 nValueNormal = 0; 1462 nValueNormal = pNormalThread->getValue(); 1463 1464 sal_Int32 nValueBelowNormal = 0; 1465 nValueBelowNormal = pBelowNormalThread->getValue(); 1466 1467 sal_Int32 nValueLowest = 0; 1468 nValueLowest = pLowestThread->getValue(); 1469 1470 printf("After 5 tenth seconds\n"); 1471 // printf("nValue in Highest Prio Thread is %d\n",nValueHighest); 1472 // printf("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal); 1473 printf("nValue in Normal Prio Thread is %d\n",nValueNormal); 1474 printf("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal); 1475 printf("nValue in Lowest Prio Thread is %d\n",nValueLowest); 1476 1477 // delete pHighestThread; 1478 // delete pAboveNormalThread; 1479 delete pNormalThread; 1480 delete pBelowNormalThread; 1481 delete pLowestThread; 1482 1483 // LLA: this is not a save test, so we only check if all values not zero 1484 // LLA: ASSERT_TRUE(// LLA: nValueHighest > nValueAboveNormal && 1485 // LLA: nValueAboveNormal > nValueNormal && 1486 // LLA: nValueNormal > nValueBelowNormal && 1487 // LLA: nValueBelowNormal > nValueLowest && 1488 // LLA: nValueLowest > 0 1489 // LLA:) << // LLA: "SetPriority"; 1490 1491 // LLA: windows let starve threads with lower priority 1492 #ifndef WNT 1493 ASSERT_TRUE(/* nValueHighest > 0 && */ 1494 /* nValueAboveNormal > 0 && */ 1495 nValueNormal > 0 && 1496 nValueBelowNormal > 0 && 1497 nValueLowest > 0) << "SetPriority"; 1498 #endif 1499 } 1500 #endif // SOLARIS 1501 1502 1503 /** Test of the osl::Thread::getPriority method 1504 */ 1505 class getPriority : public ::testing::Test 1506 { 1507 public: 1508 // initialise your test code values here. 1509 void SetUp() 1510 { 1511 } 1512 1513 void TearDown() 1514 { 1515 } 1516 }; // class getPriority 1517 1518 TEST_F(getPriority, getPriority_001) 1519 { 1520 OAddThread *pHighestThread = new OAddThread(); 1521 1522 //Create them and start running at the same time 1523 pHighestThread->create(); 1524 pHighestThread->setPriority(osl_Thread_PriorityHighest); 1525 1526 oslThreadPriority aPriority = pHighestThread->getPriority(); 1527 termAndJoinThread(pHighestThread); 1528 delete pHighestThread; 1529 1530 ThreadHelper::outputPriority(aPriority); 1531 1532 // LLA: Priority settings may not work within some OS versions. 1533 #if ( defined WNT ) || ( defined SOLARIS ) 1534 ASSERT_TRUE(aPriority == osl_Thread_PriorityHighest) << "getPriority"; 1535 #else 1536 // LLA: Linux 1537 // NO_PTHREAD_PRIORITY ??? 1538 ASSERT_TRUE(aPriority == osl_Thread_PriorityNormal) << "getPriority"; 1539 #endif 1540 } 1541 1542 TEST_F(getPriority, getPriority_002) 1543 { 1544 1545 } 1546 1547 1548 class getIdentifier : public ::testing::Test 1549 { 1550 public: 1551 // initialise your test code values here. 1552 void SetUp() 1553 { 1554 } 1555 1556 void TearDown() 1557 { 1558 } 1559 }; // class getIdentifier 1560 1561 // insert your test code here. 1562 TEST_F(getIdentifier, getIdentifier_001) 1563 { 1564 1565 } 1566 1567 TEST_F(getIdentifier, getIdentifier_002) 1568 { 1569 1570 } 1571 1572 /** Test of the osl::Thread::getCurrentIdentifier method 1573 */ 1574 class getCurrentIdentifier : public ::testing::Test 1575 { 1576 public: 1577 // initialise your test code values here. 1578 void SetUp() 1579 { 1580 } 1581 1582 void TearDown() 1583 { 1584 } 1585 }; // class getCurrentIdentifier 1586 1587 // insert your test code here. 1588 TEST_F(getCurrentIdentifier, getCurrentIdentifier_001) 1589 { 1590 oslThreadIdentifier oId; 1591 OCountThread* pCountThread = new OCountThread; 1592 //OCountThread* pCountThread2 = new OCountThread; 1593 pCountThread->create(); 1594 //pCountThread2->create(); 1595 pCountThread->setWait(3); 1596 oId = Thread::getCurrentIdentifier(); 1597 oslThreadIdentifier oIdChild = pCountThread->getIdentifier(); 1598 //printf("CurrentId is %ld, Child1 id is %ld, Child2 id is %ld\n",oId, oIdChild,pCountThread2->m_id ); 1599 termAndJoinThread(pCountThread); 1600 delete pCountThread; 1601 //termAndJoinThread(pCountThread2); 1602 //delete pCountThread2; 1603 1604 ASSERT_TRUE(oId != oIdChild) << "Get the identifier for the current active thread."; 1605 1606 } 1607 1608 TEST_F(getCurrentIdentifier, getCurrentIdentifier_002) 1609 { 1610 } 1611 1612 1613 /** Test of the osl::Thread::wait method 1614 */ 1615 class wait : public ::testing::Test 1616 { 1617 public: 1618 // initialise your test code values here. 1619 void SetUp() 1620 { 1621 } 1622 1623 void TearDown() 1624 { 1625 } 1626 }; // class wait 1627 1628 1629 /** call wait in the run method 1630 1631 ALGORITHM: 1632 tested thread wait nWaitSec seconds, main thread sleep (2) seconds, 1633 then terminate the tested thread, due to the fact that the thread do a sleep(1) + wait(5) 1634 it's finish after 6 seconds. 1635 */ 1636 TEST_F(wait, wait_001) 1637 { 1638 OCountThread *aCountThread = new OCountThread(); 1639 sal_Int32 nWaitSec = 5; 1640 aCountThread->setWait(nWaitSec); 1641 // thread runs at least 5 seconds. 1642 sal_Bool bRes = aCountThread->create(); 1643 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 1644 1645 //record the time when the running begin 1646 StopWatch aStopWatch; 1647 aStopWatch.start(); 1648 1649 // wait a little bit, to let the thread the time, to start 1650 ThreadHelper::thread_sleep_tenth_sec( 4 ); 1651 1652 // if wait works, 1653 // this function returns, after 4 sec. later 1654 termAndJoinThread(aCountThread); 1655 1656 // value should be one. 1657 sal_Int32 nValue = aCountThread->getValue(); 1658 1659 aStopWatch.stop(); 1660 1661 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds; 1662 double nTenthSec = aStopWatch.getTenthSec(); 1663 double nSec = aStopWatch.getSeconds(); 1664 delete aCountThread; 1665 printf("nTenthSec = %f \n", nTenthSec); 1666 printf("nSec = %f \n", nSec); 1667 printf("nValue = %d \n", nValue); 1668 1669 ASSERT_TRUE(nTenthSec >= 5 && nValue == 1) << "Wait: Blocks the calling thread for the given number of time."; 1670 1671 } 1672 // LLA: wait_001 does the same. 1673 // LLA: /** wait then terminate the thread 1674 // LLA: 1675 // LLA: ALGORITHM: 1676 // LLA: wait nWaitSec seconds, and terminate when the wait does not finish 1677 // LLA: Windows & UNX: thread terminates immediatlly 1678 // LLA: */ 1679 // LLA: TEST_F(wait, wait_002) 1680 // LLA: { 1681 // LLA: OCountThread aThread; 1682 // LLA: 1683 // LLA: sal_Int32 nWaitSec = 3; 1684 // LLA: aThread.setWait(nWaitSec); 1685 // LLA: 1686 // LLA: sal_Bool bRes = aThread.create(); 1687 // LLA: ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 1688 // LLA: 1689 // LLA: StopWatch aStopWatch; 1690 // LLA: // TimeValue aTimeVal_befor; 1691 // LLA: // osl_getSystemTime( &aTimeVal_befor ); 1692 // LLA: aStopWatch.start(); 1693 // LLA: 1694 // LLA: termAndJoinThread(&aThread); 1695 // LLA: sal_Int32 nValue = aThread.getValue(); 1696 // LLA: 1697 // LLA: // TimeValue aTimeVal_after; 1698 // LLA: // osl_getSystemTime( &aTimeVal_after ); 1699 // LLA: aStopWatch.stop(); 1700 // LLA: // sal_Int32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds; 1701 // LLA: double nSec = aStopWatch.getSeconds(); 1702 // LLA: printf("sec=%f\n", nSec); 1703 // LLA: printf("nValue = %d\n", nValue); 1704 // LLA: 1705 // LLA: ASSERT_TRUE(// LLA: nSec < 1 && nValue == 0 1706 // LLA:) << // LLA: "Wait: Blocks the calling thread for the given number of time."; 1707 // LLA: } 1708 /** osl::Thread::yield method: can not design good test scenario to test up to now 1709 */ 1710 class yield : public ::testing::Test 1711 { 1712 public: 1713 void SetUp() 1714 { 1715 } 1716 1717 void TearDown() 1718 { 1719 } 1720 }; // class yield 1721 1722 // insert your test code here. 1723 TEST_F(yield, yield_001) 1724 { 1725 } 1726 1727 /** Test of the osl::Thread::schedule method 1728 */ 1729 class schedule : public ::testing::Test 1730 { 1731 public: 1732 // initialise your test code values here. 1733 void SetUp() 1734 { 1735 } 1736 1737 void TearDown() 1738 { 1739 } 1740 }; // class schedule 1741 1742 /** The requested thread will get terminate the next time schedule() is called. 1743 1744 Note: on UNX, if call suspend thread is not the to be suspended thread, the to be 1745 suspended thread will get suspended the next time schedule() is called, 1746 while on w32, it's nothing with schedule. 1747 1748 check if suspend and terminate work well via schedule 1749 */ 1750 TEST_F(schedule, schedule_001) 1751 { 1752 OAddThread* aThread = new OAddThread(); 1753 sal_Bool bRes = aThread->create(); 1754 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 1755 1756 ThreadHelper::thread_sleep_tenth_sec(2); 1757 aThread->suspend(); 1758 ThreadHelper::thread_sleep_tenth_sec(1); 1759 sal_Int32 nValue = aThread->getValue(); 1760 ThreadHelper::thread_sleep_tenth_sec(3); 1761 sal_Int32 nLaterValue = aThread->getValue(); 1762 // resumeAndWaitThread(aThread); 1763 printf(" value = %d\n", nValue); 1764 printf("later value = %d\n", nLaterValue); 1765 // if value and latervalue not equal, than the thread would not suspended 1766 1767 ASSERT_TRUE(nLaterValue == nValue) << "Schedule: suspend works."; 1768 1769 aThread->resume(); 1770 ThreadHelper::thread_sleep_tenth_sec(2); 1771 1772 aThread->terminate(); 1773 sal_Int32 nValue_term = aThread->getValue(); 1774 1775 aThread->join(); 1776 sal_Int32 nValue_join = aThread->getValue(); 1777 1778 printf("value after term = %d\n", nValue_term); 1779 printf("value after join = %d\n", nValue_join); 1780 1781 // nValue_term and nValue_join should be the same 1782 // but should be differ from nValue 1783 1784 delete aThread; 1785 //check if thread really terminate after call terminate, if join immediatlly return 1786 ASSERT_TRUE(nValue_join - nValue_term <= 1 && nValue_join - nValue_term >= 0) << "Schedule: Returns False if the thread should terminate."; 1787 1788 } 1789 1790 /** design a thread that has not call schedule in the workfunction--run method 1791 */ 1792 TEST_F(schedule, schedule_002) 1793 { 1794 ONoScheduleThread aThread; // this thread runs 10 sec. (no schedule() used) 1795 sal_Bool bRes = aThread.create(); 1796 ASSERT_TRUE(bRes == sal_True) << "Can't start thread!"; 1797 1798 ThreadHelper::thread_sleep_tenth_sec(2); 1799 aThread.suspend(); 1800 sal_Int32 nValue = aThread.getValue(); 1801 1802 ThreadHelper::thread_sleep_tenth_sec(3); 1803 sal_Int32 nLaterValue = aThread.getValue(); 1804 ThreadHelper::thread_sleep_tenth_sec(5); 1805 1806 resumeAndWaitThread(&aThread); 1807 1808 printf(" value = %d\n", nValue); 1809 printf("later value = %d\n", nLaterValue); 1810 1811 //On windows, suspend works, so the values are same 1812 #ifdef WNT 1813 ASSERT_TRUE(nLaterValue == nValue) << "Schedule: don't schedule in thread run method, suspend works."; 1814 #endif 1815 1816 //On UNX, suspend does not work, so the difference of the values equals to sleep seconds number 1817 #ifdef UNX 1818 aThread.resume(); 1819 ASSERT_TRUE(nLaterValue > nValue) << "Schedule: don't schedule in thread run method, suspend does not work too."; 1820 #endif 1821 1822 // terminate will not work if no schedule in thread's work function 1823 termAndJoinThread(&aThread); 1824 sal_Int32 nValue_term = aThread.getValue(); 1825 1826 printf(" value term = %d\n", nValue_term); 1827 1828 ASSERT_TRUE(nValue_term == 10) << "Schedule: don't schedule in thread run method, terminate failed."; 1829 } 1830 1831 } // namespace osl_Thread 1832 1833 1834 // ----------------------------------------------------------------------------- 1835 // destroy function when the binding thread terminate 1836 void SAL_CALL destroyCallback(void * data) 1837 { 1838 printf("destroying local data %s\n", (char *) data); 1839 delete[] (char *) data; 1840 } 1841 1842 static ThreadData myThreadData(destroyCallback); 1843 1844 /** 1845 */ 1846 class myKeyThread : public Thread 1847 { 1848 public: 1849 // a public char member for test result checking 1850 char m_Char_Test; 1851 // for pass thread-special data to thread 1852 myKeyThread(const char cData) 1853 { 1854 m_nData = cData; 1855 } 1856 private: 1857 char m_nData; 1858 1859 void SAL_CALL run() 1860 { 1861 char * pc = new char[2]; 1862 // strcpy(pc, &m_nData); 1863 memcpy(pc, &m_nData, 1); 1864 pc[1] = '\0'; 1865 1866 myThreadData.setData(pc); 1867 char* pData = (char*)myThreadData.getData(); 1868 m_Char_Test = *pData; 1869 // wait for long time to check the data value in main thread 1870 ThreadHelper::thread_sleep_tenth_sec(3); 1871 } 1872 public: 1873 ~myKeyThread() 1874 { 1875 if (isRunning()) 1876 { 1877 printf("error: not terminated.\n"); 1878 } 1879 } 1880 }; 1881 1882 static ThreadData idData; 1883 1884 class idThread: public Thread 1885 { 1886 public: 1887 oslThreadIdentifier m_Id; 1888 private: 1889 void SAL_CALL run() 1890 { 1891 oslThreadIdentifier* pId = new oslThreadIdentifier; 1892 *pId = getIdentifier(); 1893 idData.setData(pId); 1894 oslThreadIdentifier* pIdData = (oslThreadIdentifier*)idData.getData(); 1895 //printf("Thread %d has Data %d\n", getIdentifier(), *pIdData); 1896 m_Id = *pIdData; 1897 delete pId; 1898 } 1899 1900 public: 1901 ~idThread() 1902 { 1903 if (isRunning()) 1904 { 1905 printf("error: not terminated.\n"); 1906 } 1907 } 1908 }; 1909 1910 namespace osl_ThreadData 1911 { 1912 1913 class ctors : public ::testing::Test 1914 { 1915 public: 1916 // initialise your test code values here. 1917 void SetUp() 1918 { 1919 } 1920 1921 void TearDown() 1922 { 1923 } 1924 }; // class ctors 1925 1926 1927 // insert your test code here. 1928 TEST_F(ctors, ctor_001) 1929 { 1930 1931 } 1932 1933 class setData : public ::testing::Test 1934 { 1935 public: 1936 // initialise your test code values here. 1937 void SetUp() 1938 { 1939 } 1940 1941 void TearDown() 1942 { 1943 } 1944 }; // class setData 1945 1946 /** the same instance of the class can have different values in different threads 1947 */ 1948 TEST_F(setData, setData_001) 1949 { 1950 idThread aThread1; 1951 aThread1.create(); 1952 idThread aThread2; 1953 aThread2.create(); 1954 1955 aThread1.join(); 1956 aThread2.join(); 1957 1958 oslThreadIdentifier aThreadId1 = aThread1.getIdentifier(); 1959 oslThreadIdentifier aThreadId2 = aThread2.getIdentifier(); 1960 1961 ASSERT_TRUE(aThread1.m_Id == aThreadId1 && aThread2.m_Id == aThreadId2) << "ThreadData setData: "; 1962 1963 } 1964 1965 TEST_F(setData, setData_002) 1966 { 1967 // at first, set the data a value 1968 char* pc = new char[2]; 1969 char m_nData = 'm'; 1970 // LLA: this is a copy functions only and really only for \0 terminated strings 1971 // m_nData is not a string, it's a character 1972 // strcpy(pc, &m_nData); 1973 memcpy(pc, &m_nData, 1); 1974 pc[1] = '\0'; 1975 1976 myThreadData.setData(pc); 1977 1978 myKeyThread aThread1('a'); 1979 aThread1.create(); 1980 myKeyThread aThread2('b'); 1981 aThread2.create(); 1982 // aThread1 and aThread2 should have not terminated yet, check current data, not 'a' 'b' 1983 char* pChar = (char*)myThreadData.getData(); 1984 char aChar = *pChar; 1985 1986 aThread1.join(); 1987 aThread2.join(); 1988 1989 // the saved thread data of aThread1 & aThread2, different 1990 char cData1 = aThread1.m_Char_Test; 1991 char cData2 = aThread2.m_Char_Test; 1992 1993 ASSERT_TRUE(cData1 == 'a' && cData2 == 'b' && aChar == 'm') << "ThreadData setData: "; 1994 1995 } 1996 /** setData the second time, and then getData 1997 */ 1998 TEST_F(setData, setData_003) 1999 { 2000 // at first, set the data a value 2001 char* pc = new char[2]; 2002 char m_nData = 'm'; 2003 // strcpy(pc, &m_nData); 2004 memcpy(pc, &m_nData, 1); 2005 pc[1] = '\0'; 2006 myThreadData.setData(pc); 2007 2008 myKeyThread aThread1('a'); 2009 aThread1.create(); 2010 myKeyThread aThread2('b'); 2011 aThread2.create(); 2012 // aThread1 and aThread2 should have not terminated yet 2013 // setData the second time 2014 char* pc2 = new char[2]; 2015 m_nData = 'o'; 2016 // strcpy(pc2, &m_nData); 2017 memcpy(pc2, &m_nData, 1); 2018 pc2[1] = '\0'; 2019 2020 myThreadData.setData(pc2); 2021 char* pChar = (char*)myThreadData.getData(); 2022 char aChar = *pChar; 2023 2024 aThread1.join(); 2025 aThread2.join(); 2026 2027 // the saved thread data of aThread1 & aThread2, different 2028 char cData1 = aThread1.m_Char_Test; 2029 char cData2 = aThread2.m_Char_Test; 2030 2031 ASSERT_TRUE(cData1 == 'a' && cData2 == 'b' && aChar == 'o') << "ThreadData setData: "; 2032 2033 } 2034 2035 //sal_Bool buildTwoThreads(char) 2036 2037 class getData : public ::testing::Test 2038 { 2039 public: 2040 // initialise your test code values here. 2041 void SetUp() 2042 { 2043 } 2044 2045 void TearDown() 2046 { 2047 } 2048 }; // class getData 2049 2050 // After setData in child threads, get Data in the main thread, should be independent 2051 TEST_F(getData, getData_001) 2052 { 2053 char* pc = new char[2]; 2054 char m_nData[] = "i"; 2055 strcpy(pc, m_nData); 2056 printf("pc %s\n", pc); 2057 myThreadData.setData(pc); 2058 2059 myKeyThread aThread1('c'); 2060 aThread1.create(); 2061 myKeyThread aThread2('d'); 2062 aThread2.create(); 2063 2064 aThread1.join(); 2065 aThread2.join(); 2066 2067 char cData1 = aThread1.m_Char_Test; 2068 char cData2 = aThread2.m_Char_Test; 2069 2070 char* pChar = (char*)myThreadData.getData(); 2071 char aChar = *pChar; 2072 2073 ASSERT_TRUE(cData1 == 'c' && cData2 == 'd' && aChar == 'i') << "ThreadData setData: "; 2074 2075 } 2076 2077 // setData then change the value in the address data pointer points, 2078 // and then getData, should get the new value 2079 TEST_F(getData, getData_002) 2080 { 2081 char* pc = new char[2]; 2082 char m_nData = 'i'; 2083 // strcpy(pc, &m_nData); 2084 memcpy(pc, &m_nData, 1); 2085 pc[1] = '\0'; 2086 // strncpy(pc, &m_nData, sizeof(char); 2087 2088 printf("pc %s\n", pc); 2089 myThreadData.setData(pc); 2090 2091 myKeyThread aThread1('a'); 2092 aThread1.create(); 2093 myKeyThread aThread2('b'); 2094 aThread2.create(); 2095 2096 // change the value which pc points 2097 char m_nData2 = 'j'; 2098 // strcpy(pc, &m_nData2); 2099 memcpy(pc, &m_nData2, 1); 2100 pc[1] = '\0'; 2101 2102 //printf("pc %s\n", pc); 2103 void* pChar = myThreadData.getData(); 2104 char aChar = *(char*)pChar; 2105 2106 aThread1.join(); 2107 aThread2.join(); 2108 2109 char cData1 = aThread1.m_Char_Test; 2110 char cData2 = aThread2.m_Char_Test; 2111 2112 ASSERT_TRUE(cData1 == 'a' && cData2 == 'b' && aChar == 'j') << "ThreadData setData: "; 2113 2114 } 2115 2116 2117 } // namespace osl_ThreadData 2118 2119 int main(int argc, char **argv) 2120 { 2121 ::testing::InitGoogleTest(&argc, argv); 2122 return RUN_ALL_TESTS(); 2123 } 2124