ustd: use commit_seq to get buffers from crashed process
[ust.git] / ustd / lowlevel.c
1 #include <assert.h>
2
3 #include "tracer.h"
4 #include "ustd.h"
5 #include "localerr.h"
6
7 #define USTD_BUFFER_TRUNC(offset, bufinfo) \
8 ((offset) & (~(((bufinfo)->subbuf_size*(bufinfo)->n_subbufs)-1)))
9
10 void finish_consuming_dead_subbuffer(struct buffer_info *buf)
11 {
12 struct ltt_channel_buf_struct *ltt_buf = buf->bufstruct_mem;
13
14 long write_offset = local_read(&ltt_buf->offset);
15 long consumed_offset = atomic_long_read(&ltt_buf->consumed);
16
17 long i_subbuf;
18
19 DBG("processing died buffer");
20 DBG("consumed offset is %ld", consumed_offset);
21 DBG("write offset is %ld", write_offset);
22
23 long first_subbuf = consumed_offset / buf->subbuf_size;
24 long last_subbuf = write_offset / buf->subbuf_size;
25
26 if(last_subbuf - first_subbuf > buf->n_subbufs) {
27 DBG("an overflow has occurred, nothing can be recovered");
28 return;
29 }
30
31 for(i_subbuf=first_subbuf; ; i_subbuf++, i_subbuf %= buf->n_subbufs) {
32 void *tmp;
33 long commit_seq = local_read(&ltt_buf->commit_seq[i_subbuf]);
34
35 unsigned long valid_length = buf->subbuf_size;
36 long n_subbufs_order = get_count_order(buf->n_subbufs);
37 long commit_seq_mask = (~0UL >> n_subbufs_order);
38
39 if((commit_seq & commit_seq_mask) == 0)
40 break;
41
42 /* check if subbuf was fully written */
43 if (!((commit_seq - buf->subbuf_size) & commit_seq_mask)
44 - (USTD_BUFFER_TRUNC(consumed_offset, buf) >> n_subbufs_order)
45 != 0) {
46 struct ltt_subbuffer_header *header = (struct ltt_subbuffer_header *)((char *)buf->mem)+i_subbuf*buf->subbuf_size;
47 valid_length = (unsigned long)buf->subbuf_size - header->lost_size;
48 }
49 else {
50 struct ltt_subbuffer_header *header = (struct ltt_subbuffer_header *)((char *)buf->mem)+i_subbuf*buf->subbuf_size;
51
52 valid_length = commit_seq;
53 header->lost_size = buf->subbuf_size-valid_length;
54 assert(i_subbuf == last_subbuf);
55 }
56
57 patient_write(buf->file_fd, buf->mem + i_subbuf * buf->subbuf_size, valid_length);
58
59 /* pad with empty bytes */
60 tmp = malloc(buf->subbuf_size-valid_length);
61 memset(tmp, 0, buf->subbuf_size-valid_length);
62 patient_write(buf->file_fd, tmp, buf->subbuf_size-valid_length);
63 free(tmp);
64
65 if(i_subbuf == last_subbuf)
66 break;
67 }
68 }
69
This page took 0.031229 seconds and 5 git commands to generate.