start implementing sharing of buffer info
[lttng-ust.git] / libtracing / relay.c
index 0133f3e3bb5cc8ae57073fd6b6d541b96c1cfc24..2087bcd98a9294b163ea7619353f58996a14ae53 100644 (file)
@@ -92,8 +92,8 @@ static struct dentry *ltt_create_buf_file_callback(struct rchan_buf *buf);
 
 static int relay_alloc_buf(struct rchan_buf *buf, size_t *size)
 {
-       unsigned int n_pages;
-       struct buf_page *buf_page, *n;
+//ust//        unsigned int n_pages;
+//ust//        struct buf_page *buf_page, *n;
 
        void *ptr;
        int result;
@@ -892,9 +892,13 @@ static notrace void ltt_deliver(struct rchan_buf *buf, unsigned int subbuf_idx,
        struct ltt_channel_struct *channel =
                (struct ltt_channel_struct *)buf->chan->private_data;
        struct ltt_channel_buf_struct *ltt_buf = channel->buf;
+       int result;
 
-       if(ltt_buf->call_wake_consumer)
-               relay_wake_consumer(ACCESS_ONCE(ltt_buf->wake_consumer_arg), 0);
+       result = write(ltt_buf->data_ready_fd_write, "1", 1);
+       if(result == -1) {
+               PERROR("write (in ltt_relay_buffer_flush)");
+               ERR("this should never happen!");
+       }
 //ust//        atomic_set(&ltt_buf->wakeup_readers, 1);
 }
 
@@ -1456,6 +1460,8 @@ static int ltt_relay_create_buffer(struct ltt_trace_struct *trace,
 {
        struct ltt_channel_buf_struct *ltt_buf = ltt_chan->buf;
        unsigned int j;
+       int fds[2];
+       int result;
 
        ltt_buf->commit_count =
                zmalloc(sizeof(ltt_buf->commit_count) * n_subbufs);
@@ -1480,8 +1486,13 @@ static int ltt_relay_create_buffer(struct ltt_trace_struct *trace,
        local_set(&ltt_buf->events_lost, 0);
        local_set(&ltt_buf->corrupted_subbuffers, 0);
 
-       ltt_buf->call_wake_consumer = 0;
-       ltt_buf->wake_consumer_arg = NULL;
+       result = pipe(fds);
+       if(result == -1) {
+               PERROR("pipe");
+               return -1;
+       }
+       ltt_buf->data_ready_fd_read = fds[0];
+       ltt_buf->data_ready_fd_write = fds[1];
 
        return 0;
 }
@@ -1501,6 +1512,48 @@ static void ltt_relay_destroy_buffer(struct ltt_channel_struct *ltt_chan)
 //ust//        wake_up_interruptible(&trace->kref_wq);
 }
 
+static void ltt_chan_alloc_ltt_buf(struct ltt_channel_struct *ltt_chan)
+{
+       void *ptr;
+       int result;
+
+       /* Get one page */
+       size_t size = PAGE_ALIGN(1);
+
+       result = ltt_chan->buf_shmid = shmget(getpid(), size, IPC_CREAT | IPC_EXCL | 0700);
+       if(ltt_chan->buf_shmid == -1) {
+               PERROR("shmget");
+               return -1;
+       }
+
+       ptr = shmat(ltt_chan->buf_shmid, NULL, 0);
+       if(ptr == (void *) -1) {
+               perror("shmat");
+               goto destroy_shmem;
+       }
+
+       /* Already mark the shared memory for destruction. This will occur only
+         * when all users have detached.
+        */
+       result = shmctl(ltt_chan->buf_shmid, IPC_RMID, NULL);
+       if(result == -1) {
+               perror("shmctl");
+               return -1;
+       }
+
+       ltt_chan->buf = ptr;
+
+       return 0;
+
+       destroy_shmem:
+       result = shmctl(ltt_chan->buf_shmid, IPC_RMID, NULL);
+       if(result == -1) {
+               perror("shmctl");
+       }
+
+       return -1;
+}
+
 /*
  * Create channel.
  */
@@ -1535,7 +1588,10 @@ static int ltt_relay_create_channel(const char *trace_name,
        ltt_chan->n_subbufs_order = get_count_order(n_subbufs);
        ltt_chan->commit_count_mask = (~0UL >> ltt_chan->n_subbufs_order);
 //ust//        ltt_chan->buf = percpu_alloc_mask(sizeof(struct ltt_channel_buf_struct), GFP_KERNEL, cpu_possible_map);
-       ltt_chan->buf = malloc(sizeof(struct ltt_channel_buf_struct));
+
+       ltt_chan_alloc_ltt_buf(ltt_chan);
+
+//ust//        ltt_chan->buf = malloc(sizeof(struct ltt_channel_buf_struct));
        if (!ltt_chan->buf)
                goto alloc_error;
        ltt_chan->trans_channel_data = ltt_relay_open(tmpname,
@@ -1593,11 +1649,16 @@ static notrace void ltt_relay_buffer_flush(struct rchan_buf *buf)
        struct ltt_channel_struct *channel =
                (struct ltt_channel_struct *)buf->chan->private_data;
        struct ltt_channel_buf_struct *ltt_buf = channel->buf;
+       int result;
 
        buf->finalized = 1;
        ltt_force_switch(buf, FORCE_FLUSH);
 
-       relay_wake_consumer(ltt_buf, 1);
+       result = write(ltt_buf->data_ready_fd_write, "1", 1);
+       if(result == -1) {
+               PERROR("write (in ltt_relay_buffer_flush)");
+               ERR("this should never happen!");
+       }
 }
 
 static void ltt_relay_async_wakeup_chan(struct ltt_channel_struct *ltt_channel)
@@ -1619,11 +1680,20 @@ static void ltt_relay_async_wakeup_chan(struct ltt_channel_struct *ltt_channel)
 static void ltt_relay_finish_buffer(struct ltt_channel_struct *ltt_channel)
 {
        struct rchan *rchan = ltt_channel->trans_channel_data;
+       int result;
 
        if (rchan->buf) {
                struct ltt_channel_buf_struct *ltt_buf = ltt_channel->buf;
                ltt_relay_buffer_flush(rchan->buf);
 //ust//                ltt_relay_wake_writers(ltt_buf);
+               /* closing the pipe tells the consumer the buffer is finished */
+               
+               //result = write(ltt_buf->data_ready_fd_write, "D", 1);
+               //if(result == -1) {
+               //      PERROR("write (in ltt_relay_finish_buffer)");
+               //      ERR("this should never happen!");
+               //}
+               close(ltt_buf->data_ready_fd_write);
        }
 }
 
This page took 0.02766 seconds and 4 git commands to generate.