TAS
TCP Acceleration as an OS Service
trace.c
1 /*
2  * Copyright 2019 University of Washington, Max Planck Institute for
3  * Software Systems, and The University of Texas at Austin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <stdio.h>
26 #include <assert.h>
27 
28 #include <tas_trace.h>
29 #include <utils.h>
30 #include "internal.h"
31 
32 #ifdef FLEXNIC_TRACING
33 
34 struct trace {
35  struct flexnic_trace_header *hdr;
36  void *base;
37  size_t len;
38  size_t pos;
39  uint32_t seq;
40 };
41 
42 static __thread struct trace *trace;
43 
44 static inline void copy_to_pos(struct trace *t, size_t pos, size_t len,
45  const void *src);
46 
47 int trace_thread_init(uint16_t id)
48 {
49  struct trace *t;
50  char name[64];
51 
52  t = trace;
53  if (t != NULL) {
54  fprintf(stderr, "trace_thread_init: trace already initialized for "
55  "thread\n");
56  return -1;
57  }
58 
59  if ((t = malloc(sizeof(*t))) == NULL) {
60  fprintf(stderr, "trace_thread_init: malloc failed\n");
61  return -1;
62  }
63 
64  snprintf(name, sizeof(name), FLEXNIC_TRACE_NAME, id);
65  if ((t->hdr = util_create_shmsiszed(name, FLEXNIC_TRACE_LEN, NULL))
66  == NULL)
67  {
68  free(t);
69  return -1;
70  }
71 
72  t->base = t->hdr + 1;
73  t->len = FLEXNIC_TRACE_LEN - sizeof(*t->hdr);
74  t->pos = 0;
75  t->seq = 0;
76 
77  t->hdr->end_last = 0;
78  t->hdr->length = t->len;
79 
80  trace = t;
81  return 0;
82 }
83 
84 int trace_event(uint16_t type, uint16_t len, const void *buf)
85 {
86  return trace_event2(type, len, buf, 0, NULL);
87 }
88 
89 int trace_event2(uint16_t type, uint16_t len_1, const void *buf_1,
90  uint16_t len_2, const void *buf_2)
91 {
92  struct flexnic_trace_entry_head teh;
93  struct flexnic_trace_entry_tail tet;
94  struct timespec ts;
95  struct trace *t;
96  uint64_t newpos;
97  uint16_t len = len_1 + len_2;
98 
99  t = trace;
100  if (t == NULL) {
101  fprintf(stderr, "trace_event: thread trace not initialized yet\n");
102  return -1;
103  }
104 
105  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
106  fprintf(stderr, "trace_event: clock_gettime failed\n");
107  return -1;
108  }
109 
110  teh.ts = (uint64_t) ts.tv_sec * 1000000000ULL + ts.tv_nsec;
111  teh.seq = t->seq++;
112  teh.type = type;
113  teh.length = len;
114  tet.length = len;
115 
116  copy_to_pos(t, t->pos, sizeof(teh), &teh);
117  copy_to_pos(t, t->pos + sizeof(teh), len_1, buf_1);
118  if (len_2 > 0) {
119  copy_to_pos(t, t->pos + sizeof(teh) + len_1, len_2, buf_2);
120  }
121  copy_to_pos(t, t->pos + sizeof(teh) + len, sizeof(tet), &tet);
122 
123  newpos = t->pos + len + sizeof(teh) + sizeof(tet);
124  if (newpos >= t->len) {
125  newpos -= t->len;
126  }
127  t->pos = newpos;
128  MEM_BARRIER();
129  t->hdr->end_last = newpos;
130 
131  return 0;
132 }
133 
134 static inline void copy_to_pos(struct trace *t, size_t pos, size_t len,
135  const void *src)
136 {
137  size_t first;
138 
139  if (pos >= t->len) {
140  pos -= t->len;
141  }
142  assert(pos < t->len);
143 
144  if (pos + len <= t->len) {
145  memcpy((uint8_t *) t->base + pos, src, len);
146  } else {
147  first = t->len - pos;
148  memcpy((uint8_t *) t->base + pos, src, first);
149  memcpy(t->base, (uint8_t *) src + first, len - first);
150  }
151 }
152 #endif
Definition: tas_trace.h:51
Definition: tas_trace.h:44