#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
return num_cpus;
}
-static int handle_ras_events_cpu(struct pevent *pevent, int cpu, int page_size)
+struct pthread_data {
+ pthread_t thread;
+ struct pevent *pevent;
+ int cpu;
+ int page_size;
+};
+
+static void *handle_ras_events_cpu(void *priv)
{
- int rc, fd;
+ int fd;
struct kbuffer *kbuf;
void *page;
+ char pipe_raw[PATH_MAX];
+ struct pthread_data *data = priv;
- page = malloc(page_size);
+ page = malloc(data->page_size);
if (!page) {
perror("Can't allocate page");
- return errno;
+ return NULL;
}
-printf("Endian: %d\n", ENDIAN);
+
kbuf = kbuffer_alloc(KBUFFER_LSIZE_8, ENDIAN);
if (!kbuf) {
perror("Can't allocate kbuf");
free(page);
- return errno;
+ return NULL;
}
- printf("Number of CPUs: %d. For now, opening just cpu0\n",
- get_num_cpus());
-
/* FIXME: use select to open for all CPUs */
- fd = open(DEBUGFS "tracing/per_cpu/cpu0/trace_pipe_raw",
- O_RDONLY);
+ snprintf(pipe_raw, sizeof(pipe_raw),
+ DEBUGFS "tracing/per_cpu/cpu%d/trace_pipe_raw",
+ data->cpu);
+
+ fd = open(pipe_raw, O_RDONLY);
if (fd < 0) {
perror("Can't open trace_pipe_raw");
kbuffer_free(kbuf);
free(page);
- return errno;
+ return NULL;
}
- rc = read_ras_event(fd, pevent, kbuf, page, page_size);
+ printf("Listening to events on cpu %d\n", data->cpu);
+
+ read_ras_event(fd, data->pevent, kbuf, page, data->page_size);
close(fd);
kbuffer_free(kbuf);
free(page);
- return rc;
+
+ return NULL;
}
static int handle_ras_events(void)
{
- int rc, fd, size, page_size;
+ int rc, fd, size, page_size, i, cpus;
struct pevent *pevent;
+ struct pthread_data *data;
void *page;
/* Enable RAS events */
if (rc)
goto free_pevent;
- /* FIXME: start one thread per CPU */
- rc = handle_ras_events_cpu(pevent, 0, page_size);
+ cpus = get_num_cpus();
+ data = calloc(sizeof(*data), cpus);
+ if (!data)
+ goto free_pevent;
+
+ printf("Opening one thread per cpu (%d threads)\n", cpus);
+ for (i = 0; i < cpus; i++) {
+ data[i].pevent = pevent;
+ data[i].cpu = i;
+ data[i].page_size = page_size;
+
+ rc = pthread_create(&data[i].thread, NULL,
+ handle_ras_events_cpu,
+ (void *)&data[i]);
+ if (rc) {
+ while (--i)
+ pthread_cancel(data[i].thread);
+ goto free_threads;
+ }
+ }
+
+ /* Wait for all threads to complete */
+ for (i = 0; i < cpus; i++)
+ pthread_join(data[i].thread, NULL);
+
+free_threads:
+ free(data);
free_pevent:
pevent_free(pevent);