On Tue, 3 Dec 2019 12:35:20 +0200 "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@xxxxxxxxx> wrote: > +struct tracecmd_time_sync { > + unsigned int sync_proto; > + int loop_interval; > + sem_t sem; Ug, semaphores are a horrible construct. I believe you can do the same thing here with pthread_cond variables. I attached a small program that uses pthread_cond and pthread_mutex to do interval times like this. Note, another thing is, you can just have a global "end" variable that can be set and checked (as I did in my program here). -- Steve > + char *clock_str; > + struct tracecmd_msg_handle *msg_handle; > + void *context; > +}; > +
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdarg.h> #include <errno.h> #include <stdbool.h> #include <pthread.h> #define gettid() syscall(__NR_gettid) static bool end; static void __vdie(const char *fmt, va_list ap, int err) { int ret = errno; if (err && errno) perror("bmp-read"); else ret = -1; fprintf(stderr, " "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); exit(ret); } void pdie(const char *fmt, ...) { va_list ap; va_start(ap, fmt); __vdie(fmt, ap, 1); va_end(ap); } #define NR_THREADS 8 static int nr_threads = NR_THREADS; static pthread_t *threads; static pthread_barrier_t threads_started; struct t_info { int id; int interval; pthread_mutex_t lock; pthread_cond_t cond; }; static void *thread_func(void *arg) { struct t_info *t = arg; pthread_mutex_t *this_mutex = &t->lock; pthread_cond_t *this_cond = &t->cond; struct timespec ts; int cnt = 0; pthread_barrier_wait(&threads_started); while (true) { pthread_mutex_lock(this_mutex); printf("task %d running %d\n", t->id, ++cnt); if (end) break; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += t->id + 1; pthread_cond_timedwait(this_cond, this_mutex, &ts); pthread_mutex_unlock(this_mutex); } pthread_mutex_unlock(this_mutex); printf("Task %d finished\n", t->id); return NULL; } int main (int argc, char **argv) { struct t_info *infos; int ret; int i; infos = calloc(nr_threads, sizeof(*infos)); if (!infos) pdie("calloc"); threads = calloc(nr_threads, sizeof(*threads)); if (!threads) pdie("calloc"); pthread_barrier_init(&threads_started, NULL, nr_threads + 1); for (i = 0; i < nr_threads; i++) { infos[i].id = i; if (pthread_mutex_init(&infos[i].lock, NULL)) pdie("pthread_mutex_init"); ret = pthread_create(&threads[i], NULL, thread_func, &infos[i]); if (ret < 0) pdie("creating thread %d", i); } pthread_barrier_wait(&threads_started); sleep(30); end = true; for (i = 0; i < nr_threads; i++) { pthread_mutex_lock(&infos[i].lock); pthread_cond_signal(&infos[i].cond); pthread_mutex_unlock(&infos[i].lock); pthread_join(threads[i], NULL); } return 0; }
![]() |