ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/threads.cpp
(Generate patch)
# Line 1 | Line 1
1 < #include <iostream>
2 < #include <list>
3 < #include "GThreads.h"
4 <
5 < using namespace std;
6 < //using namespace tthread;
7 <
8 < // Thread local storage variable (not available on Mac OSX ?!)
9 < #ifndef GTHREADS_NO_TLS
10 < thread_local int gLocalVar;
11 < #endif
12 <
13 < // Mutex + global count variable
14 < GMutex gMutex;
15 < GFastMutex gFastMutex;
16 < int gCount;
17 <
18 < // Condition variable
19 < GConditionVar gCond;
20 <
21 < // Thread function: Thread ID
22 < void ThreadIDs(void * aArg, GThread* thisThread)
23 < {
24 <    {
25 <            GLockGuard<GMutex> lock(gMutex);
26 <            cout << " My thread id is " << thisThread->get_id() << "." << endl << flush;
27 <    }
28 <  this_thread::sleep_for(chrono::seconds(4));
29 < }
30 <
31 < #ifndef GTHREADS_NO_TLS
32 < // Thread function: Thread-local storage
33 < void ThreadTLS(void * aArg, GThread*)
34 < {
35 <  gLocalVar = 2;
36 <  cout << " My gLocalVar is " << gLocalVar << "." << endl;
37 < }
38 < #endif
39 <
40 < // Thread function: Mutex locking
41 < void ThreadLock(void * aArg, GThread*)
42 < {
43 <  for(int i = 0; i < 10000; ++ i)
44 <  {
45 <    GLockGuard<GMutex> lock(gMutex);
46 <    ++ gCount;
47 <  }
48 < }
49 <
50 < // Thread function: Mutex locking
51 < void ThreadLock2(void * aArg, GThread*)
52 < {
53 <  for(int i = 0; i < 10000; ++ i)
54 <  {
55 <    GLockGuard<GFastMutex> lock(gFastMutex);
56 <    ++ gCount;
57 <  }
58 < }
59 <
60 < // Thread function: Condition notifier
61 < void ThreadCondition1(void * aArg, GThread*)
62 < {
63 <  GLockGuard<GMutex> lock(gMutex);
64 <  -- gCount;
65 <  gCond.notify_all();
66 < }
67 <
68 < // Thread function: Condition waiter
69 < void ThreadCondition2(void * aArg, GThread*)
70 < {
71 <  cout << " Wating..." << flush;
72 <  GLockGuard<GMutex> lock(gMutex);
73 <  while(gCount > 0)
74 <  {
75 <    cout << "." << flush;
76 <    gCond.wait(gMutex);
77 <  }
78 <  cout << "." << endl;
79 < }
80 <
81 < // Thread function: Yield
82 < void ThreadYield(void * aArg, GThread*)
83 < {
84 <  // Yield...
85 <  this_thread::yield();
86 < }
87 <
88 <
89 < // This is the main program (i.e. the main thread)
90 < int main()
91 < {
92 <  // Test 1: Show number of CPU cores in the system
93 <  cout << "PART I: Info" << endl;
94 <  cout << " Number of processor cores: " << GThread::hardware_concurrency() << endl;
95 <
96 <  // Test 2: thread IDs
97 <  cout << endl << "PART II: Thread IDs" << endl;
98 <  {
99 <    // Show the main thread ID
100 <    //cout << " Main thread id is " << this_thread::get_id() << "." << endl;
101 <
102 <    // Start a bunch of child threads - only run a single thread at a time
103 <    GThread t1(ThreadIDs, 0);
104 <    this_thread::sleep_for(chrono::milliseconds(400));
105 <    GThread t2(ThreadIDs, 0);
106 <    this_thread::sleep_for(chrono::milliseconds(400));
107 <    GThread t3(ThreadIDs, 0);
108 <    this_thread::sleep_for(chrono::milliseconds(400));
109 <    GThread t4(ThreadIDs, 0);
110 <    //t1.join();
111 <    //t2.join();
112 <    //t3.join();
113 <    //t4.join();
114 <    this_thread::sleep_for(chrono::milliseconds(200));
115 <        cout << "Waiting for all threads to finish.." << flush;
116 <    int num_threads;
117 <    while ((num_threads=GThread::num_running())>0) {
118 <      cout << "." << num_threads << "." << flush;
119 <      this_thread::sleep_for(chrono::milliseconds(300));
120 <      }
121 <    cout << ".. Done. " << endl;
122 <  }
123 <
124 <  // Test 3: thread local storage
125 <  cout << endl << "PART III: Thread local storage" << endl;
126 < #ifndef GTHREADS_NO_TLS
127 <  {
128 <    // Clear the TLS variable (it should keep this value after all threads are
129 <    // finished).
130 <    gLocalVar = 1;
131 <    cout << " Main gLocalVar is " << gLocalVar << "." << endl;
132 <
133 <    // Start a child thread that modifies gLocalVar
134 <    GThread t1(ThreadTLS, 0);
135 <    t1.join();
136 <
137 <    // Check if the TLS variable has changed
138 <    if(gLocalVar == 1)
139 <      cout << " Main gLocalVar was not changed by the child thread - OK!" << endl;
140 <    else
141 <      cout << " Main gLocalVar was changed by the child thread - FAIL!" << endl;
142 <  }
143 < #else
144 <  cout << " TLS is not supported on this platform..." << endl;
145 < #endif
146 <
147 <  // Test 4: mutex locking
148 <  cout << endl << "PART IV: Mutex locking (100 threads x 10000 iterations)" << endl;
149 <  {
150 <    // Clear the global counter.
151 <    gCount = 0;
152 <
153 <    // Start a bunch of child threads
154 <    list<GThread *> threadList;
155 <    for(int i = 0; i < 100; ++ i)
156 <      threadList.push_back(new GThread(ThreadLock, 0));
157 <
158 <    // Wait for the threads to finish
159 <    list<GThread *>::iterator it;
160 <    for(it = threadList.begin(); it != threadList.end(); ++ it)
161 <    {
162 <      GThread * t = *it;
163 <      t->join();
164 <      delete t;
165 <    }
166 <
167 <    // Check the global count
168 <    cout << " gCount = " << gCount << endl;
169 <  }
170 <
171 <  // Test 5: fast_mutex locking
172 <  cout << endl << "PART V: Fast mutex locking (100 threads x 10000 iterations)" << endl;
173 <  {
174 <    // Clear the global counter.
175 <    gCount = 0;
176 <
177 <    // Start a bunch of child threads
178 <    list<GThread *> threadList;
179 <    for(int i = 0; i < 100; ++ i)
180 <      threadList.push_back(new GThread(ThreadLock2, 0));
181 <
182 <    // Wait for the threads to finish
183 <    list<GThread *>::iterator it;
184 <    for(it = threadList.begin(); it != threadList.end(); ++ it)
185 <    {
186 <      GThread * t = *it;
187 <      t->join();
188 <      delete t;
189 <    }
190 <
191 <    // Check the global count
192 <    cout << " gCount = " << gCount << endl;
193 <  }
194 <
195 <  // Test 6: condition variable
196 <  cout << endl << "PART VI: Condition variable (40 + 1 threads)" << endl;
197 <  {
198 <    // Set the global counter to the number of threads to run.
199 <    gCount = 40;
200 <
201 <    // Start the waiting thread (it will wait for gCount to reach zero).
202 <    GThread t1(ThreadCondition2, 0);
203 <
204 <    // Start a bunch of child threads (these will decrease gCount by 1 when they
205 <    // finish)
206 <    list<GThread *> threadList;
207 <    for(int i = 0; i < 40; ++ i)
208 <      threadList.push_back(new GThread(ThreadCondition1, 0));
209 <
210 <    // Wait for the waiting thread to finish
211 <    t1.join();
212 <
213 <    // Wait for the other threads to finish
214 <    list<GThread *>::iterator it;
215 <    for(it = threadList.begin(); it != threadList.end(); ++ it)
216 <    {
217 <      GThread * t = *it;
218 <      t->join();
219 <      delete t;
220 <    }
221 <  }
222 <
223 <  // Test 7: yield
224 <  cout << endl << "PART VII: Yield (40 + 1 threads)" << endl;
225 <  {
226 <    // Start a bunch of child threads
227 <    list<GThread *> threadList;
228 <    for(int i = 0; i < 40; ++ i)
229 <      threadList.push_back(new GThread(ThreadYield, 0));
230 <
231 <    // Yield...
232 <    this_thread::yield();
233 <
234 <    // Wait for the threads to finish
235 <    list<GThread *>::iterator it;
236 <    for(it = threadList.begin(); it != threadList.end(); ++ it)
237 <    {
238 <      GThread * t = *it;
239 <      t->join();
240 <      delete t;
241 <    }
242 <  }
243 <
244 <  // Test 8: sleep
245 <  cout << endl << "PART VIII: Sleep (10 x 100 ms)" << endl;
246 <  {
247 <    // Sleep...
248 <    cout << " Sleeping" << flush;
249 <    for(int i = 0; i < 10; ++ i)
250 <    {
251 <      this_thread::sleep_for(chrono::milliseconds(100));
252 <      cout << "." << flush;
253 <    }
254 <    cout << endl;
255 <  }
256 < }
1 > #include <iostream>
2 > #include <list>
3 > #include "GThreads.h"
4 >
5 > using namespace std;
6 > //using namespace tthread;
7 >
8 > // Thread local storage variable (not available on Mac OSX ?!)
9 > #ifndef GTHREADS_NO_TLS
10 > thread_local int gLocalVar;
11 > #endif
12 >
13 > // Mutex + global count variable
14 > GMutex gMutex;
15 > GFastMutex gFastMutex;
16 > int gCount;
17 >
18 > // Condition variable
19 > GConditionVar gCond;
20 >
21 > // Thread function: Thread ID
22 > void ThreadIDs(void * aArg, GThread* thisThread)
23 > {
24 >    {
25 >            GLockGuard<GMutex> lock(gMutex);
26 >            cout << " My thread id is " << thisThread->get_id() << "." << endl << flush;
27 >    }
28 >  this_thread::sleep_for(chrono::seconds(4));
29 > }
30 >
31 > #ifndef GTHREADS_NO_TLS
32 > // Thread function: Thread-local storage
33 > void ThreadTLS(void * aArg, GThread*)
34 > {
35 >  gLocalVar = 2;
36 >  cout << " My gLocalVar is " << gLocalVar << "." << endl;
37 > }
38 > #endif
39 >
40 > // Thread function: Mutex locking
41 > void ThreadLock(void * aArg, GThread*)
42 > {
43 >  for(int i = 0; i < 10000; ++ i)
44 >  {
45 >    GLockGuard<GMutex> lock(gMutex);
46 >    ++ gCount;
47 >  }
48 > }
49 >
50 > // Thread function: Mutex locking
51 > void ThreadLock2(void * aArg, GThread*)
52 > {
53 >  for(int i = 0; i < 10000; ++ i)
54 >  {
55 >    GLockGuard<GFastMutex> lock(gFastMutex);
56 >    ++ gCount;
57 >  }
58 > }
59 >
60 > // Thread function: Condition notifier
61 > void ThreadCondition1(void * aArg, GThread*)
62 > {
63 >  GLockGuard<GMutex> lock(gMutex);
64 >  -- gCount;
65 >  gCond.notify_all();
66 > }
67 >
68 > // Thread function: Condition waiter
69 > void ThreadCondition2(void * aArg, GThread*)
70 > {
71 >  cout << " Wating..." << flush;
72 >  GLockGuard<GMutex> lock(gMutex);
73 >  while(gCount > 0)
74 >  {
75 >    cout << "." << flush;
76 >    gCond.wait(gMutex);
77 >  }
78 >  cout << "." << endl;
79 > }
80 >
81 > // Thread function: Yield
82 > void ThreadYield(void * aArg, GThread*)
83 > {
84 >  // Yield...
85 >  this_thread::yield();
86 > }
87 >
88 >
89 > // This is the main program (i.e. the main thread)
90 > int main()
91 > {
92 >  // Test 1: Show number of CPU cores in the system
93 >  cout << "PART I: Info" << endl;
94 >  cout << " Number of processor cores: " << GThread::hardware_concurrency() << endl;
95 >
96 >  // Test 2: thread IDs
97 >  cout << endl << "PART II: Thread IDs" << endl;
98 >  {
99 >    // Show the main thread ID
100 >    //cout << " Main thread id is " << this_thread::get_id() << "." << endl;
101 >
102 >    // Start a bunch of child threads - only run a single thread at a time
103 >    GThread t1(ThreadIDs, 0);
104 >    this_thread::sleep_for(chrono::milliseconds(400));
105 >    GThread t2(ThreadIDs, 0);
106 >    this_thread::sleep_for(chrono::milliseconds(400));
107 >    GThread t3(ThreadIDs, 0);
108 >    this_thread::sleep_for(chrono::milliseconds(400));
109 >    GThread t4(ThreadIDs, 0);
110 >    //t1.join();
111 >    //t2.join();
112 >    //t3.join();
113 >    //t4.join();
114 >    this_thread::sleep_for(chrono::milliseconds(200));
115 >        cout << "Waiting for all threads to finish.." << flush;
116 >    int num_threads;
117 >    while ((num_threads=GThread::num_running())>0) {
118 >      cout << "." << num_threads << "." << flush;
119 >      this_thread::sleep_for(chrono::milliseconds(300));
120 >      }
121 >    cout << ".. Done. " << endl;
122 >  }
123 >
124 >  // Test 3: thread local storage
125 >  cout << endl << "PART III: Thread local storage" << endl;
126 > #ifndef GTHREADS_NO_TLS
127 >  {
128 >    // Clear the TLS variable (it should keep this value after all threads are
129 >    // finished).
130 >    gLocalVar = 1;
131 >    cout << " Main gLocalVar is " << gLocalVar << "." << endl;
132 >
133 >    // Start a child thread that modifies gLocalVar
134 >    GThread t1(ThreadTLS, 0);
135 >    t1.join();
136 >
137 >    // Check if the TLS variable has changed
138 >    if(gLocalVar == 1)
139 >      cout << " Main gLocalVar was not changed by the child thread - OK!" << endl;
140 >    else
141 >      cout << " Main gLocalVar was changed by the child thread - FAIL!" << endl;
142 >  }
143 > #else
144 >  cout << " TLS is not supported on this platform..." << endl;
145 > #endif
146 >
147 >  // Test 4: mutex locking
148 >  cout << endl << "PART IV: Mutex locking (100 threads x 10000 iterations)" << endl;
149 >  {
150 >    // Clear the global counter.
151 >    gCount = 0;
152 >
153 >    // Start a bunch of child threads
154 >    list<GThread *> threadList;
155 >    for(int i = 0; i < 100; ++ i)
156 >      threadList.push_back(new GThread(ThreadLock, 0));
157 >
158 >    // Wait for the threads to finish
159 >    list<GThread *>::iterator it;
160 >    for(it = threadList.begin(); it != threadList.end(); ++ it)
161 >    {
162 >      GThread * t = *it;
163 >      t->join();
164 >      delete t;
165 >    }
166 >
167 >    // Check the global count
168 >    cout << " gCount = " << gCount << endl;
169 >  }
170 >
171 >  // Test 5: fast_mutex locking
172 >  cout << endl << "PART V: Fast mutex locking (100 threads x 10000 iterations)" << endl;
173 >  {
174 >    // Clear the global counter.
175 >    gCount = 0;
176 >
177 >    // Start a bunch of child threads
178 >    list<GThread *> threadList;
179 >    for(int i = 0; i < 100; ++ i)
180 >      threadList.push_back(new GThread(ThreadLock2, 0));
181 >
182 >    // Wait for the threads to finish
183 >    list<GThread *>::iterator it;
184 >    for(it = threadList.begin(); it != threadList.end(); ++ it)
185 >    {
186 >      GThread * t = *it;
187 >      t->join();
188 >      delete t;
189 >    }
190 >
191 >    // Check the global count
192 >    cout << " gCount = " << gCount << endl;
193 >  }
194 >
195 >  // Test 6: condition variable
196 >  cout << endl << "PART VI: Condition variable (40 + 1 threads)" << endl;
197 >  {
198 >    // Set the global counter to the number of threads to run.
199 >    gCount = 40;
200 >
201 >    // Start the waiting thread (it will wait for gCount to reach zero).
202 >    GThread t1(ThreadCondition2, 0);
203 >
204 >    // Start a bunch of child threads (these will decrease gCount by 1 when they
205 >    // finish)
206 >    list<GThread *> threadList;
207 >    for(int i = 0; i < 40; ++ i)
208 >      threadList.push_back(new GThread(ThreadCondition1, 0));
209 >
210 >    // Wait for the waiting thread to finish
211 >    t1.join();
212 >
213 >    // Wait for the other threads to finish
214 >    list<GThread *>::iterator it;
215 >    for(it = threadList.begin(); it != threadList.end(); ++ it)
216 >    {
217 >      GThread * t = *it;
218 >      t->join();
219 >      delete t;
220 >    }
221 >  }
222 >
223 >  // Test 7: yield
224 >  cout << endl << "PART VII: Yield (40 + 1 threads)" << endl;
225 >  {
226 >    // Start a bunch of child threads
227 >    list<GThread *> threadList;
228 >    for(int i = 0; i < 40; ++ i)
229 >      threadList.push_back(new GThread(ThreadYield, 0));
230 >
231 >    // Yield...
232 >    this_thread::yield();
233 >
234 >    // Wait for the threads to finish
235 >    list<GThread *>::iterator it;
236 >    for(it = threadList.begin(); it != threadList.end(); ++ it)
237 >    {
238 >      GThread * t = *it;
239 >      t->join();
240 >      delete t;
241 >    }
242 >  }
243 >
244 >  // Test 8: sleep
245 >  cout << endl << "PART VIII: Sleep (10 x 100 ms)" << endl;
246 >  {
247 >    // Sleep...
248 >    cout << " Sleeping" << flush;
249 >    for(int i = 0; i < 10; ++ i)
250 >    {
251 >      this_thread::sleep_for(chrono::milliseconds(100));
252 >      cout << "." << flush;
253 >    }
254 >    cout << endl;
255 >  }
256 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines