src/os/windows/vm/os_windows.cpp
Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
*** 5040,5049 ****
--- 5040,5114 ----
int os::set_sock_opt(int fd, int level, int optname,
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+ // WINDOWS CONTEXT Flags for THREAD_SAMPLING
+ #if defined(IA32)
+ # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
+ #elif defined (AMD64)
+ # define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
+ #endif
+
+ // returns true if thread could be suspended,
+ // false otherwise
+ static bool do_suspend(HANDLE* h) {
+ if (h != NULL) {
+ if (SuspendThread(*h) != ~0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // resume the thread
+ // calling resume on an active thread is a no-op
+ static void do_resume(HANDLE* h) {
+ if (h != NULL) {
+ ResumeThread(*h);
+ }
+ }
+
+ // retrieve a suspend/resume context capable handle
+ // from the tid. Caller validates handle return value.
+ void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {
+ if (h != NULL) {
+ *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
+ }
+ }
+
+ //
+ // Thread sampling implementation
+ //
+ void os::SuspendedThreadTask::internal_do_task() {
+ CONTEXT ctxt;
+ HANDLE h = NULL;
+
+ // get context capable handle for thread
+ get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());
+
+ // sanity
+ if (h == NULL || h == INVALID_HANDLE_VALUE) {
+ return;
+ }
+
+ // suspend the thread
+ if (do_suspend(&h)) {
+ ctxt.ContextFlags = sampling_context_flags;
+ // get thread context
+ GetThreadContext(h, &ctxt);
+ SuspendedThreadTaskContext context(_thread, &ctxt);
+ // pass context to Thread Sampling impl
+ do_task(context);
+ // resume thread
+ do_resume(&h);
+ }
+
+ // close handle
+ CloseHandle(h);
+ }
+
// Kernel32 API
typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);