00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00037 #include "rc_process.h"
00038
00039 namespace ReChannel {
00040
00041 rc_process_control::rc_process_control(
00042 bool is_initially_active, bool deactivate_silently)
00043 : p_activation_delta(0), p_cancel_flag(!is_initially_active),
00044 p_cancel_delta(0), p_deactivate_silently(deactivate_silently),
00045 p_parent(NULL)
00046 { }
00047
00048 rc_process_control::rc_process_control(
00049 const rc_process_control& parent, bool is_initially_active,
00050 bool deactivate_silently)
00051 : p_activation_delta(0), p_cancel_flag(!is_initially_active),
00052 p_cancel_delta(0), p_deactivate_silently(deactivate_silently),
00053 p_parent(&parent)
00054 {
00055 parent.p_child_set.insert(this);
00056 }
00057
00058 rc_process_control::~rc_process_control()
00059 {
00060 if (p_parent != NULL) {
00061 p_parent->p_child_set.erase(this);
00062 }
00063 for (pctrl_set::iterator it=p_child_set.begin();
00064 it != p_child_set.end();
00065 ++it)
00066 {
00067 (*it)->p_parent = NULL;
00068 }
00069 }
00070
00071 void rc_process_control::activate()
00072 {
00073 if (sc_is_running()) {
00074 rc_notify(p_activation_event);
00075 p_activation_delta = sc_delta_count();
00076 }
00077 p_cancel_flag = false;
00078
00079
00080 for (pctrl_set::iterator it=p_child_set.begin();
00081 it != p_child_set.end();
00082 ++it)
00083 {
00084 (*it)->activate();
00085 }
00086 }
00087
00088 void rc_process_control::deactivate()
00089 {
00090 if (sc_is_running()) {
00091 if (!p_deactivate_silently) {
00092 rc_notify(p_cancel_event);
00093 }
00094 p_cancel_delta = sc_delta_count();
00095 }
00096 p_cancel_flag = true;
00097
00098
00099 for (pctrl_set::iterator it=p_child_set.begin();
00100 it != p_child_set.end();
00101 ++it)
00102 {
00103 rc_process_control* const pctrl = *it;
00104 pctrl->deactivate();
00105 if (pctrl->p_deactivate_silently) {
00106
00107 rc_notify(pctrl->p_cancel_event);
00108 }
00109 }
00110 }
00111
00112 const sc_event rc_process_handle::s_never_notified;
00113
00114 rc_process_registry* rc_process_registry::s_instance = NULL;
00115
00116 rc_process_registry::rc_process_registry()
00117 {}
00118
00119 rc_process_handle rc_process_registry::get_process_handle(
00120 const sc_process_handle& hproc, bool implicit_creation)
00121 {
00122 process_map::iterator it =
00123 p_process_map.find(hproc.get_process_object());
00124 if (it != p_process_map.end()) {
00125 return rc_process_handle(&it->second);
00126 } else if (implicit_creation) {
00127 return this->register_process(hproc);
00128 } else {
00129 return rc_process_handle();
00130 }
00131 }
00132
00133 rc_process_handle rc_process_registry::register_process(
00134 const sc_process_handle& hproc)
00135 {
00136 if ((p_process_map.size() % gc_interval) == 0) {
00137 this->gc();
00138 }
00139 rc_process_info& pinfo = p_process_map[hproc.get_process_object()];
00140 pinfo.ref_count = 0;
00141 pinfo.handle = hproc;
00142 pinfo.dont_initialize = false;
00143 pinfo.is_cancelable = false;
00144 pinfo.is_terminated = false;
00145 pinfo.is_temporary = false;
00146 pinfo.cancel_event = NULL;
00147 pinfo.cancel_flag = NULL;
00148 pinfo.cancel_delta = NULL;
00149 pinfo.terminated_event = NULL;
00150 return rc_process_handle(pinfo);
00151 }
00152
00153 rc_process_handle rc_process_registry::register_process(
00154 const sc_process_handle& hproc,
00155 bool dont_initialize, bool is_cancelable,
00156 const rc_process_control& pctrl, bool is_temporary)
00157 {
00158 if ((p_process_map.size() % gc_interval) == 0) {
00159 this->gc();
00160 }
00161 rc_process_info& pinfo = p_process_map[hproc.get_process_object()];
00162 pinfo.ref_count = 0;
00163 pinfo.handle = hproc;
00164 pinfo.dont_initialize = dont_initialize;
00165 pinfo.is_cancelable = is_cancelable;
00166 pinfo.is_terminated = false;
00167 pinfo.is_temporary = is_temporary;
00168 pinfo.cancel_event = &pctrl.p_cancel_event;
00169 pinfo.cancel_flag = &pctrl.p_cancel_flag;
00170 pinfo.cancel_delta = &pctrl.p_cancel_delta;
00171 pinfo.terminated_event = new sc_event();
00172 return rc_process_handle(pinfo);
00173 }
00174
00175 rc_process_handle rc_process_registry::register_process(
00176 const sc_process_handle& hproc,
00177 bool dont_initialize, bool is_cancelable,
00178 const sc_event* cancel_event, const bool* cancel_flag,
00179 const sc_dt::uint64* cancel_delta, bool is_temporary)
00180 {
00181 if ((p_process_map.size() % gc_interval) == 0) {
00182 this->gc();
00183 }
00184 rc_process_info& pinfo = p_process_map[hproc.get_process_object()];
00185 pinfo.ref_count = 0;
00186 pinfo.handle = hproc;
00187 pinfo.dont_initialize = dont_initialize;
00188 pinfo.is_cancelable = is_cancelable;
00189 pinfo.is_terminated = false;
00190 pinfo.is_temporary = is_temporary;
00191 pinfo.cancel_event = cancel_event;
00192 pinfo.cancel_flag = cancel_flag;
00193 pinfo.cancel_delta = cancel_delta;
00194 pinfo.terminated_event = new sc_event();
00195 return rc_process_handle(pinfo);
00196 }
00197
00198 void rc_process_registry::gc()
00199 {
00200 for(process_map::iterator it = p_process_map.begin();
00201 it != p_process_map.end();
00202 ++it)
00203 {
00204 rc_process_info& pinfo = it->second;
00205
00206 if (pinfo.ref_count == 0 && pinfo.handle.terminated()) {
00207 if (pinfo.terminated_event != NULL) {
00208 delete pinfo.terminated_event;
00209 }
00210 p_process_map.erase(it);
00211 }
00212 }
00213 }
00214
00215 void rc_process_registry::_rc_create_singleton()
00216 {
00217 if (rc_process_registry::s_instance == NULL) {
00218 rc_process_registry::s_instance = new rc_process_registry();
00219 }
00220 }
00221
00222 void rc_process_registry::_rc_wait_event_and_list_proc(
00223 sc_event_and_list& el,
00224 sc_event* continue_event)
00225 {
00226 std::auto_ptr<sc_event> delete_on_exit(continue_event);
00227 ::sc_core::wait(el);
00228 continue_event->notify();
00229
00230 ::sc_core::wait(SC_ZERO_TIME);
00231
00232 }
00233
00234 void rc_process_registry::_rc_wait_event_and_list_proc(
00235 const sc_time& t, sc_event_and_list& el,
00236 sc_event* continue_event)
00237 {
00238 std::auto_ptr<sc_event> delete_on_exit(continue_event);
00239 ::sc_core::wait(t, el);
00240 continue_event->notify();
00241
00242 ::sc_core::wait(SC_ZERO_TIME);
00243
00244 }
00245
00246 bool rc_process_handle::terminate()
00247 {
00248 if (p_proc_info != NULL
00249 && p_proc_info->terminated_event != NULL) {
00250 if (p_proc_info->is_terminated) {
00251 return true;
00252 }
00253 p_proc_info->is_terminated = true;
00254 p_proc_info->terminated_event->notify();
00255 throw new rc_process_cancel_exception();
00256 }
00257 return false;
00258 }
00259
00260 void rc_process_handle::wait_terminated(const sc_event& reactivation_event)
00261 {
00262 if (p_proc_info != NULL
00263 && p_proc_info->terminated_event != NULL) {
00264 if (!p_proc_info->is_terminated) {
00265 p_proc_info->is_terminated = true;
00266 p_proc_info->terminated_event->notify();
00267 }
00268 ::sc_core::wait(reactivation_event);
00269 p_proc_info->is_terminated = false;
00270 } else {
00271 ::sc_core::wait(reactivation_event);
00272 }
00273 }
00274
00275 rc_spawn_options::rc_spawn_options()
00276 : p_is_dont_initialize(false)
00277 { }
00278
00279 void rc_spawn_options::set_reset_signal(
00280 const sc_in<bool>& reset_port_, bool active_level_)
00281 {
00282 p_reset_port_vector.push_back(
00283 reset_port_vector::value_type(&reset_port_, active_level_));
00284 }
00285
00286 void rc_spawn_options::set_reset_signal(
00287 const sc_signal<bool>& reset_signal_, bool active_level_)
00288 {
00289 p_reset_signal_vector.push_back(
00290 reset_signal_vector::value_type(&reset_signal_, active_level_));
00291 }
00292
00293 void rc_spawn_options::set_reset_signal(
00294 rc_reset_channel_if& reset_channel_, bool active_level_)
00295 {
00296 p_reset_channel_vector.push_back(
00297 reset_channel_vector::value_type(&reset_channel_, active_level_));
00298 }
00299
00300 void rc_spawn_options::set_reset(rc_process_reset& process_reset_)
00301 {
00302 p_process_reset_vector.push_back(&process_reset_);
00303 }
00304
00305 void rc_next_trigger()
00306 {
00307 sc_core::next_trigger();
00308 }
00309
00310 void rc_next_trigger(const sc_event& e)
00311 {
00312 rc_process_handle hproc = rc_get_current_process_handle();
00313 if (hproc.is_cancelable()) {
00314 sc_core::next_trigger(e | hproc.get_cancel_trigger_event());
00315 } else {
00316 sc_core::next_trigger(e);
00317 }
00318 }
00319
00320 void rc_next_trigger(sc_event_or_list& el)
00321 {
00322 rc_process_handle hproc = rc_get_current_process_handle();
00323 if (hproc.is_cancelable()) {
00324 sc_core::next_trigger(el | hproc.get_cancel_trigger_event());
00325 } else {
00326 sc_core::next_trigger(el);
00327 }
00328 }
00329
00330 void rc_next_trigger(sc_event_and_list& el)
00331 {
00332 rc_process_handle hproc = rc_get_current_process_handle();
00333 if (hproc.is_cancelable()) {
00334
00335 if (!hproc.is_canceled()) {
00336 std::auto_ptr<sc_event> continue_event(new sc_event());
00337 sc_spawn(
00338 sc_bind(
00339 &rc_process_registry::_rc_wait_event_and_list_proc,
00340 sc_ref(el), continue_event.get()));
00341 sc_core::next_trigger(
00342 *(continue_event.release()) | hproc.get_cancel_trigger_event());
00343
00344 } else {
00345 sc_core::next_trigger(el);
00346 }
00347 } else {
00348 sc_core::next_trigger(el);
00349 }
00350 }
00351
00352 void rc_next_trigger(const sc_time& t)
00353 {
00354 rc_process_handle hproc = rc_get_current_process_handle();
00355 if (hproc.is_cancelable()) {
00356 sc_core::next_trigger(t, hproc.get_cancel_trigger_event());
00357 } else {
00358 sc_core::next_trigger(t);
00359 }
00360 }
00361
00362 void rc_next_trigger(double v, sc_time_unit tu)
00363 {
00364 rc_next_trigger(sc_time(v, tu));
00365 }
00366
00367 void rc_next_trigger(const sc_time& t, const sc_event& e)
00368 {
00369 rc_process_handle hproc = rc_get_current_process_handle();
00370 if (hproc.is_cancelable()) {
00371 sc_core::next_trigger(t, e | hproc.get_cancel_trigger_event());
00372 } else {
00373 sc_core::next_trigger(t, e);
00374 }
00375 }
00376
00377 void rc_next_trigger(double v, sc_time_unit tu, const sc_event& e)
00378 {
00379 rc_next_trigger(sc_time(v, tu), e);
00380 }
00381
00382 void rc_next_trigger(const sc_time& t, sc_event_or_list& el)
00383 {
00384 rc_process_handle hproc = rc_get_current_process_handle();
00385 if (hproc.is_cancelable()) {
00386 sc_core::next_trigger(t, el | hproc.get_cancel_trigger_event());
00387 } else {
00388 sc_core::next_trigger(t, el);
00389 }
00390 }
00391
00392 void rc_next_trigger(double v, sc_time_unit tu, sc_event_or_list& el)
00393 {
00394 rc_next_trigger(sc_time(v, tu), el);
00395 }
00396
00397 void rc_next_trigger(const sc_time& t, sc_event_and_list& el)
00398 {
00399 rc_process_handle hproc = rc_get_current_process_handle();
00400 if (hproc.is_cancelable()) {
00401
00402 if (!hproc.is_canceled()) {
00403 std::auto_ptr<sc_event> continue_event(new sc_event());
00404 sc_spawn(
00405 sc_bind(
00406 &rc_process_registry::_rc_wait_event_and_list_proc,
00407 sc_cref(t), sc_ref(el), continue_event.get()));
00408 sc_core::next_trigger(
00409 t, (*(continue_event.release())
00410 | hproc.get_cancel_trigger_event()));
00411
00412 } else {
00413 sc_core::next_trigger(t, el);
00414 }
00415 } else {
00416 sc_core::next_trigger(t, el);
00417 }
00418 }
00419
00420 void rc_next_trigger(double v, sc_time_unit tu, sc_event_and_list& el)
00421 {
00422 rc_next_trigger(sc_time(v, tu), el);
00423 }
00424
00425 void rc_wait()
00426 {
00427 rc_process_handle hproc = rc_get_current_process_handle();
00428 if (hproc.is_cancelable()) {
00429 if (hproc.is_canceled()) {
00430 throw new rc_process_cancel_exception();
00431 } else {
00432 ::sc_core::wait();
00433 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00434 throw new rc_process_cancel_exception();
00435 }
00436 }
00437 } else {
00438 ::sc_core::wait();
00439 }
00440 }
00441
00442 void rc_wait(int n)
00443 {
00444 rc_process_handle hproc = rc_get_current_process_handle();
00445 if (hproc.is_cancelable() && n > 0) {
00446 if (hproc.is_canceled()) {
00447 throw new rc_process_cancel_exception();
00448 } else {
00449 for (int i=0; i < n; i++) {
00450 ::sc_core::wait();
00451 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00452 throw new rc_process_cancel_exception();
00453 }
00454 }
00455 }
00456 } else {
00457 ::sc_core::wait(n);
00458 }
00459 }
00460
00461 void rc_wait(const sc_event& e)
00462 {
00463 rc_process_handle hproc = rc_get_current_process_handle();
00464 if (hproc.is_cancelable()) {
00465 if (hproc.is_canceled()) {
00466 throw new rc_process_cancel_exception();
00467 } else {
00468 ::sc_core::wait(e | hproc.get_cancel_trigger_event());
00469 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00470 throw new rc_process_cancel_exception();
00471 }
00472 }
00473 } else {
00474 ::sc_core::wait(e);
00475 }
00476 }
00477
00478 void rc_wait(sc_event_or_list& el)
00479 {
00480 rc_process_handle hproc = rc_get_current_process_handle();
00481 if (hproc.is_cancelable()) {
00482 if (hproc.is_canceled()) {
00483 throw new rc_process_cancel_exception();
00484 } else {
00485 ::sc_core::wait(el | hproc.get_cancel_trigger_event());
00486 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00487 throw new rc_process_cancel_exception();
00488 }
00489 }
00490 } else {
00491 ::sc_core::wait(el);
00492 }
00493 }
00494
00495 void rc_wait(sc_event_and_list& el)
00496 {
00497 rc_process_handle hproc = rc_get_current_process_handle();
00498 if (hproc.is_cancelable()) {
00499 if (hproc.is_canceled()) {
00500 throw new rc_process_cancel_exception();
00501 } else {
00502 std::auto_ptr<sc_event> continue_event(new sc_event());
00503 sc_spawn_options opt;
00504 opt.set_stack_size(RC_PROCESS_TEMP_PROC_STACK_SIZE);
00505 sc_spawn(
00506 sc_bind(
00507 &rc_process_registry::_rc_wait_event_and_list_proc,
00508 sc_ref(el), continue_event.get()),
00509 NULL, &opt);
00510 ::sc_core::wait(
00511 *(continue_event.release()) | hproc.get_cancel_trigger_event());
00512
00513
00514 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00515 throw new rc_process_cancel_exception();
00516 }
00517 }
00518 } else {
00519 ::sc_core::wait(el);
00520 }
00521 }
00522
00523 void rc_wait(const sc_time& t)
00524 {
00525 rc_process_handle hproc = rc_get_current_process_handle();
00526 if (hproc.is_cancelable()) {
00527 if (hproc.is_canceled()) {
00528 throw new rc_process_cancel_exception();
00529 } else {
00530 ::sc_core::wait(t, hproc.get_cancel_trigger_event());
00531 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00532 throw new rc_process_cancel_exception();
00533 }
00534 }
00535 } else {
00536 ::sc_core::wait(t);
00537 }
00538 }
00539
00540 void rc_wait(double v, sc_time_unit tu)
00541 {
00542 rc_wait(sc_time(v, tu));
00543 }
00544
00545 void rc_wait(const sc_time& t, const sc_event& e)
00546 {
00547 rc_process_handle hproc = rc_get_current_process_handle();
00548 if (hproc.is_cancelable()) {
00549 if (hproc.is_canceled()) {
00550 throw new rc_process_cancel_exception();
00551 } else {
00552 ::sc_core::wait(t, e | hproc.get_cancel_trigger_event());
00553 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00554 throw new rc_process_cancel_exception();
00555 }
00556 }
00557 } else {
00558 ::sc_core::wait(t, e);
00559 }
00560 }
00561
00562 void rc_wait(double v, sc_time_unit tu, const sc_event& e)
00563 {
00564 rc_wait(sc_time(v, tu), e);
00565 }
00566
00567 void rc_wait(const sc_time& t, sc_event_or_list& el)
00568 {
00569 rc_process_handle hproc = rc_get_current_process_handle();
00570 if (hproc.is_cancelable()) {
00571 if (hproc.is_canceled()) {
00572 throw new rc_process_cancel_exception();
00573 } else {
00574 ::sc_core::wait(t, el | hproc.get_cancel_trigger_event());
00575 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00576 throw new rc_process_cancel_exception();
00577 }
00578 }
00579 } else {
00580 ::sc_core::wait(t, el);
00581 }
00582 }
00583
00584 void rc_wait(double v, sc_time_unit tu, sc_event_or_list& el)
00585 {
00586 rc_wait(sc_time(v, tu), el);
00587 }
00588
00589 void rc_wait(const sc_time& t, sc_event_and_list& el)
00590 {
00591 rc_process_handle hproc = rc_get_current_process_handle();
00592 if (hproc.is_cancelable()) {
00593 if (hproc.is_canceled()) {
00594 throw new rc_process_cancel_exception();
00595 } else {
00596 std::auto_ptr<sc_event> continue_event(new sc_event());
00597 sc_spawn_options opt;
00598 opt.set_stack_size(RC_PROCESS_TEMP_PROC_STACK_SIZE);
00599 sc_spawn(
00600 sc_bind(
00601 &rc_process_registry::_rc_wait_event_and_list_proc,
00602 sc_cref(t), sc_ref(el), continue_event.get()),
00603 NULL, &opt);
00604 ::sc_core::wait(
00605 t, (*(continue_event.release())
00606 | hproc.get_cancel_trigger_event()));
00607
00608
00609 if (hproc.is_canceled() || hproc.is_cancel_event()) {
00610 throw new rc_process_cancel_exception();
00611 }
00612 }
00613 } else {
00614 ::sc_core::wait(t, el);
00615 }
00616 }
00617
00618 void rc_wait(double v, sc_time_unit tu, sc_event_and_list& el)
00619 {
00620 rc_wait(sc_time(v, tu), el);
00621 }
00622
00623 bool rc_is_update_phase()
00624 {
00625 static bool s_is_update_phase = false;
00626 static sc_dt::uint64 s_last_delta = 0;
00627 static sc_event s_test_event;
00628
00629 if (s_is_update_phase == false
00630 || s_last_delta != sc_delta_count()) {
00631 try {
00632 s_test_event.notify();
00633 return false;
00634 } catch(sc_report r) {
00635 s_is_update_phase = true;
00636 s_last_delta = sc_delta_count();
00637 }
00638 }
00639 return true;
00640 }
00641
00642 void rc_notify(sc_event& e)
00643 {
00644 static bool s_is_update_phase = false;
00645 static sc_dt::uint64 s_last_delta = 0;
00646
00647 if (s_is_update_phase == true) {
00648 if (s_last_delta == sc_delta_count()) {
00649 e.notify(SC_ZERO_TIME);
00650 return;
00651 } else {
00652 s_is_update_phase = false;
00653 }
00654 }
00655 try {
00656 e.notify();
00657 } catch(sc_report r) {
00658 s_is_update_phase = true;
00659 s_last_delta = sc_delta_count();
00660 e.notify(SC_ZERO_TIME);
00661 }
00662 }
00663
00664 }
00665
00666
00667
00668
00669