41539fe5c60add29ac122b02751232b437563865
[invirt/third/libt4.git] / tprintf.h
1 #ifndef tprintf_h
2 #define tprintf_h
3
4 #include <iomanip>
5 #include <iostream>
6 #include <stdio.h>
7 #include <map>
8 #include "lock.h"
9
10 extern mutex cerr_mutex;
11 extern std::map<std::thread::id, int> thread_name_map;
12 extern int next_thread_num;
13 extern std::map<void *, int> instance_name_map;
14 extern int next_instance_num;
15 extern char tprintf_thread_prefix;
16
17 template <class A>
18 struct iterator_pair : public std::pair<A, A> {
19     explicit iterator_pair(const A & first, const A & second) : std::pair<A, A>(first, second) {}
20 };
21
22 template <class A>
23 const struct iterator_pair<A> make_iterator_pair(const A & first, const A & second) {
24     return iterator_pair<A>(first, second);
25 }
26
27 template <class A, class B>
28 std::ostream & operator<<(std::ostream &o, const std::pair<A,B> &d) {
29     o << "<" << d.first << "," << d.second << ">";
30     return o;
31 }
32
33 template <class A>
34 std::ostream & operator<<(std::ostream &o, const iterator_pair<A> &d) {
35     o << "[";
36     for (auto i=d.first; i!=d.second; i++) {
37         o << *i;
38         auto j(i);
39         if (++j != d.second)
40             o << ", ";
41     }
42     o << "]";
43     return o;
44 }
45
46 #define LOG_PREFIX { \
47     cerr_mutex.lock(); \
48     auto _thread_ = std::this_thread::get_id(); \
49     int _tid_ = thread_name_map[_thread_]; \
50     if (_tid_==0) \
51         _tid_ = thread_name_map[_thread_] = ++next_thread_num; \
52     auto _utime_ = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 1000000000; \
53     std::cerr << std::setfill('0') << std::dec << std::left << std::setw(9) << _utime_ << " "; \
54     std::cerr << tprintf_thread_prefix << std::left << std::setw(2) << _tid_; \
55     std::cerr << " " << std::setw(20) << __FILE__ << " " << std::setw(18) << __func__; \
56 }
57 #define LOG_THIS_POINTER { \
58     int _self_ = instance_name_map[this]; \
59     if (_self_==0) \
60         _self_ = instance_name_map[this] = ++next_instance_num; \
61     std::cerr << "#" << std::setw(2) << _self_; \
62 }
63 #define LOG_SUFFIX { \
64     cerr_mutex.unlock(); \
65 }
66
67 #define LOG_NONMEMBER(_x_) { \
68     LOG_PREFIX; \
69     std::cerr << _x_ << std::endl; \
70     LOG_SUFFIX; \
71 }
72 #define LOG(_x_) { \
73     LOG_PREFIX; \
74     LOG_THIS_POINTER; \
75     std::cerr << _x_ << std::endl; \
76     LOG_SUFFIX; \
77 }
78 #define LOG_FUNC_ENTER { \
79     LOG_PREFIX; \
80     LOG_THIS_POINTER; \
81     std::cerr << "lid=" << lid; \
82     std::cerr << std::endl; \
83     LOG_SUFFIX; \
84 }
85 #define LOG_FUNC_ENTER_SERVER { \
86     LOG_PREFIX; \
87     LOG_THIS_POINTER; \
88     std::cerr << "lid=" << lid; \
89     std::cerr << " client=" << id << "," << xid; \
90     std::cerr << std::endl; \
91     LOG_SUFFIX; \
92 }
93 #define LOG_FUNC_EXIT { \
94     LOG_PREFIX; \
95     LOG_THIS_POINTER; \
96     std::cerr << "return" << lid; \
97     std::cerr << std::endl; \
98     LOG_SUFFIX; \
99 }
100
101 #define tprintf(...) { \
102     char *buf = nullptr; \
103     int len = asprintf(&buf, __VA_ARGS__); \
104     if (buf[len-1]=='\n') \
105         buf[len-1] = '\0'; \
106     LOG_NONMEMBER(buf); \
107     free(buf); \
108 }
109
110 #endif