test.cpp
上传用户:sunlush021
上传日期:2022-06-22
资源大小:90k
文件大小:6k
源码类别:

操作系统开发

开发平台:

C/C++

  1. /*
  2. Copyright (c) 2010 Marcus Geelnard
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely, subject to the following restrictions:
  9.     1. The origin of this software must not be misrepresented; you must not
  10.     claim that you wrote the original software. If you use this software
  11.     in a product, an acknowledgment in the product documentation would be
  12.     appreciated but is not required.
  13.     2. Altered source versions must be plainly marked as such, and must not be
  14.     misrepresented as being the original software.
  15.     3. This notice may not be removed or altered from any source
  16.     distribution.
  17. */
  18. #include <iostream>
  19. #include <list>
  20. #include <tinythread.h>
  21. #include <fast_mutex.h>
  22. using namespace std;
  23. using namespace tthread;
  24. // HACK: Mac OS X and early MinGW do not support thread-local storage #if defined(__APPLE__) || (defined(__MINGW32__) && (__GNUC__ < 4))
  25.  #define NO_TLS #endif
  26. // Thread local storage variable #ifndef NO_TLS thread_local int gLocalVar;
  27. #endif
  28. // Mutex + global count variable
  29. mutex gMutex;
  30. fast_mutex gFastMutex;
  31. int gCount;
  32. // Condition variable
  33. condition_variable gCond;
  34. // Thread function: Thread ID
  35. void ThreadIDs(void * aArg)
  36. {
  37.   cout << " My thread id is " << this_thread::get_id() << "." << endl;
  38. }
  39. #ifndef NO_TLS // Thread function: Thread-local storage
  40. void ThreadTLS(void * aArg)
  41. {
  42.   gLocalVar = 2;
  43.   cout << " My gLocalVar is " << gLocalVar << "." << endl;
  44. }
  45. #endif
  46. // Thread function: Mutex locking
  47. void ThreadLock(void * aArg)
  48. {
  49.   for(int i = 0; i < 10000; ++ i)
  50.   {
  51.     lock_guard<mutex> lock(gMutex);
  52.     ++ gCount;
  53.   }
  54. }
  55. // Thread function: Mutex locking
  56. void ThreadLock2(void * aArg)
  57. {
  58.   for(int i = 0; i < 10000; ++ i)
  59.   {
  60.     lock_guard<fast_mutex> lock(gFastMutex);
  61.     ++ gCount;
  62.   }
  63. }
  64. // Thread function: Condition notifier
  65. void ThreadCondition1(void * aArg)
  66. {
  67.   lock_guard<mutex> lock(gMutex);
  68.   -- gCount;
  69.   gCond.notify_all();
  70. }
  71. // Thread function: Condition waiter
  72. void ThreadCondition2(void * aArg)
  73. {
  74.   cout << " Wating..." << flush;
  75.   lock_guard<mutex> lock(gMutex);
  76.   while(gCount > 0)
  77.   {
  78.     cout << "." << flush;
  79.     gCond.wait(gMutex);
  80.   }
  81.   cout << "." << endl;
  82. }
  83. // This is the main program (i.e. the main thread)
  84. int main()
  85. {
  86.   // Test 1: Show number of CPU cores in the system
  87.   cout << "PART I: Info" << endl;
  88.   cout << " Number of processor cores: " << number_of_processors() << endl;
  89.   // Test 2: thread IDs
  90.   cout << endl << "PART II: Thread IDs" << endl;
  91.   {
  92.     // Show the main thread ID
  93.     cout << " Main thread id is " << this_thread::get_id() << "." << endl;
  94.     // Start a bunch of child threads - only run a single thread at a time
  95.     thread t1(ThreadIDs, 0);
  96.     t1.join();
  97.     thread t2(ThreadIDs, 0);
  98.     t2.join();
  99.     thread t3(ThreadIDs, 0);
  100.     t3.join();
  101.     thread t4(ThreadIDs, 0);
  102.     t4.join();
  103.   }
  104.   // Test 3: thread local storage
  105.   cout << endl << "PART III: Thread local storage" << endl;
  106. #ifndef NO_TLS   {
  107.     // Clear the TLS variable (it should keep this value after all threads are
  108.     // finished).
  109.     gLocalVar = 1;
  110.     cout << " Main gLocalVar is " << gLocalVar << "." << endl;
  111.     // Start a child thread that modifies gLocalVar
  112.     thread t1(ThreadTLS, 0);
  113.     t1.join();
  114.     // Check if the TLS variable has changed
  115.     if(gLocalVar == 1)
  116.       cout << " Main gLocalID was not changed by the child thread - OK!" << endl;
  117.     else
  118.       cout << " Main gLocalID was changed by the child thread - FAIL!" << endl;
  119.   }
  120. #else   cout << " TLS is not supported on this platform..." << endl;
  121. #endif
  122.   // Test 4: mutex locking
  123.   cout << endl << "PART IV: Mutex locking (100 threads x 10000 iterations)" << endl;
  124.   {
  125.     // Clear the global counter.
  126.     gCount = 0;
  127.     // Start a bunch of child threads
  128.     list<thread *> threadList;
  129.     for(int i = 0; i < 100; ++ i)
  130.       threadList.push_back(new thread(ThreadLock, 0));
  131.     // Wait for the threads to finish
  132.     list<thread *>::iterator it;
  133.     for(it = threadList.begin(); it != threadList.end(); ++ it)
  134.     {
  135.       thread * t = *it;
  136.       t->join();
  137.       delete t;
  138.     }
  139.     // Check the global count
  140.     cout << " gCount = " << gCount << endl;
  141.   }
  142.   // Test 5: fast_mutex locking
  143.   cout << endl << "PART V: Fast mutex locking (100 threads x 10000 iterations)" << endl;
  144.   {
  145.     // Clear the global counter.
  146.     gCount = 0;
  147.     // Start a bunch of child threads
  148.     list<thread *> threadList;
  149.     for(int i = 0; i < 100; ++ i)
  150.       threadList.push_back(new thread(ThreadLock2, 0));
  151.     // Wait for the threads to finish
  152.     list<thread *>::iterator it;
  153.     for(it = threadList.begin(); it != threadList.end(); ++ it)
  154.     {
  155.       thread * t = *it;
  156.       t->join();
  157.       delete t;
  158.     }
  159.     // Check the global count
  160.     cout << " gCount = " << gCount << endl;
  161.   }
  162.   // Test 6: condition variable
  163.   cout << endl << "PART VI: Condition variable (40 + 1 threads)" << endl;
  164.   {
  165.     // Set the global counter to the number of threads to run.
  166.     gCount = 40;
  167.     // Start the waiting thread (it will wait for gCount to reach zero).
  168.     thread t1(ThreadCondition2, 0);
  169.     // Start a bunch of child threads (these will decrease gCount by 1 when they
  170.     // finish)
  171.     list<thread *> threadList;
  172.     for(int i = 0; i < 40; ++ i)
  173.       threadList.push_back(new thread(ThreadCondition1, 0));
  174.     // Wait for the waiting thread to finish
  175.     t1.join();
  176.     // Wait for the other threads to finish
  177.     list<thread *>::iterator it;
  178.     for(it = threadList.begin(); it != threadList.end(); ++ it)
  179.     {
  180.       thread * t = *it;
  181.       t->join();
  182.       delete t;
  183.     }
  184.   }
  185. }