| // CRT headers |
| #include <process.h> |
| |
| // Standard C++ headers |
| #include <iostream> |
| |
| #define WIN32_LEAN_AND_MEAN |
| #include <windows.h> |
| |
| int __thread tls_value = 0; |
| |
| unsigned __stdcall thread_fn(void*) |
| { |
| ++tls_value; |
| return 0; |
| } |
| |
| // This is derived from the jig that I setup to explore the problems with |
| // MT exception handling - you could probably just as easily set processors to |
| // some value rather than tying it to the actual # of cores... |
| int main() |
| { |
| // Get the number of processors available to use |
| SYSTEM_INFO si; |
| GetSystemInfo(&si); |
| const unsigned processors = si.dwNumberOfProcessors; |
| |
| // Make a thread for every processor and assign the thread to it |
| HANDLE *threads = new HANDLE[processors]; |
| |
| for (unsigned i = 0; i < processors; i++) { |
| threads[i] = (HANDLE)_beginthreadex(0, 0, thread_fn, 0, CREATE_SUSPENDED, 0); |
| SetThreadAffinityMask(threads[i], 1 << i); |
| } |
| |
| // Restart all the threads |
| for (unsigned i = 0; i < processors; i++) |
| ResumeThread(threads[i]); |
| |
| // Rejoin those threads |
| WaitForMultipleObjects(processors, threads, 1, INFINITE); |
| for (unsigned i = 0; i < processors; i++) |
| CloseHandle(threads[i]); |
| |
| delete[] threads; |
| |
| if (tls_value != 0) { |
| std::cout << "How is it possible that tls_value is " << tls_value << " != 0 ?" << std::endl; |
| std::terminate (); |
| } |
| |
| return 0; |
| } |