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 |