static void *itimer_thread_func(void *_handle_tick) { TickProc handle_tick = _handle_tick; uint64_t nticks; int timerfd = -1; #if defined(USE_TIMERFD_FOR_ITIMER) && USE_TIMERFD_FOR_ITIMER struct itimerspec it; it.it_value.tv_sec = TimeToSeconds(itimer_interval); it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000; it.it_interval = it.it_value; timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { sysErrorBelch("timerfd_create"); stg_exit(EXIT_FAILURE); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { sysErrorBelch("timerfd_settime"); stg_exit(EXIT_FAILURE); } #endif while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { sysErrorBelch("Itimer: read(timerfd) failed"); } } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { sysErrorBelch("usleep(TimeToUS(itimer_interval) failed"); } } // first try a cheap test if (stopped) { ACQUIRE_LOCK(&mutex); // should we really stop? if (stopped) { waitCondition(&start_cond, &mutex); } RELEASE_LOCK(&mutex); } else { handle_tick(0); } } if (USE_TIMERFD_FOR_ITIMER) close(timerfd); closeMutex(&mutex); closeCondition(&start_cond); return NULL; }
int waitForPipeFullyEmpty(int pipe) { Spipe *p = checkSpipeData(pipe); if(!p) return -1; waitCondition(p->fully_empty_wid); return p->seek - p->offset; }
int waitForPipeReadyWrite(int pipe) { Spipe *p = checkSpipeData(pipe); if(!p) return -1; waitCondition(p->ready_write_wid); return p->seek - p->offset; }
int waitForPipeFullyFlushed(int pipe) { Spipe *p = checkSpipeData(pipe); if(!p) return -1; if(p->seek - p->offset < p->size) { waitCondition(p->fully_flushed_wid); } return p->seek; }