예제 #1
0
/*=============================================================
 * External API
 */
void Scm_ProfilerStart(void)
{
    ScmVM *vm = Scm_VM();
    ScmObj templat = Scm_StringAppendC(SCM_STRING(Scm_TmpDir()),
                                       "/gauche-profXXXXXX", -1, -1);
    char *templat_buf = Scm_GetString(SCM_STRING(templat)); /*mutable copy*/

    if (!vm->prof) {
        vm->prof = SCM_NEW(ScmVMProfiler);
        vm->prof->state = SCM_PROFILER_INACTIVE;
        vm->prof->samplerFd = Scm_Mkstemp(templat_buf);
        vm->prof->currentSample = 0;
        vm->prof->totalSamples = 0;
        vm->prof->errorOccurred = 0;
        vm->prof->currentCount = 0;
        vm->prof->statHash =
            SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0));
#if defined(GAUCHE_WINDOWS)
        vm->prof->hTargetThread = NULL;
        vm->prof->hObserverThread = NULL;
        vm->prof->hTimerEvent = NULL;
        vm->prof->samplerFileName = templat_buf;
#else  /* !GAUCHE_WINDOWS */
        unlink(templat_buf);       /* keep anonymous tmpfile */
#endif /* !GAUCHE_WINDOWS */
    } else if (vm->prof->samplerFd < 0) {
        vm->prof->samplerFd = Scm_Mkstemp(templat_buf);
#if defined(GAUCHE_WINDOWS)
        vm->prof->samplerFileName = templat_buf;
#else  /* !GAUCHE_WINDOWS */
        unlink(templat_buf);
#endif /* !GAUCHE_WINDOWS */
    }

    if (vm->prof->state == SCM_PROFILER_RUNNING) return;
    vm->prof->state = SCM_PROFILER_RUNNING;
    vm->profilerRunning = TRUE;

    /* NB: this should be done globally!!! */
#if defined(GAUCHE_WINDOWS)
    if (!DuplicateHandle(GetCurrentProcess(),
                         GetCurrentThread(),
                         GetCurrentProcess(),
                         &vm->prof->hTargetThread,
                         0, FALSE, DUPLICATE_SAME_ACCESS)) {
        vm->prof->hTargetThread = NULL;
        Scm_SysError("DuplicateHandle failed");
    }
#else  /* !GAUCHE_WINDOWS */
    struct sigaction act;
    act.sa_handler = sampler_sample;
    sigfillset(&act.sa_mask);
    act.sa_flags = SA_RESTART;
    if (sigaction(SIGPROF, &act, NULL) < 0) {
        Scm_SysError("sigaction failed");
    }
#endif /* !GAUCHE_WINDOWS */

    ITIMER_START();
}
예제 #2
0
파일: prof.c 프로젝트: qykth-git/Gauche
/*=============================================================
 * External API
 */
void Scm_ProfilerStart(void)
{
    ScmVM *vm = Scm_VM();
    ScmObj templat = Scm_StringAppendC(SCM_STRING(Scm_TmpDir()),
                                       "/gauche-profXXXXXX", -1, -1);
    char *templat_buf = Scm_GetString(SCM_STRING(templat)); /*mutable copy*/

    if (!vm->prof) {
        vm->prof = SCM_NEW(ScmVMProfiler);
        vm->prof->state = SCM_PROFILER_INACTIVE;
        vm->prof->samplerFd = Scm_Mkstemp(templat_buf);
        vm->prof->currentSample = 0;
        vm->prof->totalSamples = 0;
        vm->prof->errorOccurred = 0;
        vm->prof->currentCount = 0;
        vm->prof->statHash =
            SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0));
        unlink(templat_buf);       /* keep anonymous tmpfile */
    } else if (vm->prof->samplerFd < 0) {
        vm->prof->samplerFd = Scm_Mkstemp(templat_buf);
        unlink(templat_buf);
    }

    if (vm->prof->state == SCM_PROFILER_RUNNING) return;
    vm->prof->state = SCM_PROFILER_RUNNING;
    vm->profilerRunning = TRUE;

    /* NB: this should be done globally!!! */
    struct sigaction act;
    act.sa_handler = sampler_sample;
    sigfillset(&act.sa_mask);
    act.sa_flags = SA_RESTART;
    if (sigaction(SIGPROF, &act, NULL) < 0) {
        Scm_SysError("sigaction failed");
    }

    ITIMER_START();
}