2 * Copyright (C) 2008 Eduard - Gabriel Munteanu
4 * This file is released under GPL version 2.
11 #include <sys/types.h>
19 #include <kmemtrace.h>
21 struct dataset
*dataset_open(char *format
, unsigned long cpu
)
27 ret
= malloc(sizeof(struct dataset
));
31 len
= snprintf(ret
->filename
, FILENAME_MAX
, format
, cpu
);
32 if (len
>= FILENAME_MAX
)
35 ret
->fd
= open(ret
->filename
, O_RDONLY
);
39 if (fstat(ret
->fd
, &stat_buf
))
41 ret
->size
= stat_buf
.st_size
;
43 ret
->map
= mmap(NULL
, ret
->size
, PROT_READ
, MAP_PRIVATE
, ret
->fd
, 0);
56 void dataset_close(struct dataset
*set
)
61 munmap(set
->map
, set
->size
);
65 static inline struct dataset_event
dataset_event_read(struct dataset
*set
,
68 struct dataset_event d_ev
;
70 d_ev
.event
= set
->map
+ *offset
;
72 if (((void *) d_ev
.event
) + d_ev
.event
->event_size
>
73 set
->map
+ set
->size
) {
74 printf("dataset_event_read: Event reaches "
75 "outside mapped region, clamping dataset.\n");
81 if (set
->size
- *offset
< sizeof(struct kmemtrace_event
)) {
82 panic("dataset_event_read: Not enough data\n");
85 if (d_ev
.event
->event_size
> sizeof(struct kmemtrace_event
)) {
86 d_ev
.extra
= set
->map
+ *offset
+
87 sizeof(struct kmemtrace_event
);
91 *offset
+= d_ev
.event
->event_size
;
96 int dataset_iter(struct dataset
*set
, int (*action
)(struct kmemtrace_event
*,
100 struct dataset_event d_ev
;
102 while (off
< set
->size
) {
103 d_ev
= dataset_event_read(set
, &off
);
106 if (action(d_ev
.event
, d_ev
.extra
))
113 static inline unsigned long
114 dataset_group_get_earliest(struct dataset_group
*group
)
118 for (i
= 0; i
< group
->count
; i
++) {
119 if (!group
->has_data
[i
])
125 if (group
->ds_event
[i
].event
->seq_num
<
126 group
->ds_event
[min
].event
->seq_num
)
131 group
->has_data
[min
] = 0;
136 /* Returns non-zero if interrupted / not completed. */
137 int dataset_iter_ordered(struct dataset_group
*group
,
138 int (*action
)(struct kmemtrace_event
*,
139 void *, unsigned long))
141 unsigned long i
, next
;
142 size_t *off
, prev_off
, tsize
= 0;
144 int have_expected
= 0;
149 off
= calloc(group
->count
, sizeof(size_t));
151 for (i
= 0; i
< group
->count
; i
++)
152 tsize
+= group
->dataset
[i
]->size
;
155 for (i
= 0; i
< group
->count
; i
++)
156 if (off
[i
] < group
->dataset
[i
]->size
&&
157 !group
->has_data
[i
]) {
160 dataset_event_read(group
->dataset
[i
],
162 if (group
->ds_event
[i
].event
)
163 group
->has_data
[i
] = 1;
164 tsize
-= off
[i
] - prev_off
;
167 next
= dataset_group_get_earliest(group
);
172 if (!have_expected
) {
174 expected
= group
->ds_event
[next
].event
->seq_num
+ 1;
176 if (expected
!= group
->ds_event
[next
].event
->seq_num
) {
177 printf("dataset_iter_ordered: Wrong sequence "
178 "number %d, expected %d.\n",
179 group
->ds_event
[next
].event
->seq_num
,
187 debug("Processing packet seq_num = %d from CPU %lu...\n",
188 group
->ds_event
[next
].event
->seq_num
- 1, next
);
190 if (action(group
->ds_event
[next
].event
,
191 group
->ds_event
[next
].extra
, next
)) {
202 struct dataset_group
*dataset_group_create(unsigned long count
)
204 struct dataset_group
*ret
;
206 ret
= malloc(sizeof(struct dataset_group
));
209 ret
->dataset
= calloc(count
, sizeof(struct dataset
*));
210 ret
->ds_event
= calloc(count
, sizeof(struct dataset_event
));
211 ret
->has_data
= calloc(count
, sizeof(int));
217 void dataset_group_destroy(struct dataset_group
*group
)
221 for (cpu
= 0; cpu
< group
->count
; cpu
++)
222 if (group
->dataset
[cpu
])
223 dataset_close(group
->dataset
[cpu
]);
224 free(group
->dataset
);
225 free(group
->ds_event
);
226 free(group
->has_data
);