void* bootstrap_main(void *v) { SCM th; (void)v; scm_c_define_gsubr("test-func", 0, 0, 0, test_func); th = scm_spawn_thread(scheme_environment, NULL, NULL, NULL); scm_join_thread(th); return NULL; }
void init_scheduler(void) { event_tag = scm_make_smob_type("sched_event", sizeof(SCHED_EVENT)); queue = NULL; pool = NULL; gc_hit = 0; pthread_mutex_init(&qmutex, NULL); pthread_mutex_init(&pmutex, NULL); pthread_cond_init(&qcondvar, NULL); scm_c_define_gsubr("sched-at", 2, 1, 0, sched_at); scm_c_define_gsubr("sched-in", 2, 1, 0, sched_in); scm_c_define_gsubr("sched-cancel", 1, 0, 0, sched_cancel); scm_c_define_gsubr("sched-entry?", 1, 0, 0, sched_has_entry); scm_c_define_gsubr("sched-entry-time", 1, 0, 0, sched_entry_time); scm_spawn_thread(sched_thread, NULL, NULL, NULL); return; }
static SCM sched_thread(void *data) { SCHED_EVENT *event; utime_t next_wake; utime_t now, early, late; time_t tnow; scheduling = 1; next_wake = 0; pthread_mutex_lock(&qmutex); while (scheduling) { pthread_cond_timedwait(&qcondvar, &qmutex, sleep_till(next_wake)); now = now_usec(); late = now - DISPATCH_WINDOW / 2; early = now + DISPATCH_WINDOW / 2; event = queue; while (event != NULL) { if (event->clock < late) { log_msg("would drop %1.3f < %1.3f\n", event->clock / (double)TIME_RES, late / (double)TIME_RES); // queue = event->link; // release_node(event); // event = queue; // continue; } if (event->clock > early) break; queue = event->link; if (event->state == STATE_PENDING) { scm_spawn_thread(dispatch_event, (void *)&(event->action), NULL, NULL); } release_node(event); event = queue; } queue = sweep_cancellations(queue); if (queue != NULL) next_wake = queue->clock; else next_wake = 0; if (((tnow = time(NULL)) - gc_hit) > GC_HIT_INTERVAL) { gc_hit = tnow; scm_gc(); } } pthread_mutex_unlock(&qmutex); return SCM_BOOL_T; }