Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(193)

Unified Diff: src/pkg/runtime/windows/thread.c

Issue 4960057: code review 4960057: runtime: implement pprof support for windows (Closed)
Patch Set: diff -r b80728111ff9 https://go.googlecode.com/hg/ Created 12 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pkg/runtime/windows/os.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pkg/runtime/windows/thread.c
===================================================================
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -10,32 +10,48 @@
#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
+#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
+#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
+#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
#pragma dynimport runtime·LoadLibraryEx LoadLibraryExA "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceCounter QueryPerformanceCounter "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceFrequency QueryPerformanceFrequency "kernel32.dll"
+#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
+#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
+#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
+#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
+#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
extern void *runtime·CloseHandle;
extern void *runtime·CreateEvent;
extern void *runtime·CreateThread;
+extern void *runtime·CreateWaitableTimer;
+extern void *runtime·DuplicateHandle;
extern void *runtime·ExitProcess;
extern void *runtime·FreeEnvironmentStringsW;
extern void *runtime·GetEnvironmentStringsW;
extern void *runtime·GetProcAddress;
extern void *runtime·GetStdHandle;
+extern void *runtime·GetThreadContext;
extern void *runtime·LoadLibraryEx;
extern void *runtime·QueryPerformanceCounter;
extern void *runtime·QueryPerformanceFrequency;
+extern void *runtime·ResumeThread;
extern void *runtime·SetConsoleCtrlHandler;
extern void *runtime·SetEvent;
+extern void *runtime·SetThreadPriority;
+extern void *runtime·SetWaitableTimer;
+extern void *runtime·SuspendThread;
+extern void *runtime·timeBeginPeriod;
extern void *runtime·WaitForSingleObject;
extern void *runtime·WriteFile;
@@ -44,8 +60,13 @@
void
runtime·osinit(void)
{
+ // -1 = current process, -2 = current thread
+ runtime·stdcall(runtime·DuplicateHandle, 7,
+ (uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
+ (uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
+ runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
}
void
@@ -211,11 +232,13 @@
USED(g); // assuming g = m->g0
USED(fn); // assuming fn = mstart
- thandle = runtime·stdcall(runtime·CreateThread, 6, (uintptr)0, (uintptr)0, runtime·tstart_stdcall, m, (uintptr)0, (uintptr)0);
- if(thandle == 0) {
+ thandle = runtime·stdcall(runtime·CreateThread, 6,
+ nil, nil, runtime·tstart_stdcall, m, nil, nil);
+ if(thandle == nil) {
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
runtime·throw("runtime.newosproc");
}
+ runtime·atomicstorep(&m->thread, thandle);
}
// Called to initialize a new m (including the bootstrap m).
@@ -324,6 +347,89 @@
return 0;
}
+extern void runtime·dosigprof(Context *r, G *gp);
+extern void runtime·profileloop(void);
+static void *profiletimer;
+
+static void
+profilem(M *mp)
+{
+ extern M runtime·m0;
+ extern uint32 runtime·tls0[];
+ byte rbuf[sizeof(Context)+15];
+ Context *r;
+ void *tls;
+ G *gp;
+
+ tls = mp->tls;
+ if(mp == &runtime·m0)
+ tls = runtime·tls0;
+ gp = *(G**)tls;
+
+ if(gp != nil && gp != mp->g0 && gp->status != Gsyscall) {
+ // align Context to 16 bytes
+ r = (Context*)((uintptr)(&rbuf[15]) & ~15);
+ r->ContextFlags = CONTEXT_CONTROL;
+ runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r);
+ runtime·dosigprof(r, gp);
+ }
+}
+
+void
+runtime·profileloop1(void)
+{
+ M *mp, *allm;
+ void *thread;
+
+ runtime·stdcall(runtime·SetThreadPriority, 2,
+ (uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST);
+
+ for(;;) {
+ runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (uintptr)-1);
+ allm = runtime·atomicloadp(&runtime·allm);
+ for(mp = allm; mp != nil; mp = mp->alllink) {
+ thread = runtime·atomicloadp(&mp->thread);
brainman 2011/09/16 02:56:42 Why do you prefer that to starting new thread susp
+ if(thread == nil)
+ continue;
+ runtime·stdcall(runtime·SuspendThread, 1, thread);
+ if(mp->profilehz != 0)
+ profilem(mp);
+ runtime·stdcall(runtime·ResumeThread, 1, thread);
+ }
+ }
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+ static Lock lock;
+ void *timer, *thread;
+ int32 ms;
+ int64 due;
+
+ runtime·lock(&lock);
+ if(profiletimer == nil) {
+ timer = runtime·stdcall(runtime·CreateWaitableTimer, 3, nil, nil, nil);
+ runtime·atomicstorep(&profiletimer, timer);
+ thread = runtime·stdcall(runtime·CreateThread, 6,
+ nil, nil, runtime·profileloop, nil, nil, nil);
+ runtime·stdcall(runtime·CloseHandle, 1, thread);
+ }
+ runtime·unlock(&lock);
+
+ ms = 0;
+ due = 1LL<<63;
+ if(hz > 0) {
+ ms = 1000 / hz;
+ if(ms == 0)
+ ms = 1;
+ due = ms * -10000;
+ }
+ runtime·stdcall(runtime·SetWaitableTimer, 6,
+ profiletimer, &due, (uintptr)ms, nil, nil, nil);
+ runtime·atomicstore((uint32*)&m->profilehz, hz);
+}
+
void
os·sigpipe(void)
{
« no previous file with comments | « src/pkg/runtime/windows/os.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b