Created
August 15, 2014 05:30
-
-
Save SaitoAtsushi/7555d9352084ecedc715 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/configure.ac b/configure.ac | |
index 16448ce..c900f48 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -452,7 +452,7 @@ dnl Also adds -DUNICODE to CFLAGS enable Windows wchar API, | |
dnl if GAUCHE_CHAR_ENCODING is UTF_8. | |
dnl ALTERNATIVE_GOSH is no-console version of gosh; only built on Windows. | |
case "$host" in | |
- *mingw*) LIBS="$LIBS -lnetapi32 -lshlwapi -lws2_32" | |
+ *mingw*) LIBS="$LIBS -lnetapi32 -lshlwapi -lws2_32 -lkernel32" | |
ALTERNATIVE_GOSH="gosh-noconsole.exe" | |
case "$GAUCHE_CHAR_ENCODING" in | |
utf8) CFLAGS="$CFLAGS -DUNICODE" ;; | |
diff --git a/src/gauche/vm.h b/src/gauche/vm.h | |
index f96c9fc..bacea82 100644 | |
--- a/src/gauche/vm.h | |
+++ b/src/gauche/vm.h | |
@@ -45,7 +45,7 @@ | |
#define SCM_PCTYPE ScmWord* | |
-#if defined(ITIMER_PROF) && defined(SIGPROF) | |
+#if (defined(ITIMER_PROF) && defined(SIGPROF)) || defined(GAUCHE_WINDOWS) | |
/* define if you want to use profiler */ | |
#define GAUCHE_PROFILE | |
#endif /* defined(ITIMER_PROF) && defined(SIGPROF) */ | |
diff --git a/src/prof.c b/src/prof.c | |
index 15de532..2e70906 100644 | |
--- a/src/prof.c | |
+++ b/src/prof.c | |
@@ -53,6 +53,48 @@ | |
#define SAMPLING_PERIOD 10000 | |
+#ifdef GAUCHE_WINDOWS | |
+#define TIMERNAME L"Profiler Stopper" | |
+ | |
+HANDLE mainThread = INVALID_HANDLE_VALUE; | |
+ | |
+static void sampler_sample(ScmVM*); | |
+HANDLE hTimer = INVALID_HANDLE_VALUE; | |
+ | |
+void do_observer_thrad(void* arg) | |
+{ | |
+ HANDLE hTimer = (HANDLE)OpenEvent(TIMER_ALL_ACCESS, FALSE, TIMERNAME); | |
+ ScmVM* vm=(ScmVM*) arg; | |
+ | |
+ do { | |
+ if(SuspendThread(mainThread) == -1) | |
+ Scm_SysError("suspend failed"); | |
+ | |
+ sampler_sample(vm); | |
+ | |
+ if(ResumeThread(mainThread)==-1) | |
+ Scm_SysError("suspend failed"); | |
+ } while(WAIT_OBJECT_0 != WaitForSingleObject(hTimer, 10)); | |
+ | |
+ CloseHandle(hTimer); | |
+ _endthread(); | |
+} | |
+ | |
+inline void ITIMER_START(void) | |
+{ | |
+ _beginthread(do_observer_thrad, 0, Scm_VM()); | |
+} | |
+ | |
+inline void ITIMER_STOP(void) | |
+{ | |
+ HANDLE hTimer = (HANDLE)OpenEvent(TIMER_ALL_ACCESS, FALSE, TIMERNAME); | |
+ SetEvent(hTimer); | |
+ Sleep(10); | |
+ ResetEvent(hTimer); | |
+ CloseHandle(hTimer); | |
+} | |
+ | |
+#else | |
#define ITIMER_START() \ | |
do { \ | |
struct itimerval tval, oval; \ | |
@@ -73,6 +115,8 @@ | |
setitimer(ITIMER_PROF, &tval, &oval); \ | |
} while (0) | |
+#endif | |
+ | |
/*============================================================= | |
* Statistic sampler | |
*/ | |
@@ -100,16 +144,27 @@ static void sampler_flush(ScmVM *vm) | |
} | |
/* signal handler */ | |
+#ifdef GAUCHE_WINDOWS | |
+static void sampler_sample(ScmVM *vm) | |
+#else | |
static void sampler_sample(int sig) | |
+#endif | |
{ | |
+#ifndef GAUCHE_WINDOWS | |
ScmVM *vm = Scm_VM(); | |
+#endif | |
+ | |
if (vm == NULL || vm->prof == NULL) return; | |
if (vm->prof->state != SCM_PROFILER_RUNNING) return; | |
if (vm->prof->currentSample >= SCM_PROF_SAMPLES_IN_BUFFER) { | |
+#ifndef GAUCHE_WINDOWS | |
ITIMER_STOP(); | |
+#endif | |
sampler_flush(vm); | |
+#ifndef GAUCHE_WINDOWS | |
ITIMER_START(); | |
+#endif | |
} | |
int i = vm->prof->currentSample++; | |
@@ -162,11 +217,12 @@ void Scm_ProfilerCountBufferFlush(ScmVM *vm) | |
if (vm->prof->currentCount == 0) return; | |
/* suspend itimer during hash table operation */ | |
+#ifndef GAUCHE_WINDOWS | |
sigset_t set; | |
sigemptyset(&set); | |
sigaddset(&set, SIGPROF); | |
SIGPROCMASK(SIG_BLOCK, &set, NULL); | |
- | |
+#endif | |
int ncounts = vm->prof->currentCount; | |
for (int i=0; i<ncounts; i++) { | |
ScmObj e; | |
@@ -198,7 +254,10 @@ void Scm_ProfilerCountBufferFlush(ScmVM *vm) | |
vm->prof->currentCount = 0; | |
/* resume itimer */ | |
+#ifndef GAUCHE_WINDOWS | |
SIGPROCMASK(SIG_UNBLOCK, &set, NULL); | |
+#endif | |
+ | |
} | |
/*============================================================= | |
@@ -207,7 +266,7 @@ void Scm_ProfilerCountBufferFlush(ScmVM *vm) | |
void Scm_ProfilerStart(void) | |
{ | |
ScmVM *vm = Scm_VM(); | |
- char templat[] = "/tmp/gauche-profXXXXXX"; | |
+ char templat[] = "/temp/gauche-profXXXXXX"; | |
if (!vm->prof) { | |
vm->prof = SCM_NEW(ScmVMProfiler); | |
@@ -230,6 +289,16 @@ void Scm_ProfilerStart(void) | |
vm->profilerRunning = TRUE; | |
/* NB: this should be done globally!!! */ | |
+#ifdef GAUCHE_WINDOWS | |
+ if(!DuplicateHandle(GetCurrentProcess(), | |
+ GetCurrentThread(), | |
+ GetCurrentProcess(), | |
+ &mainThread, | |
+ PROCESS_ALL_ACCESS, FALSE, 0)) { | |
+ Scm_SysError("duplicatehandle failed"); | |
+ }; | |
+ hTimer = CreateEvent(NULL, FALSE, FALSE, TIMERNAME); | |
+#else | |
struct sigaction act; | |
act.sa_handler = sampler_sample; | |
sigfillset(&act.sa_mask); | |
@@ -237,6 +306,7 @@ void Scm_ProfilerStart(void) | |
if (sigaction(SIGPROF, &act, NULL) < 0) { | |
Scm_SysError("sigaction failed"); | |
} | |
+#endif | |
ITIMER_START(); | |
} | |
@@ -247,6 +317,10 @@ int Scm_ProfilerStop(void) | |
if (vm->prof == NULL) return 0; | |
if (vm->prof->state != SCM_PROFILER_RUNNING) return 0; | |
ITIMER_STOP(); | |
+#ifdef GAUCHE_WINDOWS | |
+ CloseHandle(hTimer); | |
+ CloseHandle(mainThread); | |
+#endif | |
vm->prof->state = SCM_PROFILER_PAUSING; | |
vm->profilerRunning = FALSE; | |
return vm->prof->totalSamples; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment