/*============================================================= * 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(); }
/* Returns uninterned symbol. PREFIX can be NULL */ ScmObj Scm_Gensym(ScmString *prefix) { char numbuf[50]; /* We don't need mutex for this variable, since a race on it is tolerated---multiple threads may be get the same name symbols, but they are uninterned and never be eq? to each other. */ static intptr_t gensym_count = 0; if (prefix == NULL) prefix = &default_prefix; int nc = snprintf(numbuf, 49, "%"PRIdPTR, gensym_count++); numbuf[49] = '\0'; ScmObj name = Scm_StringAppendC(prefix, numbuf, nc, nc); ScmSymbol *sym = make_sym(SCM_CLASS_SYMBOL, SCM_STRING(name), FALSE); return SCM_OBJ(sym); }
/*============================================================= * 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(); }