1/*
2    Copyright (c) 2014 Intel Corporation.  All Rights Reserved.
3
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8      * Redistributions of source code must retain the above copyright
9        notice, this list of conditions and the following disclaimer.
10      * Redistributions in binary form must reproduce the above copyright
11        notice, this list of conditions and the following disclaimer in the
12        documentation and/or other materials provided with the distribution.
13      * Neither the name of Intel Corporation nor the names of its
14        contributors may be used to endorse or promote products derived
15        from this software without specific prior written permission.
16
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30
31#include "offload_trace.h"
32#include <stdio.h>
33#include <stdlib.h>
34#include <stdint.h>
35#include <sstream>
36#include "liboffload_error_codes.h"
37
38extern const char *prefix;
39
40#if !HOST_LIBRARY
41extern int mic_index;
42#endif
43
44// The debug routines
45
46static const char * offload_stage(std::stringstream &ss,
47                                  int offload_number,
48                                  const char *tag,
49                                  const char *text,
50                                  bool print_tag)
51{
52    ss << "[" << report_get_message_str(c_report_offload) << "]";
53#if HOST_LIBRARY
54    ss << " [" << prefix << "]";
55    if (print_tag) {
56        ss << "  [" << report_get_message_str(c_report_tag);
57        ss << " " << offload_number << "]";
58    }
59    else {
60        ss << "         ";
61    }
62    ss << " [" << tag << "]";
63    ss << "           " << text;
64#else
65    ss << " [" << prefix << " " << mic_index << "]";
66    if (print_tag) {
67        ss << " [" << report_get_message_str(c_report_tag);
68        ss << " " << offload_number << "]";
69    }
70    ss << " [" << tag << "]";
71    ss << "           " << text;
72#endif
73    return 0;
74}
75
76static const char * offload_signal(std::stringstream &ss,
77                                  int offload_number,
78                                  const char *tag,
79                                  const char *text)
80{
81    ss << "[" << report_get_message_str(c_report_offload) << "]";
82    ss << " [" << prefix << "]";
83    ss << "  [" << report_get_message_str(c_report_tag);
84    ss << " " << offload_number << "]";
85    ss << " [" << tag << "]";
86    ss << "          " << text;
87    return 0;
88}
89
90void offload_stage_print(int stage, int offload_number, ...)
91{
92    std::string buf;
93    std::stringstream ss;
94    char const *str1;
95    char const *str2;
96    va_list va_args;
97    va_start(va_args, offload_number);
98    va_arg(va_args, char*);
99
100    switch (stage) {
101        case c_offload_start:
102            str1 = report_get_message_str(c_report_state);
103            str2 = report_get_message_str(c_report_start);
104            offload_stage(ss, offload_number, str1, str2, true);
105            break;
106        case c_offload_init:
107            str1 = report_get_message_str(c_report_state);
108            str2 = report_get_message_str(c_report_init);
109            offload_stage(ss, offload_number, str1, str2, false);
110            ss << " " << report_get_message_str(c_report_logical_card);
111            ss << " " << va_arg(va_args, int);
112            ss << " = " << report_get_message_str(c_report_physical_card);
113            ss << " " << va_arg(va_args, int);
114            break;
115        case c_offload_register:
116            str1 = report_get_message_str(c_report_state);
117            str2 = report_get_message_str(c_report_register);
118            offload_stage(ss, offload_number, str1, str2, true);
119            break;
120        case c_offload_init_func:
121            str1 = report_get_message_str(c_report_state);
122            str2 = report_get_message_str(c_report_init_func);
123            offload_stage(ss, offload_number, str1, str2, true);
124            ss << ": " << va_arg(va_args, char*);
125            break;
126        case c_offload_create_buf_host:
127            str1 = report_get_message_str(c_report_state);
128            str2 = report_get_message_str(c_report_create_buf_host);
129            offload_stage(ss, offload_number, str1, str2, true);
130            ss << ": base=0x" << std::hex << va_arg(va_args, uint64_t);
131            ss << " length=" << std::dec << va_arg(va_args, uint64_t);
132            break;
133        case c_offload_create_buf_mic:
134            str1 = report_get_message_str(c_report_state);
135            str2 = report_get_message_str(c_report_create_buf_mic);
136            offload_stage(ss, offload_number, str1, str2, true);
137            ss << ": size=" << va_arg(va_args, uint64_t);
138            ss << " offset=" << va_arg(va_args, int);
139            if (va_arg(va_args,int))
140               ss << " (2M page)";
141            break;
142        case c_offload_send_pointer_data:
143            str1 = report_get_message_str(c_report_state);
144            str2 = report_get_message_str(c_report_send_pointer_data);
145            offload_stage(ss, offload_number, str1, str2, true);
146            break;
147        case c_offload_sent_pointer_data:
148            str1 = report_get_message_str(c_report_state);
149            str2 = report_get_message_str(c_report_sent_pointer_data);
150            offload_stage(ss, offload_number, str1, str2, true);
151            ss << " " << va_arg(va_args, uint64_t);
152            break;
153        case c_offload_gather_copyin_data:
154            str1 = report_get_message_str(c_report_state);
155            str2 = report_get_message_str(c_report_gather_copyin_data);
156            offload_stage(ss, offload_number, str1, str2, true);
157            break;
158        case c_offload_copyin_data:
159            str1 = report_get_message_str(c_report_state);
160            str2 = report_get_message_str(c_report_copyin_data);
161            offload_stage(ss, offload_number, str1, str2, true);
162            ss << " " << va_arg(va_args, uint64_t) << " ";
163            break;
164        case c_offload_compute:
165            str1 = report_get_message_str(c_report_state);
166            str2 = report_get_message_str(c_report_compute);
167            offload_stage(ss, offload_number, str1, str2, true);
168            break;
169        case c_offload_receive_pointer_data:
170            str1 = report_get_message_str(c_report_state);
171            str2 = report_get_message_str(c_report_receive_pointer_data);
172            offload_stage(ss, offload_number, str1, str2, true);
173            break;
174        case c_offload_received_pointer_data:
175            str1 = report_get_message_str(c_report_state);
176            str2 = report_get_message_str(c_report_received_pointer_data);
177            offload_stage(ss, offload_number, str1, str2, true);
178            ss << " " << va_arg(va_args, uint64_t);
179            break;
180        case c_offload_start_target_func:
181            str1 = report_get_message_str(c_report_state);
182            str2 = report_get_message_str(c_report_start_target_func);
183            offload_stage(ss, offload_number, str1, str2, true);
184            ss << ": " << va_arg(va_args, char*);
185            break;
186        case c_offload_var:
187            str1 = report_get_message_str(c_report_var);
188            offload_stage(ss, offload_number, str1, "  ", true);
189            va_arg(va_args, int);
190            ss << va_arg(va_args, char*);
191            ss << " " << " " << va_arg(va_args, char*);
192            break;
193        case c_offload_scatter_copyin_data:
194            str1 = report_get_message_str(c_report_state);
195            str2 = report_get_message_str(c_report_scatter_copyin_data);
196            offload_stage(ss, offload_number, str1, str2, true);
197            break;
198        case c_offload_gather_copyout_data:
199            str1 = report_get_message_str(c_report_state);
200            str2 = report_get_message_str(c_report_gather_copyout_data);
201            offload_stage(ss, offload_number, str1, str2, true);
202            break;
203        case c_offload_scatter_copyout_data:
204            str1 = report_get_message_str(c_report_state);
205            str2 = report_get_message_str(c_report_scatter_copyout_data);
206            offload_stage(ss, offload_number, str1, str2, true);
207            break;
208        case c_offload_copyout_data:
209            str1 = report_get_message_str(c_report_state);
210            str2 = report_get_message_str(c_report_copyout_data);
211            offload_stage(ss, offload_number, str1, str2, true);
212            ss << "   " << va_arg(va_args, uint64_t);
213            break;
214        case c_offload_signal:
215            {
216                uint64_t  *signal;
217                str1 = report_get_message_str(c_report_state_signal);
218                str2 = report_get_message_str(c_report_signal);
219                offload_signal(ss, offload_number, str1, str2);
220	        signal = va_arg(va_args, uint64_t*);
221	        if (signal)
222                   ss << " 0x" << std::hex << *signal;
223                else
224                   ss << " none";
225            }
226            break;
227        case c_offload_wait:
228            {
229                int count;
230                uint64_t  **signal;
231                str1 = report_get_message_str(c_report_state_signal);
232                str2 = report_get_message_str(c_report_wait);
233                offload_signal(ss, offload_number, str1, str2);
234                count = va_arg(va_args, int);
235                signal = va_arg(va_args, uint64_t**);
236                if (count) {
237                    while (count) {
238                        ss << " " << std::hex << signal[count-1];
239                        count--;
240                    }
241                }
242                else
243                    ss << " none";
244            }
245            break;
246        case c_offload_unregister:
247            str1 = report_get_message_str(c_report_state);
248            str2 = report_get_message_str(c_report_unregister);
249            offload_stage(ss, offload_number, str1, str2, false);
250            break;
251        case c_offload_destroy:
252            str1 = report_get_message_str(c_report_state);
253            str2 = report_get_message_str(c_report_destroy);
254            offload_stage(ss, offload_number, str1, str2, true);
255            break;
256        case c_offload_myoinit:
257            str1 = report_get_message_str(c_report_state);
258            str2 = report_get_message_str(c_report_myoinit);
259            offload_stage(ss, offload_number, str1, str2, false);
260            break;
261        case c_offload_myoregister:
262            str1 = report_get_message_str(c_report_state);
263            str2 = report_get_message_str(c_report_myoregister);
264            offload_stage(ss, offload_number, str1, str2, false);
265            break;
266        case c_offload_myofini:
267            str1 = report_get_message_str(c_report_state);
268            str2 = report_get_message_str(c_report_myofini);
269            offload_stage(ss, offload_number, str1, str2, false);
270            break;
271        case c_offload_mic_myo_shared:
272            str1 = report_get_message_str(c_report_state);
273            str2 = report_get_message_str(c_report_mic_myo_shared);
274            offload_stage(ss, offload_number, str1, str2, false);
275            ss << " " << va_arg(va_args, char*);
276            break;
277        case c_offload_mic_myo_fptr:
278            str1 = report_get_message_str(c_report_state);
279            str2 = report_get_message_str(c_report_mic_myo_fptr);
280            offload_stage(ss, offload_number, str1, str2, false);
281            ss << " " << va_arg(va_args, char*);
282            break;
283        case c_offload_myosharedmalloc:
284            str1 = report_get_message_str(c_report_state);
285            str2 = report_get_message_str(c_report_myosharedmalloc);
286            offload_stage(ss, offload_number, str1, str2, false);
287            va_arg(va_args, char*);
288            ss << " " << va_arg(va_args, size_t);
289            break;
290        case c_offload_myosharedfree:
291            str1 = report_get_message_str(c_report_state);
292            str2 = report_get_message_str(c_report_myosharedfree);
293            offload_stage(ss, offload_number, str1, str2, false);
294            break;
295        case c_offload_myosharedalignedmalloc:
296            str1 = report_get_message_str(c_report_state);
297            str2 = report_get_message_str(c_report_myosharedalignedmalloc);
298            offload_stage(ss, offload_number, str1, str2, false);
299            va_arg(va_args, char*);
300            ss << " " << va_arg(va_args, size_t);
301            ss << " " << va_arg(va_args, size_t);
302            break;
303        case c_offload_myosharedalignedfree:
304            str1 = report_get_message_str(c_report_state);
305            str2 = report_get_message_str(c_report_myosharedalignedfree);
306            offload_stage(ss, offload_number, str1, str2, false);
307            break;
308        case c_offload_myoacquire:
309            str1 = report_get_message_str(c_report_state);
310            str2 = report_get_message_str(c_report_myoacquire);
311            offload_stage(ss, offload_number, str1, str2, false);
312            break;
313        case c_offload_myorelease:
314            str1 = report_get_message_str(c_report_state);
315            str2 = report_get_message_str(c_report_myorelease);
316            offload_stage(ss, offload_number, str1, str2, false);
317            break;
318        default:
319            LIBOFFLOAD_ERROR(c_report_unknown_trace_node);
320            abort();
321    }
322    ss << "\n";
323    buf = ss.str();
324    fprintf(stdout, buf.data());
325    fflush(stdout);
326
327    va_end(va_args);
328    return;
329}
330