Re: [PATCH v17 16/18] trace-cmd: Basic infrastructure for host - guest timestamp synchronization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;
}

[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux