Big live update, see details
[lttngtop.git] / lib / mmap-packet-seek.c
diff --git a/lib/mmap-packet-seek.c b/lib/mmap-packet-seek.c
new file mode 100644 (file)
index 0000000..08af9d3
--- /dev/null
@@ -0,0 +1,130 @@
+#include "babeltrace/ctf/types.h"
+#include "babeltrace/ctf/metadata.h"
+
+void ctf_move_mmap_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence)
+{
+       struct ctf_file_stream *file_stream =
+               container_of(pos, struct ctf_file_stream, pos);
+       int ret, err, i;
+       off_t off;
+       struct packet_index *index;
+       int len_index;
+       struct mmap_stream *iter, *tmp;
+       struct mmap_stream tmp_snapshot;
+
+       /* first time we have to mmap the region */
+       if (pos->mmap_len == 0) {
+               /* get the len of the mmap region */
+               ret = kernctl_get_mmap_len(pos->fd, &pos->mmap_len);
+               if (ret != 0) {
+                       ret = errno;
+                       perror("kernctl_get_mmap_len");
+                       goto end;
+               }
+               pos->mmap_real_base = mmap(NULL, pos->mmap_len, PROT_READ, MAP_PRIVATE, pos->fd, 0);
+               if (pos->mmap_real_base == MAP_FAILED) {
+                       perror("Error mmaping");
+                       ret = -1;
+               }
+       }
+
+       if (pos->base) {
+               /* FIXME : put_subbuf should work but fails after nb_subbuf get + put */
+               ret = kernctl_put_next_subbuf(pos->fd);
+               if (ret != 0) {
+                       ret = errno;
+                       perror("kernctl_put_subbuf");
+               }
+               pos->base = NULL;
+       }
+
+next_snapshot:
+       tmp_snapshot.kconsumerd_fd = 0;
+       for (i = 0; i < available_snapshots->len; i++) {
+               tmp = g_ptr_array_index(available_snapshots, 0);
+               if (tmp->kconsumerd_fd->wait_fd == pos->fd) {
+                       tmp_snapshot.last_pos = tmp->last_pos;
+                       tmp_snapshot.kconsumerd_fd = tmp->kconsumerd_fd;
+                       g_ptr_array_remove_index(available_snapshots, i);
+                       free(tmp);
+                       break;
+               }
+       }
+       if (tmp_snapshot.kconsumerd_fd == 0) {
+               pos->offset = EOF;
+               return;
+       }
+//     fprintf(stderr,"READING FROM SNAPSHOT ON FD %d at %lu\n",
+//                     tmp_snapshot.kconsumerd_fd->wait_fd, tmp_snapshot.last_pos);
+       ret = kernctl_get_subbuf(tmp_snapshot.kconsumerd_fd->wait_fd, &tmp_snapshot.last_pos);
+       if (ret != 0) {
+               ret = errno;
+               perror("kernctl_get_subbuf");
+               goto next_snapshot;
+       }
+
+       ret = kernctl_get_mmap_read_offset(pos->fd, &(pos->mmap_offset));
+       if (ret != 0) {
+               ret = errno;
+               perror("kernctl_get_mmap_read_offset");
+               goto end;
+       }
+
+       /* read only the data in the subbuffer */
+       err = kernctl_get_subbuf_size(pos->fd, &pos->content_size);
+       if (err != 0) {
+               ret = errno;
+               perror("Getting sub-buffer len failed.");
+               goto end;
+       }
+       /* bits vs bytes */
+       pos->content_size *= CHAR_BIT;
+       /* read the whole subbuffer */
+       err = kernctl_get_padded_subbuf_size(pos->fd, &pos->packet_size);
+       if (err != 0) {
+               ret = errno;
+               perror("Getting sub-buffer len failed.");
+               goto end;
+       }
+       /* bits vs bytes */
+       pos->packet_size *= CHAR_BIT;
+
+       pos->offset = 0;    /* will read headers */
+
+       /* map new base. Need mapping length from header. */
+       pos->base = pos->mmap_real_base + pos->mmap_offset;
+
+       /* update trace_packet_header and stream_packet_context */
+       if (pos->prot != PROT_WRITE && file_stream->parent.trace_packet_header) {
+               /* Read packet header */
+               ret = generic_rw(&pos->parent, &file_stream->parent.trace_packet_header->p);
+               assert(!ret);
+       }
+       if (pos->prot != PROT_WRITE && file_stream->parent.stream_packet_context) {
+               /* Read packet context */
+               ret = generic_rw(&pos->parent, &file_stream->parent.stream_packet_context->p);
+               assert(!ret);
+       }
+
+       /* read timestamp begin from header */
+       len_index = struct_declaration_lookup_field_index(
+                       file_stream->parent.stream_packet_context->declaration,
+                       g_quark_from_static_string("timestamp_begin"));
+       if (len_index >= 0) {
+               struct definition_integer *defint;
+               struct definition *field;
+
+               field = struct_definition_get_field_from_index(
+                               file_stream->parent.stream_packet_context, len_index);
+               assert(field->declaration->id == CTF_TYPE_INTEGER);
+               defint = container_of(field, struct definition_integer, p);
+               assert(defint->declaration->signedness == FALSE);
+               file_stream->parent.timestamp = defint->value._unsigned;
+//             fprintf(stderr, "READ TIMESTAMP : %lu\n", file_stream->parent.timestamp);
+       }
+
+
+end:
+       return;
+}
+
This page took 0.023293 seconds and 4 git commands to generate.