ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/threads.cpp
Revision: 310
Committed: Fri Mar 22 20:06:27 2013 UTC (6 years, 6 months ago) by gpertea
File size: 7043 byte(s)
Log Message:
sync with igm repo

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