| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" // NOLINT | 5 #include "platform/globals.h" // NOLINT |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
| 9 #include "vm/os_thread.h" | 9 #include "vm/os_thread.h" |
| 10 | 10 |
| 11 #include <process.h> // NOLINT | 11 #include <process.h> // NOLINT |
| 12 | 12 |
| 13 #include "platform/assert.h" | 13 #include "platform/assert.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 // This flag is flipped by platform_win.cc when the process is exiting. | 17 // This flag is flipped by platform_win.cc when the process is exiting. |
| 18 // TODO(zra): Remove once VM shuts down cleanly. | 18 // TODO(zra): Remove once VM shuts down cleanly. |
| 19 bool private_flag_windows_run_tls_destructors = true; | 19 bool private_flag_windows_run_tls_destructors = true; |
| 20 | 20 |
| 21 class ThreadStartData { | 21 class ThreadStartData { |
| 22 public: | 22 public: |
| 23 ThreadStartData(OSThread::ThreadStartFunction function, uword parameter) | 23 ThreadStartData(const char* name, |
| 24 : function_(function), parameter_(parameter) {} | 24 OSThread::ThreadStartFunction function, |
| 25 uword parameter) |
| 26 : name_(name), function_(function), parameter_(parameter) {} |
| 25 | 27 |
| 28 const char* name() const { return name_; } |
| 26 OSThread::ThreadStartFunction function() const { return function_; } | 29 OSThread::ThreadStartFunction function() const { return function_; } |
| 27 uword parameter() const { return parameter_; } | 30 uword parameter() const { return parameter_; } |
| 28 | 31 |
| 29 private: | 32 private: |
| 33 const char* name_; |
| 30 OSThread::ThreadStartFunction function_; | 34 OSThread::ThreadStartFunction function_; |
| 31 uword parameter_; | 35 uword parameter_; |
| 32 | 36 |
| 33 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); | 37 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); |
| 34 }; | 38 }; |
| 35 | 39 |
| 36 | 40 |
| 37 // Dispatch to the thread start function provided by the caller. This trampoline | 41 // Dispatch to the thread start function provided by the caller. This trampoline |
| 38 // is used to ensure that the thread is properly destroyed if the thread just | 42 // is used to ensure that the thread is properly destroyed if the thread just |
| 39 // exits. | 43 // exits. |
| 40 static unsigned int __stdcall ThreadEntry(void* data_ptr) { | 44 static unsigned int __stdcall ThreadEntry(void* data_ptr) { |
| 41 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); | 45 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); |
| 42 | 46 |
| 47 const char* name = data->name(); |
| 43 OSThread::ThreadStartFunction function = data->function(); | 48 OSThread::ThreadStartFunction function = data->function(); |
| 44 uword parameter = data->parameter(); | 49 uword parameter = data->parameter(); |
| 45 delete data; | 50 delete data; |
| 46 | 51 |
| 47 MonitorData::GetMonitorWaitDataForThread(); | 52 MonitorData::GetMonitorWaitDataForThread(); |
| 48 | 53 |
| 54 // Create new OSThread object and set as TLS for new thread. |
| 55 OSThread* thread = new OSThread(); |
| 56 OSThread::SetCurrent(thread); |
| 57 thread->set_name(name); |
| 58 |
| 49 // Call the supplied thread start function handing it its parameters. | 59 // Call the supplied thread start function handing it its parameters. |
| 50 function(parameter); | 60 function(parameter); |
| 51 | 61 |
| 52 // Clean up the monitor wait data for this thread. | 62 // Clean up the monitor wait data for this thread. |
| 53 MonitorWaitData::ThreadExit(); | 63 MonitorWaitData::ThreadExit(); |
| 54 | 64 |
| 55 return 0; | 65 return 0; |
| 56 } | 66 } |
| 57 | 67 |
| 58 | 68 |
| 59 int OSThread::Start(ThreadStartFunction function, uword parameter) { | 69 int OSThread::Start(const char* name, |
| 60 ThreadStartData* start_data = new ThreadStartData(function, parameter); | 70 ThreadStartFunction function, |
| 71 uword parameter) { |
| 72 ThreadStartData* start_data = new ThreadStartData(name, function, parameter); |
| 61 uint32_t tid; | 73 uint32_t tid; |
| 62 uintptr_t thread = _beginthreadex(NULL, OSThread::GetMaxStackSize(), | 74 uintptr_t thread = _beginthreadex(NULL, OSThread::GetMaxStackSize(), |
| 63 ThreadEntry, start_data, 0, &tid); | 75 ThreadEntry, start_data, 0, &tid); |
| 64 if (thread == -1L || thread == 0) { | 76 if (thread == -1L || thread == 0) { |
| 65 #ifdef DEBUG | 77 #ifdef DEBUG |
| 66 fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno)); | 78 fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno)); |
| 67 #endif | 79 #endif |
| 68 return errno; | 80 return errno; |
| 69 } | 81 } |
| 70 | 82 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 return ::GetCurrentThreadId(); | 120 return ::GetCurrentThreadId(); |
| 109 } | 121 } |
| 110 | 122 |
| 111 | 123 |
| 112 ThreadId OSThread::GetCurrentThreadTraceId() { | 124 ThreadId OSThread::GetCurrentThreadTraceId() { |
| 113 return ::GetCurrentThreadId(); | 125 return ::GetCurrentThreadId(); |
| 114 } | 126 } |
| 115 | 127 |
| 116 | 128 |
| 117 ThreadJoinId OSThread::GetCurrentThreadJoinId() { | 129 ThreadJoinId OSThread::GetCurrentThreadJoinId() { |
| 130 // TODO(zra): Use the thread handle as the join id in order to have a more |
| 131 // reliable join on windows. |
| 118 return ::GetCurrentThreadId(); | 132 return ::GetCurrentThreadId(); |
| 119 } | 133 } |
| 120 | 134 |
| 121 | 135 |
| 122 void OSThread::Join(ThreadJoinId id) { | 136 void OSThread::Join(ThreadJoinId id) { |
| 123 HANDLE handle = OpenThread(SYNCHRONIZE, false, id); | 137 HANDLE handle = OpenThread(SYNCHRONIZE, false, id); |
| 124 | 138 |
| 125 // TODO(zra): OSThread::Start() closes the handle to the thread. Thus, by the | 139 // TODO(zra): OSThread::Start() closes the handle to the thread. Thus, by the |
| 126 // time we try to join the thread, its resources may have already been | 140 // time we try to join the thread, its resources may have already been |
| 127 // reclaimed, and joining will fail. This can be avoided in a couple of ways. | 141 // reclaimed, and joining will fail. This can be avoided in a couple of ways. |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 #pragma data_seg(".CRT$XLB") | 698 #pragma data_seg(".CRT$XLB") |
| 685 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; | 699 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; |
| 686 | 700 |
| 687 // Reset the default section. | 701 // Reset the default section. |
| 688 #pragma data_seg() | 702 #pragma data_seg() |
| 689 | 703 |
| 690 #endif // _WIN64 | 704 #endif // _WIN64 |
| 691 } // extern "C" | 705 } // extern "C" |
| 692 | 706 |
| 693 #endif // defined(TARGET_OS_WINDOWS) | 707 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |