ebb22221f2b8cf3e2120508824e50b84cfb5ba45
[invirt/third/libt4.git] / threaded_log.h
1 #ifndef threaded_log_h
2 #define threaded_log_h
3
4 #include "types.h"
5
6 extern mutex cerr_mutex;
7 extern map<thread::id, int> thread_name_map;
8 extern int next_thread_num;
9 extern map<void *, int> instance_name_map;
10 extern int next_instance_num;
11 extern char log_thread_prefix;
12
13 namespace std {
14     // This... is an awful hack.  But sticking this in std:: makes it possible for
15     // ostream_iterator to use it.
16     template <class A, class B>
17     ostream & operator<<(ostream &o, const pair<A,B> &d) {
18         return o << "<" << d.first << "," << d.second << ">";
19     }
20 }
21
22 template <class A>
23 typename enable_if<is_iterable<A>::value && !is_same<A,string>::value, ostream>::type &
24 operator<<(ostream &o, const A &a) {
25     o << "[";
26     auto oit = ostream_iterator<typename A::value_type>(o, ", ");
27     copy(a.begin(), a.end(), oit);
28     o << "]";
29     return o;
30 }
31
32 #define LOG_PREFIX { \
33     auto _thread_ = std::this_thread::get_id(); \
34     int _tid_ = thread_name_map[_thread_]; \
35     if (_tid_==0) \
36         _tid_ = thread_name_map[_thread_] = ++next_thread_num; \
37     auto _utime_ = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count() % 1000000000; \
38     cerr << setfill('0') << dec << left << setw(9) << _utime_ << " "; \
39     cerr << setfill(' ') << log_thread_prefix << left << setw(2) << _tid_; \
40     cerr << " " << setw(20) << __FILE__ << " " << setw(18) << __func__; \
41 }
42 #define LOG_THIS_POINTER { \
43     int _self_ = instance_name_map[this]; \
44     if (_self_==0) \
45         _self_ = instance_name_map[this] = ++next_instance_num; \
46     cerr << "#" << setw(2) << _self_; \
47 }
48
49 #define LOG_NONMEMBER(_x_) { \
50     lock _cel_(cerr_mutex); \
51     LOG_PREFIX; \
52     cerr << _x_ << endl; \
53 }
54 #define LOG(_x_) { \
55     lock _cel_(cerr_mutex); \
56     LOG_PREFIX; \
57     LOG_THIS_POINTER; \
58     cerr << _x_ << endl; \
59 }
60
61 #endif