+/* create a timed thread (object creation only) */
+timed_thread *timed_thread_create(void *start_routine(void *), void *arg,
+ unsigned int interval_usecs)
+{
+ timed_thread *p_timed_thread;
+
+ assert(start_routine != NULL);
+ assert(interval_usecs >= MINIMUM_INTERVAL_USECS);
+
+ if ((p_timed_thread = calloc(sizeof(timed_thread), 1)) == 0) {
+ return NULL;
+ }
+
+ /* create thread pipe (used to tell threads to die) */
+ if (pipe(p_timed_thread->pipefd)) {
+ return NULL;
+ }
+
+ /* init attributes, e.g. joinable thread */
+ pthread_attr_init(&p_timed_thread->thread_attr);
+ pthread_attr_setdetachstate(&p_timed_thread->thread_attr,
+ PTHREAD_CREATE_JOINABLE);
+ /* init mutexes */
+ pthread_mutex_init(&p_timed_thread->cs_mutex, NULL);
+ pthread_mutex_init(&p_timed_thread->runnable_mutex, NULL);
+ /* init cond */
+ pthread_cond_init(&p_timed_thread->runnable_cond, NULL);
+
+ p_timed_thread->start_routine = start_routine;
+ p_timed_thread->arg = arg;
+
+ /* set wait time to current time */
+ if (now(&p_timed_thread->wait_time)) {
+ return NULL;
+ }
+
+ /* seconds portion of the microseconds interval */
+ p_timed_thread->interval_time.tv_sec = (time_t) (interval_usecs / 1000000);
+ /* remaining microseconds convert to nanoseconds */
+ p_timed_thread->interval_time.tv_nsec =
+ (long) ((interval_usecs % 1000000) * 1000);
+
+ /* printf("interval_time.tv_sec = %li, .tv_nsec = %li\n",
+ p_timed_thread->interval_time.tv_sec,
+ p_timed_thread->interval_time.tv_nsec); */
+ return p_timed_thread;