/* * External entry to manage registering callbacks * 'xtra1' and 'xtra2' are ignored by most callbacks; only the two callbacks * use them: * glutTimerFunc: xtra1 for millliseconds, xtra2 for value * glutJoystickFunc: xtra1 for interval */ void Scm_GlutRegisterCallback(int type, ScmObj closure, int xtra1, int xtra2) { SCM_ASSERT(type >= 0 && type < SCM_GLUT_NUM_CBS); if (type < SCM_GLUT_NUM_WINDOW_CBS) { int win = glutGetWindow(); ScmObj entry = Scm_HashTableRef(SCM_HASH_TABLE(ScmGlutCallbackTable), SCM_MAKE_INT(win), SCM_FALSE); if (SCM_EQ(entry, SCM_FALSE)) { entry = Scm_MakeVector(SCM_GLUT_NUM_WINDOW_CBS, SCM_FALSE); Scm_HashTableSet(SCM_HASH_TABLE(ScmGlutCallbackTable), SCM_MAKE_INT(win), entry, 0); } SCM_VECTOR_ELEMENT(entry, type) = closure; registrars[type](!SCM_FALSEP(closure), xtra1); } else if (type == SCM_GLUT_CB_IDLE) { idle_closure = closure; if (SCM_FALSEP(closure)) { glutIdleFunc(NULL); } else { glutIdleFunc(idle_cb); } } else { timer_closure = closure; if (!SCM_FALSEP(closure)) { glutTimerFunc(xtra1, timer_cb, xtra2); } } }
/*============================================================= * 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(); }
static ScmObj get_callback(int type) { int win = glutGetWindow(); ScmObj entry = Scm_HashTableRef(SCM_HASH_TABLE(ScmGlutCallbackTable), SCM_MAKE_INT(win), SCM_FALSE); SCM_ASSERT(type >= 0 && type < SCM_GLUT_NUM_WINDOW_CBS); if (SCM_VECTORP(entry)) { return SCM_VECTOR_ELEMENT(entry, type); } else { return SCM_FALSE; } }
/* Write/ss main driver This should never be called recursively. We modify port->flags and port->writeState; they are cleaned up by the caller even if we throw an error during write. */ static void write_ss(ScmObj obj, ScmPort *port, ScmWriteContext *ctx) { SCM_ASSERT(port->writeState == NULL); /* pass 1 */ port->flags |= SCM_PORT_WALKING; if (SCM_WRITE_MODE(ctx)==SCM_WRITE_SHARED) port->flags |= SCM_PORT_WRITESS; ScmWriteState *s = Scm_MakeWriteState(NULL); s->sharedTable = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0)); port->writeState = s; write_walk(obj, port); port->flags &= ~(SCM_PORT_WALKING|SCM_PORT_WRITESS); /* pass 2 */ write_rec(obj, port, ctx); cleanup_port_write_state(port); }
void Scm_ProfilerReset(void) { ScmVM *vm = Scm_VM(); if (vm->prof == NULL) return; if (vm->prof->state == SCM_PROFILER_INACTIVE) return; if (vm->prof->state == SCM_PROFILER_RUNNING) Scm_ProfilerStop(); if (vm->prof->samplerFd >= 0) { close(vm->prof->samplerFd); vm->prof->samplerFd = -1; } vm->prof->totalSamples = 0; vm->prof->currentSample = 0; vm->prof->errorOccurred = 0; vm->prof->currentCount = 0; vm->prof->statHash = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0)); vm->prof->state = SCM_PROFILER_INACTIVE; }
/*============================================================= * 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(); }
void Scm_ProfilerReset(void) { ScmVM *vm = Scm_VM(); if (vm->prof == NULL) return; if (vm->prof->state == SCM_PROFILER_INACTIVE) return; if (vm->prof->state == SCM_PROFILER_RUNNING) Scm_ProfilerStop(); if (vm->prof->samplerFd >= 0) { close(vm->prof->samplerFd); vm->prof->samplerFd = -1; #if defined(GAUCHE_WINDOWS) unlink(vm->prof->samplerFileName); #endif /* GAUCHE_WINDOWS */ } vm->prof->totalSamples = 0; vm->prof->currentSample = 0; vm->prof->errorOccurred = 0; vm->prof->currentCount = 0; vm->prof->statHash = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_EQ, 0)); vm->prof->state = SCM_PROFILER_INACTIVE; }
void Scm__InitSymbol(void) { SCM_INTERNAL_MUTEX_INIT(obtable_mutex); obtable = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_STRING, 4096)); init_builtin_syms(); }