Partially fixed a bug in the test suite that led to test runs randomly failing.
[invirt/third/libt4.git] / threaded_log.h
index 6918220..6630a86 100644 (file)
 #ifndef threaded_log_h
 #define threaded_log_h
 
-#include <iomanip>
-#include <iostream>
-#include <stdio.h>
-#include <map>
-#include "lock.h"
+#include "types.h"
 
 extern mutex cerr_mutex;
-extern std::map<std::thread::id, int> thread_name_map;
+extern map<thread::id, int> thread_name_map;
 extern int next_thread_num;
-extern std::map<void *, int> instance_name_map;
+extern map<void *, int> instance_name_map;
 extern int next_instance_num;
 extern char log_thread_prefix;
 
-template <class A>
-struct iterator_pair : public std::pair<A, A> {
-    explicit iterator_pair(const A & first, const A & second) : std::pair<A, A>(first, second) {}
-};
-
-template <class A>
-const struct iterator_pair<A> make_iterator_pair(const A & first, const A & second) {
-    return iterator_pair<A>(first, second);
-}
-
-template <class A, class B>
-std::ostream & operator<<(std::ostream &o, const std::pair<A,B> &d) {
-    o << "<" << d.first << "," << d.second << ">";
-    return o;
+namespace std {
+    // Sticking this in std:: makes it possible for ostream_iterator to use it.
+    template <class A, class B>
+    ostream & operator<<(ostream &o, const pair<A,B> &d) {
+        return o << "<" << d.first << "," << d.second << ">";
+    }
 }
 
 template <class A>
-std::ostream & operator<<(std::ostream &o, const iterator_pair<A> &d) {
-    o << "[";
-    for (auto i=d.first; i!=d.second; i++) {
-        o << *i;
-        auto j(i);
-        if (++j != d.second)
-            o << ", ";
-    }
-    o << "]";
-    return o;
+typename enable_if<is_const_iterable<A>::value && !is_same<A,string>::value, ostream>::type &
+operator<<(ostream &o, const A &a) {
+    return o << "[" << implode(a, ", ") << "]";
 }
 
 #define LOG_PREFIX { \
-    cerr_mutex.lock(); \
-    auto _thread_ = std::this_thread::get_id(); \
+    auto _thread_ = this_thread::get_id(); \
     int _tid_ = thread_name_map[_thread_]; \
     if (_tid_==0) \
         _tid_ = thread_name_map[_thread_] = ++next_thread_num; \
-    auto _utime_ = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 1000000000; \
-    std::cerr << std::setfill('0') << std::dec << std::left << std::setw(9) << _utime_ << " "; \
-    std::cerr << std::setfill(' ') << log_thread_prefix << std::left << std::setw(2) << _tid_; \
-    std::cerr << " " << std::setw(20) << __FILE__ << " " << std::setw(18) << __func__; \
+    auto _utime_ = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count() % 1000000000; \
+    cerr << setfill('0') << dec << left << setw(9) << _utime_ << " "; \
+    cerr << setfill(' ') << log_thread_prefix << left << setw(2) << _tid_; \
+    cerr << " " << setw(20) << __FILE__ << " " << setw(18) << __func__; \
 }
 #define LOG_THIS_POINTER { \
     int _self_ = instance_name_map[this]; \
     if (_self_==0) \
         _self_ = instance_name_map[this] = ++next_instance_num; \
-    std::cerr << "#" << std::setw(2) << _self_; \
-}
-#define LOG_SUFFIX { \
-    cerr_mutex.unlock(); \
+    cerr << "#" << left << setw(2) << _self_ << " "; \
 }
 
 #define LOG_NONMEMBER(_x_) { \
+    lock _cel_(cerr_mutex); \
     LOG_PREFIX; \
-    std::cerr << _x_ << std::endl; \
-    LOG_SUFFIX; \
+    cerr << _x_ << endl; \
 }
 #define LOG(_x_) { \
+    lock _cel_(cerr_mutex); \
     LOG_PREFIX; \
     LOG_THIS_POINTER; \
-    std::cerr << _x_ << std::endl; \
-    LOG_SUFFIX; \
-}
-#define LOG_FUNC_ENTER { \
-    LOG_PREFIX; \
-    LOG_THIS_POINTER; \
-    std::cerr << "lid=" << lid; \
-    std::cerr << std::endl; \
-    LOG_SUFFIX; \
-}
-#define LOG_FUNC_ENTER_SERVER { \
-    LOG_PREFIX; \
-    LOG_THIS_POINTER; \
-    std::cerr << "lid=" << lid; \
-    std::cerr << " client=" << id << "," << xid; \
-    std::cerr << std::endl; \
-    LOG_SUFFIX; \
-}
-#define LOG_FUNC_EXIT { \
-    LOG_PREFIX; \
-    LOG_THIS_POINTER; \
-    std::cerr << "return" << lid; \
-    std::cerr << std::endl; \
-    LOG_SUFFIX; \
+    cerr << _x_ << endl; \
 }
 
+extern int DEBUG_LEVEL;
+
+#define IF_LEVEL(level) if(DEBUG_LEVEL >= abs(level))
+
 #endif