Skip to content

Instantly share code, notes, and snippets.

@SaitoAtsushi
Created August 15, 2014 05:30
Show Gist options
  • Save SaitoAtsushi/7555d9352084ecedc715 to your computer and use it in GitHub Desktop.
Save SaitoAtsushi/7555d9352084ecedc715 to your computer and use it in GitHub Desktop.
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