Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00013 #ifndef SYNC_TASK_H
00014 #define SYNC_TASK_H
00015
00016
00017 #define SC_CALL_USES_ASYNC_REQUEST_UPDATE
00018
00019 #include <systemc>
00020 #include <boost/thread.hpp>
00021 #include "utils/io-lock.h"
00022 #ifdef SC_CALL_USES_ASYNC_REQUEST_UPDATE
00023 #include "async-event-queue.h"
00024 #endif
00025
00026 class sync_task {
00027 private:
00028 sync_task(const sync_task &) {};
00029
00030 private:
00043 bool wait_task(sc_core::sc_time &remaining_time) {
00044 boost::unique_lock<boost::mutex> lock(m_mutex);
00045 while ((!m_done)
00046 && m_remaining_time == sc_core::SC_ZERO_TIME
00047 && m_sc_function.empty())
00048 m_cond_systemc.wait(lock);
00049 if (!m_sc_function.empty()) {
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 lock.unlock();
00063 m_sc_function();
00064
00065 lock.lock();
00066 m_sc_function = NULL;
00067 m_sc_function_executed.notify_one();
00068 }
00069
00070
00071
00072
00073
00074
00075 remaining_time = m_remaining_time - m_catch_up_time;
00076 return m_done;
00077 }
00078
00079 private:
00084 void consume_remaining_time(sc_core::sc_time &remaining_time) {
00085
00086
00087
00088 D_COUT << "// TEST-IGNORE: Remaining time to consume: "
00089 << remaining_time << std::endl;
00090
00091
00092
00093
00094
00095 #ifdef SC_CALL_USES_ASYNC_REQUEST_UPDATE
00096 sc_core::sc_time before = sc_core::sc_time_stamp();
00097 sc_core::wait(remaining_time, m_systemc_synchro_ev);
00098 const sc_core::sc_time &time_waited = sc_core::sc_time_stamp() - before;
00099 #else
00100 sc_core::wait(remaining_time);
00101 const sc_core::sc_time &time_waited = remaining_time;
00102 #endif
00103 {
00104 boost::unique_lock<boost::mutex> lock(m_mutex);
00105 m_remaining_time -= time_waited;
00106 }
00107 m_cond_catch_up.notify_one();
00108 }
00109
00110 public:
00122 sync_task(const boost::function<void()> & routine,
00123 const sc_core::sc_time & t = sc_core::SC_ZERO_TIME)
00124 : m_routine(routine),
00125 m_done(false),
00126 m_remaining_time(t),
00127 m_catch_up_time(sc_core::SC_ZERO_TIME)
00128 {};
00129
00139 void wait_for_completion() {
00140 sc_core::sc_time remaining_time;
00141 bool done;
00142 do {
00143 done = this->wait_task(remaining_time);
00144 consume_remaining_time(remaining_time);
00145
00146
00147
00148
00149 } while (!done);
00150 }
00151
00164 void extra_time(const sc_core::sc_time & t) {
00165 {
00166 boost::unique_lock<boost::mutex> lock(m_mutex);
00167 m_remaining_time += t;
00168 }
00169 D_COUT << "// TEST-IGNORE: extra_time(" << t << ") => "
00170 << m_remaining_time << std::endl;
00171 m_cond_systemc.notify_one();
00172 }
00173
00182 void catch_up(const sc_core::sc_time & t) {
00183 boost::unique_lock<boost::mutex> lock(m_mutex);
00184 m_catch_up_time = t;
00185
00186
00187
00188
00189
00190
00191 D_COUT << "// TEST-IGNORE: entering catch up (" << t << ")" << std::endl;
00192
00193 while (!(m_remaining_time <= m_catch_up_time)) {
00194 m_cond_catch_up.wait(lock);
00195 }
00196 m_catch_up_time = sc_core::SC_ZERO_TIME;
00197 D_COUT << "// TEST-IGNORE: leaving catch up" << std::endl;
00198 }
00199
00208 void sc_call(const boost::function<void()> & f) {
00209 boost::unique_lock<boost::mutex> lock(m_mutex);
00210 m_sc_function = f;
00211 #ifdef SC_CALL_USES_ASYNC_REQUEST_UPDATE
00212
00213
00214
00215 m_async_event_queue.async_notify_event(m_systemc_synchro_ev);
00216 #endif
00217 m_cond_systemc.notify_one();
00218 do {
00219 D_COUT << "// TEST-IGNORE: sc_call: wait(lock) id = "
00220 << boost::this_thread::get_id() << std::endl;
00221 m_sc_function_executed.wait(lock);
00222 } while (!m_sc_function.empty());
00223 }
00224
00235 void process() {
00236 m_routine();
00237 {
00238 boost::unique_lock<boost::mutex> lock(m_mutex);
00239 m_done = true;
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 m_cond_systemc.notify_one();
00250 }
00251 }
00254 public:
00264 void wait_nosc() {
00265 sc_core::sc_time time;
00266 bool done = wait_task(time);
00267 (void)done;
00268 assert(done == true);
00269 assert(time == sc_core::SC_ZERO_TIME);
00270 }
00273 private:
00274 boost::function<void()> m_routine;
00275
00279 bool m_done;
00280 sc_core::sc_time m_remaining_time;
00282 boost::condition_variable m_cond_systemc;
00284 boost::mutex m_mutex;
00285
00289 boost::condition_variable m_sc_function_executed;
00290 boost::function<void()> m_sc_function;
00291 #ifdef SC_CALL_USES_ASYNC_REQUEST_UPDATE
00292
00293 sc_core::sc_event m_systemc_synchro_ev;
00294 static async_event_queue m_async_event_queue;
00295 #endif
00296
00301 boost::condition_variable m_cond_catch_up;
00302 sc_core::sc_time m_catch_up_time;
00303
00304 };
00305
00306 #endif // SYNC_TASK_H