Commit | Line | Data |
---|---|---|
68c1021b PMF |
1 | #include <stdio.h> |
2 | #include <unistd.h> | |
b6bf28ec | 3 | #include <sys/mman.h> |
9c67dc50 PMF |
4 | #include <stdarg.h> |
5 | #include <sys/types.h> | |
6 | #include <sys/stat.h> | |
7 | #include <fcntl.h> | |
68c1021b | 8 | |
59b161cd | 9 | #include "../libmarkers/marker.h" |
5f54827b PMF |
10 | #include "usterr.h" |
11 | #include "tracer.h" | |
ba6459ba | 12 | #include "marker-control.h" |
9c67dc50 PMF |
13 | #include "relay.h" |
14 | ||
15 | ||
16 | char consumer_stack[10000]; | |
9c67dc50 PMF |
17 | |
18 | #define CPRINTF(fmt, args...) safe_printf(fmt "\n", ## args) | |
19 | ||
20 | int safe_printf(const char *fmt, ...) | |
21 | { | |
22 | static char buf[500]; | |
23 | va_list ap; | |
24 | int n; | |
25 | ||
26 | va_start(ap, fmt); | |
27 | ||
28 | n = vsnprintf(buf, sizeof(buf), fmt, ap); | |
29 | ||
30 | write(STDOUT_FILENO, buf, n); | |
31 | ||
32 | va_end(ap); | |
33 | } | |
34 | ||
98963de4 PMF |
35 | struct consumer_channel { |
36 | int fd; | |
37 | struct ltt_channel_struct *chan; | |
38 | }; | |
39 | ||
9c67dc50 PMF |
40 | int consumer(void *arg) |
41 | { | |
42 | int result; | |
9c67dc50 | 43 | int fd; |
9c67dc50 | 44 | char str[] = "Hello, this is the consumer.\n"; |
9c67dc50 | 45 | struct ltt_trace_struct *trace; |
98963de4 PMF |
46 | struct consumer_channel *consumer_channels; |
47 | int i; | |
4db647c5 | 48 | char trace_name[] = "auto"; |
9c67dc50 PMF |
49 | |
50 | ltt_lock_traces(); | |
51 | trace = _ltt_trace_find(trace_name); | |
52 | ltt_unlock_traces(); | |
53 | ||
54 | if(trace == NULL) { | |
55 | CPRINTF("cannot find trace!"); | |
56 | return 1; | |
57 | } | |
58 | ||
98963de4 | 59 | consumer_channels = (struct consumer_channel *) malloc(trace->nr_channels * sizeof(struct consumer_channel)); |
fbd8191b | 60 | if(consumer_channels == NULL) { |
98963de4 PMF |
61 | ERR("malloc returned NULL"); |
62 | return 1; | |
63 | } | |
9c67dc50 | 64 | |
98963de4 PMF |
65 | CPRINTF("opening trace files"); |
66 | for(i=0; i<trace->nr_channels; i++) { | |
67 | char tmp[100]; | |
68 | struct ltt_channel_struct *chan = &trace->channels[i]; | |
9c67dc50 | 69 | |
98963de4 | 70 | consumer_channels[i].chan = chan; |
9c67dc50 | 71 | |
98963de4 PMF |
72 | snprintf(tmp, sizeof(tmp), "trace/%s", chan->channel_name); |
73 | result = consumer_channels[i].fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 00644); | |
74 | if(result == -1) { | |
75 | perror("open"); | |
76 | return -1; | |
77 | } | |
78 | CPRINTF("\topened trace file %s", tmp); | |
79 | ||
9c67dc50 | 80 | } |
98963de4 | 81 | CPRINTF("done opening trace files"); |
9c67dc50 PMF |
82 | |
83 | for(;;) { | |
98963de4 PMF |
84 | /*wait*/ |
85 | ||
86 | for(i=0; i<trace->nr_channels; i++) { | |
87 | struct rchan *rchan = consumer_channels[i].chan->trans_channel_data; | |
88 | struct rchan_buf *rbuf = rchan->buf; | |
89 | struct ltt_channel_buf_struct *lttbuf = consumer_channels[i].chan->buf; | |
90 | long consumed_old; | |
91 | ||
92 | result = ltt_do_get_subbuf(rbuf, lttbuf, &consumed_old); | |
93 | if(result < 0) { | |
94 | CPRINTF("ltt_do_get_subbuf: error: %s", strerror(-result)); | |
95 | } | |
96 | else { | |
97 | CPRINTF("success!"); | |
98 | ||
99 | result = write(consumer_channels[i].fd, rbuf->buf_data + (consumed_old & (2 * 4096-1)), 4096); | |
100 | ltt_do_put_subbuf(rbuf, lttbuf, consumed_old); | |
101 | } | |
9c67dc50 | 102 | } |
9c67dc50 PMF |
103 | |
104 | sleep(1); | |
105 | } | |
98963de4 PMF |
106 | |
107 | // CPRINTF("consumer: got a trace: %s with %d channels\n", trace_name, trace->nr_channels); | |
108 | // | |
109 | // struct ltt_channel_struct *chan = &trace->channels[0]; | |
110 | // | |
111 | // CPRINTF("channel 1 (%s) active=%u", chan->channel_name, chan->active & 1); | |
112 | ||
113 | // struct rchan *rchan = chan->trans_channel_data; | |
114 | // struct rchan_buf *rbuf = rchan->buf; | |
115 | // struct ltt_channel_buf_struct *lttbuf = chan->buf; | |
116 | // long consumed_old; | |
117 | // | |
118 | // result = fd = open("trace.out", O_WRONLY | O_CREAT | O_TRUNC, 00644); | |
119 | // if(result == -1) { | |
120 | // perror("open"); | |
121 | // return -1; | |
122 | // } | |
123 | ||
124 | // for(;;) { | |
125 | // write(STDOUT_FILENO, str, sizeof(str)); | |
126 | // | |
127 | // result = ltt_do_get_subbuf(rbuf, lttbuf, &consumed_old); | |
128 | // if(result < 0) { | |
129 | // CPRINTF("ltt_do_get_subbuf: error: %s", strerror(-result)); | |
130 | // } | |
131 | // else { | |
132 | // CPRINTF("success!"); | |
133 | // | |
134 | // result = write(fd, rbuf->buf_data + (consumed_old & (2 * 4096-1)), 4096); | |
135 | // ltt_do_put_subbuf(rbuf, lttbuf, consumed_old); | |
136 | // } | |
137 | // | |
138 | // //CPRINTF("There seems to be %ld bytes available", SUBBUF_TRUNC(local_read(<tbuf->offset), rbuf->chan) - consumed_old); | |
139 | // CPRINTF("Commit count %ld", local_read(<tbuf->commit_count[0])); | |
140 | // | |
141 | // | |
142 | // sleep(1); | |
143 | // } | |
9c67dc50 PMF |
144 | } |
145 | ||
146 | void start_consumer(void) | |
147 | { | |
148 | int result; | |
149 | ||
fbd8191b | 150 | result = clone(consumer, consumer_stack+sizeof(consumer_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD, NULL); |
9c67dc50 PMF |
151 | if(result == -1) { |
152 | perror("clone"); | |
153 | } | |
154 | } | |
59b161cd PMF |
155 | |
156 | void probe(const struct marker *mdata, | |
157 | void *probe_private, void *call_private, | |
158 | const char *fmt, va_list *args) | |
159 | { | |
160 | printf("In probe\n"); | |
161 | } | |
162 | ||
8d938dbd PMF |
163 | void inthandler(int sig) |
164 | { | |
165 | printf("in handler\n"); | |
166 | exit(0); | |
167 | } | |
168 | ||
169 | int init_int_handler(void) | |
170 | { | |
171 | int result; | |
172 | struct sigaction act; | |
173 | ||
174 | result = sigemptyset(&act.sa_mask); | |
175 | if(result == -1) { | |
176 | PERROR("sigemptyset"); | |
177 | return -1; | |
178 | } | |
179 | ||
180 | act.sa_handler = inthandler; | |
181 | act.sa_flags = SA_RESTART; | |
182 | ||
183 | /* Only defer ourselves. Also, try to restart interrupted | |
184 | * syscalls to disturb the traced program as little as possible. | |
185 | */ | |
186 | result = sigaction(SIGINT, &act, NULL); | |
187 | if(result == -1) { | |
188 | PERROR("sigaction"); | |
189 | return -1; | |
190 | } | |
191 | ||
192 | return 0; | |
193 | } | |
194 | ||
5f54827b | 195 | int main() |
b6bf28ec | 196 | { |
5f54827b | 197 | int result; |
98963de4 | 198 | int i; |
5f54827b | 199 | |
8d938dbd PMF |
200 | init_int_handler(); |
201 | ||
9c67dc50 | 202 | start_consumer(); |
68c1021b | 203 | printf("Hello, World!\n"); |
59b161cd | 204 | |
9c67dc50 | 205 | sleep(1); |
98963de4 | 206 | for(i=0; i<50; i++) { |
aafb1650 PMF |
207 | trace_mark(foo, bar, "str %s", "FOOBAZ"); |
208 | trace_mark(foo, bar2, "number1 %d number2 %d", 53, 9800); | |
9c67dc50 | 209 | usleep(100000); |
8d938dbd | 210 | } |
59b161cd | 211 | |
68c1021b PMF |
212 | scanf("%*s"); |
213 | ||
214 | return 0; | |
215 | } | |
c463904d PMF |
216 | |
217 | MARKER_LIB |