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