Browse Source

Added categories to logging

Eyck Jentzsch 2 years ago
parent
commit
46d79504a8
8 changed files with 399 additions and 26 deletions
  1. 4
    3
      incl/sysc/memory.h
  2. 14
    7
      incl/sysc/report.h
  3. 52
    0
      incl/util/assert.h
  4. 72
    0
      incl/util/ities.h
  5. 50
    15
      incl/util/logging.h
  6. 87
    0
      incl/util/sparse_array.h
  7. 117
    0
      incl/util/thread_syncronizer.h
  8. 3
    1
      src/report.cpp

+ 4
- 3
incl/sysc/memory.h View File

@@ -27,6 +27,7 @@
27 27
 #define SC_INCLUDE_DYNAMIC_PROCESSES
28 28
 
29 29
 #include "utilities.h"
30
+#include <sysc/report.h>
30 31
 #include <tlm.h>
31 32
 #include <tlm_utils/simple_target_socket.h>
32 33
 
@@ -53,7 +54,7 @@ private:
53 54
 };
54 55
 
55 56
 template<unsigned SIZE, unsigned BUSWIDTH, bool LOG_ACCESS>
56
-memory<SIZE,BUSWIDTH,LOG_ACCESS>::memory(const sc_core::sc_module_name& nm):sc_module(nm),SOCKET(socket) {
57
+memory<SIZE,BUSWIDTH,LOG_ACCESS>::memory(const sc_core::sc_module_name& nm):sc_module(nm),NAMED(socket) {
57 58
     // Register callback for incoming b_transport interface method call
58 59
     socket.register_b_transport(this, &memory::b_transport);
59 60
     socket.register_transport_dbg(this, &memory::transport_dbg);
@@ -95,9 +96,9 @@ int memory<SIZE,BUSWIDTH,LOG_ACCESS>::handle_operation(tlm::tlm_generic_payload&
95 96
     tlm::tlm_command cmd = trans.get_command();
96 97
     if(LOG_ACCESS){
97 98
         if(adr>=0x20 && adr<0x60)
98
-            LOG(logging::warning)<<(cmd==tlm::TLM_READ_COMMAND?"read":"write")<<" access to addr 0x"<<std::hex<<adr-0x20<<"(0x"<<(adr)<<")"<<std::dec;
99
+            LOG(WARNING)<<(cmd==tlm::TLM_READ_COMMAND?"read":"write")<<" access to addr 0x"<<std::hex<<adr-0x20<<"(0x"<<(adr)<<")"<<std::dec;
99 100
         else
100
-            LOG(logging::warning)<<(cmd==tlm::TLM_READ_COMMAND?"read":"write")<<" access to addr 0x"<<std::hex<<adr<<std::dec;
101
+            LOG(WARNING)<<(cmd==tlm::TLM_READ_COMMAND?"read":"write")<<" access to addr 0x"<<std::hex<<adr<<std::dec;
101 102
     }
102 103
     if (cmd == tlm::TLM_READ_COMMAND)
103 104
         memcpy(ptr, mem + adr, len);

+ 14
- 7
incl/sysc/report.h View File

@@ -30,6 +30,9 @@
30 30
 #include <iomanip>
31 31
 
32 32
 
33
+namespace logging {
34
+struct SystemC {};
35
+}
33 36
 namespace sysc {
34 37
 
35 38
 namespace log=logging;
@@ -46,6 +49,11 @@ class Log: public logging::Log<T>{
46 49
 public:
47 50
     Log(){};
48 51
 
52
+
53
+    Log(const Log&) = delete;
54
+
55
+    Log& operator =(const Log&) = delete;
56
+
49 57
     /**
50 58
      *
51 59
      * @param level
@@ -63,7 +71,7 @@ public:
63 71
 
64 72
 };
65 73
 
66
-class FILELOG_DECLSPEC Logger : public Log<logging::Output2FILE> {
74
+class FILELOG_DECLSPEC Logger : public Log<logging::Output2FILE<log::SystemC>> {
67 75
     static std::once_flag once;
68 76
 public:
69 77
     /**
@@ -73,17 +81,16 @@ public:
73 81
      */
74 82
     static logging::log_level& reporting_level(){
75 83
         std::call_once(once, [](){ init_logging();});
76
-        return logging::Log<logging::Output2FILE>::reporting_level();
84
+        return logging::Log<logging::Output2FILE<log::SystemC>>::reporting_level();
77 85
     }
78 86
 };
79 87
 
80 88
 }
81 89
 
82 90
 #undef LOG
83
-#define LOG(level) \
84
-        if (level > FILELOG_MAX_LEVEL) ;\
85
-        else if (level > logging::Logger::reporting_level() || !logging::Output2FILE::stream()) ; \
86
-        else sysc::Logger().get(level)
87
-
91
+#define LOG(LEVEL) \
92
+        if (logging::LEVEL > FILELOG_MAX_LEVEL) ;\
93
+        else if (logging::LEVEL > LOGGER(SystemC)::reporting_level() || !LOG_OUTPUT(SystemC)::stream()) ; \
94
+        else LOGGER(SystemC)().get(logging::LEVEL)
88 95
 
89 96
 #endif /* _SYSC_REPORT_H_ */

+ 52
- 0
incl/util/assert.h View File

@@ -0,0 +1,52 @@
1
+/*******************************************************************************
2
+ * Copyright (C) 2017, MINRES Technologies GmbH
3
+ * All rights reserved.
4
+ * 
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * 
8
+ * 1. Redistributions of source code must retain the above copyright notice,
9
+ *    this list of conditions and the following disclaimer.
10
+ * 
11
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ *    this list of conditions and the following disclaimer in the documentation
13
+ *    and/or other materials provided with the distribution.
14
+ * 
15
+ * 3. Neither the name of the copyright holder nor the names of its contributors
16
+ *    may be used to endorse or promote products derived from this software
17
+ *    without specific prior written permission.
18
+ * 
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ * 
31
+ * Contributors:
32
+ *       eyck@minres.com - initial API and implementation
33
+ ******************************************************************************/
34
+
35
+#ifndef _ASSERT_H_
36
+#define _ASSERT_H_
37
+
38
+#include <util/logging.h>
39
+
40
+#ifndef NDEBUG
41
+#   define ASSERT(condition, message) \
42
+    do { \
43
+        if (! (condition)) { \
44
+        	LOG(FATAL) << "Assertion `" #condition "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
45
+            std::terminate(); \
46
+        } \
47
+    } while (false)
48
+#else
49
+#   define ASSERT(condition, message) do { } while (false)
50
+#endif
51
+
52
+#endif /* _ASSERT_H_ */

+ 72
- 0
incl/util/ities.h View File

@@ -0,0 +1,72 @@
1
+/*******************************************************************************
2
+ * Copyright (C) 2017, MINRES Technologies GmbH
3
+ * All rights reserved.
4
+ * 
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * 
8
+ * 1. Redistributions of source code must retain the above copyright notice,
9
+ *    this list of conditions and the following disclaimer.
10
+ * 
11
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ *    this list of conditions and the following disclaimer in the documentation
13
+ *    and/or other materials provided with the distribution.
14
+ * 
15
+ * 3. Neither the name of the copyright holder nor the names of its contributors
16
+ *    may be used to endorse or promote products derived from this software
17
+ *    without specific prior written permission.
18
+ * 
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ * 
31
+ * Contributors:
32
+ *       eyck@minres.com - initial API and implementation
33
+ ******************************************************************************/
34
+
35
+#ifndef _UTIL_ITIES_H_
36
+#define _UTIL_ITIES_H_
37
+
38
+#include <bitset>
39
+#include <type_traits>
40
+
41
+//some helper functions
42
+template<unsigned int bit, unsigned int width, typename T>
43
+inline constexpr T bit_sub(T v) {
44
+	return (v >> bit) & ((T(1) << width) - 1);
45
+}
46
+
47
+template<unsigned int bit, unsigned int width, typename T>
48
+inline constexpr typename std::make_signed<T>::type signed_bit_sub(T v) {
49
+	typename std::make_signed<T>::type r = v<<(sizeof(T)*8-bit-width);
50
+	typename std::make_signed<T>::type ret = (r >> (sizeof(T)*8-width));
51
+	return ret;
52
+}
53
+
54
+// according to http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
55
+static const int MultiplyDeBruijnBitPosition[32] =
56
+    {
57
+      0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
58
+      31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
59
+    };
60
+template<size_t N>
61
+constexpr size_t find_first(std::bitset<N>& bits){
62
+    static_assert(N<=32, "find_first only supports bitsets smaller than 33");
63
+    return MultiplyDeBruijnBitPosition[((uint32_t)((bits.to_ulong() & -bits.to_ulong()) * 0x077CB531U)) >> 27];
64
+}
65
+
66
+// according to https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation
67
+constexpr size_t bit_count(uint32_t u) {
68
+    size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
69
+    return ((uCount + (uCount >> 3)) & 030707070707) % 63;
70
+}
71
+
72
+#endif /* _UTIL_ITIES_H_ */

+ 50
- 15
incl/util/logging.h View File

@@ -42,6 +42,7 @@
42 42
 #include <cstring>
43 43
 #include <mutex>
44 44
 #include <stdio.h>
45
+#include <assert.h>
45 46
 #include <sys/time.h>
46 47
 
47 48
 #define LEVELS(L) L(NONE) L(FATAL) L(ERROR) L(WARNING) L(INFO) L(DEBUG) L(TRACE)
@@ -53,32 +54,51 @@ namespace logging {
53 54
 static const char * const buffer[] = { LEVELS(DO_DESCRIPTION)};
54 55
 enum log_level { LEVELS(DO_ENUM) };
55 56
 
57
+inline
58
+log_level as_log_level(int l){
59
+    assert(l>=NONE && l<=TRACE);
60
+    const log_level m[]={NONE,FATAL,ERROR,WARNING,INFO,DEBUG,TRACE};
61
+    return m[l];
62
+}
63
+
56 64
 inline std::string now_time();
57 65
 
58 66
 template <typename T>
59 67
 class Log{
60 68
 public:
61 69
 	Log(){};
70
+
71
+    Log(const Log&) = delete;
72
+
73
+    Log& operator =(const Log&) = delete;
74
+
62 75
     virtual ~Log(){
63 76
 		os << std::endl;
64 77
 		T::output(os.str());
65 78
 		//TODO: use a more specific exception
66 79
 		if(get_last_log_level() == FATAL) throw std::exception();
67
-	};
68
-    std::ostringstream& get(log_level level = INFO){
69
-		os << "- " << now_time();
70
-		os << " " << to_string(level) << ": ";
80
+	}
81
+
82
+    std::ostringstream& get(log_level level = INFO, const char* category=""){
83
+		if(print_time()) os << "- " << now_time();
84
+		if(print_severity()){
85
+		    os << " " << to_string(level);
86
+	        if(strlen(category)) os<<"/"<<category;
87
+	        os<< ": ";
88
+		}
71 89
 		get_last_log_level()=level;
72 90
 		return os;
73 91
 	};
74
-public:
92
+
75 93
     static log_level& reporting_level(){
76 94
 		static log_level reportingLevel = WARNING;
77 95
 		return reportingLevel;
78 96
 	}
97
+
79 98
     static std::string to_string(log_level level){
80 99
 		return std::string(get_log_level_cstr()[level]);
81 100
 	};
101
+
82 102
     static log_level from_string(const std::string& level) {
83 103
 		for(unsigned int i=NONE; i<=TRACE; i++)
84 104
 			if(!strncasecmp(level.c_str(), (const char*)(get_log_level_cstr()+i), strlen((const char*)get_log_level_cstr()+i))) return i;
@@ -86,6 +106,15 @@ public:
86 106
 		return INFO;
87 107
 	}
88 108
 
109
+    static bool& print_time(){
110
+        static bool flag=true;
111
+        return flag;
112
+    }
113
+
114
+    static bool& print_severity(){
115
+        static bool flag=true;
116
+        return flag;
117
+    }
89 118
 protected:
90 119
     log_level& get_last_log_level(){
91 120
 		static log_level level = TRACE;
@@ -95,12 +124,10 @@ protected:
95 124
 		return buffer;
96 125
 	};
97 126
     std::ostringstream os;
98
-private:
99
-    Log(const Log&);
100
-    Log& operator =(const Log&);
101 127
 };
102 128
 
103
-struct Output2FILE {
129
+template<typename CATEGORY>
130
+struct Output2FILE: CATEGORY {
104 131
     static FILE*& stream(){
105 132
 		static FILE* pStream = stderr;
106 133
 		return pStream;
@@ -114,6 +141,7 @@ struct Output2FILE {
114 141
 		fflush(pStream);
115 142
 	}
116 143
 };
144
+class DEFAULT {};
117 145
 
118 146
 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
119 147
 #   if defined (BUILDING_FILELOG_DLL)
@@ -127,17 +155,24 @@ struct Output2FILE {
127 155
 #   define FILELOG_DECLSPEC
128 156
 #endif // _WIN32
129 157
 
130
-class FILELOG_DECLSPEC Logger : public Log<Output2FILE> {};
131
-//typedef Log<Output2FILE> Logger;
132 158
 
133 159
 #ifndef FILELOG_MAX_LEVEL
134 160
 #define FILELOG_MAX_LEVEL logging::TRACE
135 161
 #endif
136 162
 
137
-#define LOG(level) \
138
-    if (level > FILELOG_MAX_LEVEL) ;\
139
-    else if (level > logging::Logger::reporting_level() || !logging::Output2FILE::stream()) ; \
140
-    else logging::Logger().get(level)
163
+#define LOGGER(CATEGORY) logging::Log<logging::Output2FILE<logging::CATEGORY>>
164
+#define LOG_OUTPUT(CATEGORY) logging::Output2FILE<logging::CATEGORY>
165
+
166
+#define LOG(LEVEL) \
167
+    if (logging::LEVEL > FILELOG_MAX_LEVEL) ;\
168
+    else if (logging::LEVEL > LOGGER(DEFAULT)::reporting_level() || !LOG_OUTPUT(DEFAULT)::stream()) ; \
169
+    else LOGGER(DEFAULT)().get(logging::LEVEL)
170
+
171
+#define CLOG(LEVEL, CATEGORY) \
172
+    if (logging::LEVEL > FILELOG_MAX_LEVEL) ;\
173
+    else if (logging::LEVEL > LOGGER(CATEGORY)::reporting_level() || !LOG_OUTPUT(CATEGORY)::stream()) ; \
174
+    else LOGGER(CATEGORY)().get(logging::LEVEL,#CATEGORY)
175
+
141 176
 
142 177
 #if defined(WIN32)
143 178
 

+ 87
- 0
incl/util/sparse_array.h View File

@@ -0,0 +1,87 @@
1
+/*******************************************************************************
2
+ * Copyright (C) 2017, MINRES Technologies GmbH
3
+ * All rights reserved.
4
+ * 
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * 
8
+ * 1. Redistributions of source code must retain the above copyright notice,
9
+ *    this list of conditions and the following disclaimer.
10
+ * 
11
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ *    this list of conditions and the following disclaimer in the documentation
13
+ *    and/or other materials provided with the distribution.
14
+ * 
15
+ * 3. Neither the name of the copyright holder nor the names of its contributors
16
+ *    may be used to endorse or promote products derived from this software
17
+ *    without specific prior written permission.
18
+ * 
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ * 
31
+ * Contributors:
32
+ *       eyck@minres.com - initial API and implementation
33
+ ******************************************************************************/
34
+
35
+#ifndef _SPARSE_ARRAY_H_
36
+#define _SPARSE_ARRAY_H_
37
+
38
+#include <array>
39
+#include <cassert>
40
+
41
+namespace util {
42
+
43
+/**
44
+ *  a simple array which allocates memory in 16MB chunks
45
+ */
46
+template<typename T, uint64_t SIZE, int lower_width=24>
47
+struct sparse_array {
48
+
49
+	const uint64_t page_addr_mask = (1<<lower_width)-1;
50
+
51
+	const uint64_t page_size = (1<<lower_width);
52
+
53
+	const uint64_t page_addr_width = lower_width;
54
+
55
+	using page_type=std::array<T,1<<lower_width>;
56
+
57
+
58
+	sparse_array(){
59
+		arr.fill(nullptr);
60
+	}
61
+
62
+	~sparse_array(){
63
+		for(auto i:arr) delete i;
64
+	}
65
+
66
+	T& operator[](uint32_t addr) {
67
+		assert(addr<SIZE);
68
+		T nr = addr>>lower_width;
69
+		if(arr[nr] == nullptr) arr[nr]= new page_type();
70
+		return arr[nr]->at(addr & page_addr_mask);
71
+	}
72
+
73
+	page_type& operator()(uint32_t page_nr) {
74
+		assert(page_nr<(SIZE/(1<<lower_width)));
75
+		if(arr[page_nr] == nullptr) arr[page_nr]= new page_type();
76
+		return *(arr[page_nr]);
77
+	}
78
+
79
+	uint64_t size(){return SIZE;}
80
+
81
+protected:
82
+	std::array<page_type*, SIZE/(1<<lower_width)+1> arr;
83
+};
84
+
85
+}
86
+
87
+#endif /* _SPARSE_ARRAY_H_ */

+ 117
- 0
incl/util/thread_syncronizer.h View File

@@ -0,0 +1,117 @@
1
+/*******************************************************************************
2
+ * Copyright (C) 2017, MINRES Technologies GmbH
3
+ * All rights reserved.
4
+ * 
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * 
8
+ * 1. Redistributions of source code must retain the above copyright notice,
9
+ *    this list of conditions and the following disclaimer.
10
+ * 
11
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ *    this list of conditions and the following disclaimer in the documentation
13
+ *    and/or other materials provided with the distribution.
14
+ * 
15
+ * 3. Neither the name of the copyright holder nor the names of its contributors
16
+ *    may be used to endorse or promote products derived from this software
17
+ *    without specific prior written permission.
18
+ * 
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ * POSSIBILITY OF SUCH DAMAGE.
30
+ * 
31
+ * Contributors:
32
+ *       eyck@minres.com - initial API and implementation
33
+ ******************************************************************************/
34
+#ifndef _THREAD_SYNCRONIZER_H_
35
+#define _THREAD_SYNCRONIZER_H_
36
+
37
+
38
+#include <queue>
39
+#include <atomic>
40
+#include <future>
41
+#include <functional>
42
+#include <stdexcept>
43
+
44
+class thread_syncronizer {
45
+private:
46
+	std::queue< std::function< void() > > tasks_;
47
+	std::atomic<bool> ready;
48
+	std::mutex mutex_;
49
+	std::condition_variable condition_;
50
+public:
51
+	/// @brief Constructor.
52
+	thread_syncronizer() { }
53
+
54
+	/// @brief Destructor.
55
+	~thread_syncronizer(){
56
+		// Set running flag to false then notify all threads.
57
+		condition_.notify_all();
58
+	}
59
+
60
+	bool is_ready(){return ready.load(std::memory_order_acquire);}
61
+
62
+	template<class F, class... Args>
63
+	typename std::result_of<F(Args...)>::type enqueue_and_wait(F&& f, Args&&... args) {
64
+		auto res = enqueue(f, args...);
65
+		res.wait();
66
+		return res.get();
67
+	}
68
+
69
+
70
+	template<class F, class... Args>
71
+	auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
72
+	    using return_type = typename std::result_of<F(Args...)>::type;
73
+	    auto task = std::make_shared< std::packaged_task<return_type()> >(
74
+	            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
75
+	        );
76
+
77
+	    std::future<return_type> res = task->get_future();
78
+	    {
79
+	        std::unique_lock<std::mutex> lock(mutex_);
80
+	        tasks_.emplace([task](){ (*task)(); });
81
+	    }
82
+	    condition_.notify_one();
83
+	    return res;
84
+	}
85
+	/// @brief execute the next task in queue but do not wait for the next one
86
+	void execute(){
87
+		if(tasks_.empty()) return ;
88
+		{
89
+			std::unique_lock< std::mutex > lock( mutex_ );
90
+			// Copy task locally and remove from the queue. This is done within
91
+			// its own scope so that the task object is destructed immediately
92
+			// after running the task.  This is useful in the event that the
93
+			// function contains shared_ptr arguments bound via bind.
94
+			std::function< void() > functor = tasks_.front();
95
+			tasks_.pop();
96
+			lock.unlock();
97
+			// Run the task.
98
+			try{
99
+				functor();
100
+			}  catch ( ... ) {} // Suppress all exceptions.
101
+		}
102
+	}
103
+
104
+	/// @brief execute the next task in queue or wait for the next one
105
+	void executeNext(){
106
+        ready.store(true, std::memory_order_release);
107
+		// Wait on condition variable while the task is empty
108
+		std::unique_lock< std::mutex > lock( mutex_ );
109
+		while ( tasks_.empty() && ready.load(std::memory_order_acquire)){
110
+			condition_.wait_for(lock, std::chrono::milliseconds(10));
111
+		}
112
+		lock.unlock();
113
+		execute();
114
+		ready.store(false, std::memory_order_release);
115
+	}
116
+};
117
+#endif /* _THREAD_SYNCRONIZER_H_ */

+ 3
- 1
src/report.cpp View File

@@ -52,7 +52,9 @@ static const std::string compose_message(const sc_report& rep){
52 52
 static void report_handler(const sc_report& rep, const sc_actions& actions){
53 53
     const logging::log_level map[] = {logging::INFO, logging::WARNING, logging::ERROR, logging::FATAL};
54 54
     if ( actions & SC_DISPLAY )
55
-        LOG(map[rep.get_severity()]) << compose_message(rep);
55
+        if (map[rep.get_severity()] > FILELOG_MAX_LEVEL) ;\
56
+        else if (map[rep.get_severity()] > LOGGER(SystemC)::reporting_level() || !LOG_OUTPUT(SystemC)::stream()) ; \
57
+        else LOGGER(SystemC)().get(map[rep.get_severity()])<< compose_message(rep);
56 58
     //    if ( (actions & SC_LOG) && log_file_name ) {
57 59
     //        if ( !log_stream ) log_stream = new ::std::ofstream(log_file_name); // ios::trunc
58 60
     //        *log_stream << rep.get_time() << ": " << my_report_compose_message(rep) << ::std::endl;