rc_process.h

Go to the documentation of this file.
00001 // vim:set et sts=4 ts=4 tw=75 sw=4 ai ci cin cino=g0,t0:
00002 /*
00003  * Copyright (C) 2007, Technical Computer Science Group,
00004  *                     University of Bonn
00005  *
00006  * This file is part of the ReChannel library.
00007  *
00008  * The ReChannel library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the
00011  * License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be
00014  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this library; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00021  * Boston, MA 02110-1301, USA.
00022  *
00023  * Authors: Andreas Raabe and Armin Felke. Implementation by Armin Felke.
00024  *          {raabe, felke}@cs.uni-bonn.de
00025  */
00037 #ifndef RC_PROCESS_H_
00038 #define RC_PROCESS_H_
00039 
00040 #include "ReChannel/core/rc_common_header.h"
00041 #include "ReChannel/util/rc_hash_map.h"
00042 
00043 namespace ReChannel {
00044 
00045 // you may decrease stack size to 1KB (or even lower) if your OS allows
00046 #ifndef RC_PROCESS_TEMP_PROC_STACK_SIZE
00047  #define RC_PROCESS_TEMP_PROC_STACK_SIZE 16384
00048 #endif // RC_PROCESS_TEMP_PROC_STACK_SIZE
00049 
00050 class rc_process_handle;
00051 class rc_process_behavior_change;
00052 class rc_process_cancel_exception;
00053 class rc_spawn_options;
00054 
00055 class rc_reset_channel_if;
00056 class rc_process_reset;
00057 
00058 namespace internals {
00059 class process_support;
00060 } // namespace internals
00061 
00065 class rc_process_control
00066 {
00067     friend class rc_process_registry;
00068     friend class rc_process_behavior_change;
00069 
00070 private:
00071     typedef std::set<rc_process_control*> pctrl_set;
00072 
00073 public:
00074     explicit rc_process_control(
00075         bool is_initially_active=false, bool deactivate_silently=false);
00076 
00077     explicit rc_process_control(
00078         const rc_process_control& parent,
00079         bool is_initially_active=false, bool deactivate_silently=false);
00080 
00081     void activate();
00082 
00083     void deactivate();
00084 
00085     inline bool is_active() const
00086         { return !p_cancel_flag; }
00087 
00088     inline bool is_deactivation_event() const
00089         { return (p_cancel_delta == sc_delta_count()); }
00090 
00091     inline const sc_event& get_deactivation_event() const
00092         { return p_cancel_event; }
00093 
00094     inline bool is_activation_event() const
00095         { return (p_activation_delta == sc_delta_count()); }
00096 
00097     inline const sc_event& get_activation_event() const
00098         { return p_activation_event; }
00099 
00100     inline bool is_deactivate_silently() const
00101         { return p_deactivate_silently; }
00102 
00103     inline void set_deactivate_silently(bool b)
00104         { p_deactivate_silently = b; }
00105 
00106     inline bool has_parent() const
00107         { return (p_parent != NULL); }
00108 
00109     inline const rc_process_control* get_parent() const
00110         { return p_parent; }
00111 
00112     ~rc_process_control();
00113 
00114 private:
00115     sc_event      p_activation_event;
00116     sc_dt::uint64 p_activation_delta;
00117 
00118     sc_event      p_cancel_event;
00119     bool          p_cancel_flag;
00120     sc_dt::uint64 p_cancel_delta;
00121 
00122     bool          p_deactivate_silently;
00123 
00124     const rc_process_control* p_parent;
00125     mutable pctrl_set         p_child_set;
00126 
00127 private:
00128     // disabled
00129     rc_process_control& operator=(const rc_process_control& orig);
00130 };
00131 
00135 struct rc_process_info
00136 {
00137     unsigned int         ref_count;
00138     sc_process_handle    handle;
00139     bool                 dont_initialize : 1;
00140     bool                 is_cancelable   : 1;
00141     bool                 is_terminated   : 1;
00142     bool                 is_temporary    : 1;
00143     const sc_event*      cancel_event;
00144     const bool*          cancel_flag;
00145     const sc_dt::uint64* cancel_delta;
00146     sc_event*            terminated_event;
00147 };
00148 
00152 class rc_process_handle
00153 {
00154     friend rc_process_handle rc_get_current_process_handle();
00155 
00156     friend void rc_next_trigger();
00157     friend void rc_next_trigger(const sc_event&);
00158     friend void rc_next_trigger(sc_event_or_list&);
00159     friend void rc_next_trigger(sc_event_and_list&);
00160     friend void rc_next_trigger(const sc_time&);
00161     friend void rc_next_trigger(double v, sc_time_unit tu);
00162     friend void rc_next_trigger(const sc_time&, const sc_event&);
00163     friend void rc_next_trigger(double, sc_time_unit, const sc_event&);
00164     friend void rc_next_trigger(const sc_time&, sc_event_or_list&);
00165     friend void rc_next_trigger(double, sc_time_unit, sc_event_or_list&);
00166     friend void rc_next_trigger(const sc_time&, sc_event_and_list&);
00167     friend void rc_next_trigger(double, sc_time_unit, sc_event_and_list&);
00168 
00169     friend void rc_wait();
00170     friend void rc_wait(const sc_event&);
00171     friend void rc_wait(sc_event_or_list&);
00172     friend void rc_wait(sc_event_and_list&);
00173     friend void rc_wait(const sc_time&);
00174     friend void rc_wait(double v, sc_time_unit tu);
00175     friend void rc_wait(const sc_time&, const sc_event&);
00176     friend void rc_wait(double, sc_time_unit, const sc_event&);
00177     friend void rc_wait(const sc_time&, sc_event_or_list&);
00178     friend void rc_wait(double, sc_time_unit, sc_event_or_list&);
00179     friend void rc_wait(const sc_time&, sc_event_and_list&);
00180     friend void rc_wait(double, sc_time_unit, sc_event_and_list&);
00181 
00182     friend bool operator==(
00183         const rc_process_handle& left, const rc_process_handle& right);
00184     friend bool operator!=(
00185         const rc_process_handle& left, const rc_process_handle& right);
00186 
00187     friend class rc_process_behavior_change;
00188     friend class rc_process_registry;
00189     friend class internals::process_support;
00190 
00191 public:
00192     inline rc_process_handle();
00193     inline rc_process_handle(const rc_process_handle& hproc);
00194     inline rc_process_handle(const sc_process_handle& hproc);
00195     inline ~rc_process_handle();
00196 
00197     inline rc_process_handle& operator=(const rc_process_handle& hproc);
00198 
00199 public:
00200     inline bool is_dont_initialize() const;
00201     inline sc_process_handle get_sc_process_handle() const;
00202     inline operator sc_process_handle() const;
00203     inline bool is_cancelable() const;
00204     inline bool is_canceled() const;
00205     inline bool is_cancel_event() const;
00206     inline bool is_terminatable() const;
00207     inline bool is_temporary() const;
00208 
00209     inline rc_process_behavior_change behavior_change(
00210         bool is_cancelable);
00211 
00212     inline rc_process_behavior_change behavior_change(
00213         const rc_process_control& pctrl);
00214 
00215     /*inline rc_process_behavior_change behavior_change(
00216         bool is_cancelable, const sc_event* cancel_event,
00217         const bool* cancel_flag, const sc_dt::uint64* cancel_delta);*/
00218 
00219 /* members for sc_process_handle compatibility */
00220 
00221     inline bool valid() const;
00222     inline const char* name() const;
00223     inline sc_curr_proc_kind proc_kind() const;
00224     inline const std::vector<sc_object*>& get_child_objects() const;
00225     inline sc_object* get_parent_object() const;
00226     inline sc_object* get_process_object() const;
00227     inline bool dynamic() const;
00228     inline bool terminated() const;
00229     inline const sc_event& terminated_event() const;
00230 
00231 private:
00232     inline rc_process_handle(rc_process_info* proc_info);
00233     inline rc_process_handle(rc_process_info& proc_info);
00234 
00235     inline const sc_event& get_cancel_trigger_event() const;
00236 
00237 /* special members called by class process_support */
00238 
00239     // note: calling these methods requires a handle on the current process
00240     void wait_terminated(const sc_event& reactivation_event);
00241     bool terminate();
00242     inline void notify_terminated_event();
00243 
00244 private:
00245     rc_process_info* p_proc_info;
00246 
00247     static const sc_event s_never_notified;
00248 };
00249 
00253 class rc_process_registry
00254 {
00255     friend rc_process_registry& rc_get_process_registry();
00256     friend rc_process_handle rc_get_current_process_handle();
00257 
00258     friend void rc_next_trigger();
00259     friend void rc_next_trigger(const sc_event&);
00260     friend void rc_next_trigger(sc_event_or_list&);
00261     friend void rc_next_trigger(sc_event_and_list&);
00262     friend void rc_next_trigger(const sc_time&);
00263     friend void rc_next_trigger(double v, sc_time_unit tu);
00264     friend void rc_next_trigger(const sc_time&, const sc_event&);
00265     friend void rc_next_trigger(double, sc_time_unit, const sc_event&);
00266     friend void rc_next_trigger(const sc_time&, sc_event_or_list&);
00267     friend void rc_next_trigger(double, sc_time_unit, sc_event_or_list&);
00268     friend void rc_next_trigger(const sc_time&, sc_event_and_list&);
00269     friend void rc_next_trigger(double, sc_time_unit, sc_event_and_list&);
00270 
00271     friend void rc_wait();
00272     friend void rc_wait(const sc_event&);
00273     friend void rc_wait(sc_event_or_list&);
00274     friend void rc_wait(sc_event_and_list&);
00275     friend void rc_wait(const sc_time&);
00276     friend void rc_wait(double v, sc_time_unit tu);
00277     friend void rc_wait(const sc_time&, const sc_event&);
00278     friend void rc_wait(double, sc_time_unit, const sc_event&);
00279     friend void rc_wait(const sc_time&, sc_event_or_list&);
00280     friend void rc_wait(double, sc_time_unit, sc_event_or_list&);
00281     friend void rc_wait(const sc_time&, sc_event_and_list&);
00282     friend void rc_wait(double, sc_time_unit, sc_event_and_list&);
00283 
00284     friend class rc_process_handle;
00285     friend class tmp_behavior_modification;
00286     friend class tmp_behavior_modification_simple;
00287     friend class internals::process_support;
00288 
00289 private:
00290     enum registry_options { gc_interval=100 };
00291 
00292 protected:
00293     typedef rc_hash_map<sc_object*, rc_process_info> process_map;
00294 
00295 public:
00296     // returns the number of the current entries in the registry
00297     inline unsigned int get_process_count() const
00298         { return p_process_map.size(); }
00299 
00300     // deletes physically terminated processes from the registry
00301     void gc();
00302 
00303 protected:
00304     ~rc_process_registry()
00305         { rc_process_registry::s_instance = NULL; }
00306 
00307 private:
00308     rc_process_registry();
00309 
00310     rc_process_handle get_process_handle(
00311         const sc_process_handle& hproc, bool implicit_creation=true);
00312 
00313     rc_process_handle register_process(
00314         const sc_process_handle& hproc);
00315 
00316     rc_process_handle register_process(
00317         const sc_process_handle& hproc, bool dont_initialize,
00318         bool is_cancelable, const rc_process_control& pctrl,
00319         bool is_temporary=false);
00320 
00321     rc_process_handle register_process(
00322         const sc_process_handle& hproc, bool dont_initialize,
00323         bool is_cancelable, const sc_event* cancel_event,
00324         const bool* cancel_flag, const sc_dt::uint64* cancel_delta,
00325         bool is_temporary=false);
00326 
00327 private:
00328     static void _rc_wait_event_and_list_proc(
00329         sc_event_and_list& el, sc_event* continue_event);
00330 
00331     static void _rc_wait_event_and_list_proc(
00332         const sc_time& t, sc_event_and_list& el,
00333         sc_event* continue_event);
00334 
00335     static void _rc_create_singleton();
00336 
00337 private:
00338     process_map p_process_map;
00339 
00340     rc_process_handle p_cached_hproc;
00341 
00342 private:
00343     static rc_process_registry* s_instance;
00344 
00345 private:
00346     // disabled
00347     rc_process_registry(const rc_process_registry& orig);
00348     rc_process_registry& operator=(const rc_process_registry& orig);
00349 };
00350 
00351 inline
00352 rc_process_registry& rc_get_process_registry()
00353 {
00354     if (rc_process_registry::s_instance == NULL) {
00355         rc_process_registry::_rc_create_singleton();
00356     }
00357     return *(rc_process_registry::s_instance);
00358 }
00359 
00360 class rc_process_behavior_change
00361 {
00362     friend class rc_process_handle;
00363 
00364 public:
00365     inline rc_process_behavior_change();
00366 
00367     inline rc_process_behavior_change(
00368         const rc_process_behavior_change& pbc);
00369 
00370     inline ~rc_process_behavior_change()
00371         { this->release(); }
00372 
00373     inline bool is_released() const
00374         { return (p_proc_info == NULL); }
00375 
00376     inline void release();
00377 
00378 private:
00379     inline rc_process_behavior_change(
00380         rc_process_info& proc_info, bool is_cancelable);
00381 
00382     inline rc_process_behavior_change(
00383         rc_process_info& proc_info, bool is_cancelable,
00384         const rc_process_control& pctrl);
00385 
00386     inline rc_process_behavior_change(
00387         rc_process_info& proc_info, bool is_cancelable,
00388         const sc_event* cancel_event, const bool* cancel_flag,
00389         const sc_dt::uint64* cancel_delta);
00390 
00391     inline rc_process_behavior_change& operator=(
00392         const rc_process_behavior_change& pbc);
00393 
00394 private:
00395     mutable rc_process_info* p_proc_info;
00396     bool                     p_orig_is_cancelable;
00397     const sc_event*          p_orig_cancel_event;
00398     const bool*              p_orig_cancel_flag;
00399     const sc_dt::uint64*     p_orig_cancel_delta;
00400     sc_event*                p_orig_terminated_event;
00401 };
00402 
00406 class rc_process_cancel_exception
00407     : public rc_throwable
00408 {
00409 public:
00410     virtual void rc_throw()
00411         { throw this; }
00412 };
00413 
00417 class rc_spawn_options
00418     : private sc_spawn_options
00419 {
00420     friend class internals::process_support;
00421 
00422 private:
00423     typedef std::vector<std::pair<const rc_reset_channel_if*, bool> >
00424         reset_channel_vector;
00425     typedef std::vector<std::pair<const sc_in<bool>*, bool> >
00426         reset_port_vector;
00427     typedef std::vector<std::pair<const sc_signal<bool>*, bool> >
00428         reset_signal_vector;
00429     typedef std::vector<rc_process_reset*> process_reset_vector;
00430 
00431 public:
00432     rc_spawn_options();
00433 
00434 public:
00435     inline void spawn_method()
00436         { sc_spawn_options::spawn_method(); }
00437     inline bool is_method() const
00438         { return sc_spawn_options::is_method(); }
00439     inline void dont_initialize()
00440     {
00441         sc_spawn_options::dont_initialize();
00442         p_is_dont_initialize = true;
00443     }
00444     inline bool is_dont_initialize() const
00445         { return p_is_dont_initialize; }
00446     inline void set_stack_size(int stack_size)
00447         { sc_spawn_options::set_stack_size(stack_size); }
00448     inline void set_sensitivity(const sc_event* event_)
00449         { sc_spawn_options::set_sensitivity(event_); }
00450     inline void set_sensitivity(sc_port_base* port_)
00451         { sc_spawn_options::set_sensitivity(port_); }
00452     inline void set_sensitivity(sc_export_base* export_)
00453         { sc_spawn_options::set_sensitivity(export_); }
00454     inline void set_sensitivity(sc_interface* if_)
00455         { sc_spawn_options::set_sensitivity(if_); }
00456     inline void set_sensitivity(sc_event_finder* ef_)
00457         { sc_spawn_options::set_sensitivity(ef_); }
00458     void set_reset_signal(const sc_in<bool>& reset_port_, bool level_);
00459     void set_reset_signal(
00460         const sc_signal<bool>& reset_signal_, bool level_);
00461     void set_reset_signal(
00462         rc_reset_channel_if& reset_channel_, bool level_);
00463     void set_reset(rc_process_reset& process_reset_);
00464 
00465 private:
00466     inline reset_port_vector& get_reset_port_vector()
00467         { return p_reset_port_vector; }
00468     inline reset_signal_vector& get_reset_signal_vector()
00469         { return p_reset_signal_vector; }
00470     inline reset_channel_vector& get_reset_channel_vector()
00471         { return p_reset_channel_vector; }
00472     inline process_reset_vector& get_process_reset_vector()
00473         { return p_process_reset_vector; }
00474 
00475 private:
00476     bool                 p_is_dont_initialize;
00477     reset_channel_vector p_reset_channel_vector;
00478     reset_signal_vector  p_reset_signal_vector;
00479     reset_port_vector    p_reset_port_vector;
00480     process_reset_vector p_process_reset_vector;
00481 
00482 private:
00483     // disabled
00484     rc_spawn_options(const rc_spawn_options&);
00485     rc_spawn_options& operator=(const rc_spawn_options&);
00486 };
00487 
00488 /* inline code */
00489 
00490 inline rc_process_handle::rc_process_handle()
00491     : p_proc_info(NULL)
00492 { }
00493 
00494 inline
00495 rc_process_handle::rc_process_handle(rc_process_info* proc_info)
00496 {
00497     p_proc_info = proc_info;
00498     if (proc_info != NULL) { ++proc_info->ref_count; }
00499 }
00500 
00501 inline
00502 rc_process_handle::rc_process_handle(rc_process_info& proc_info)
00503 {
00504     p_proc_info = &proc_info;
00505     ++proc_info.ref_count;
00506 }
00507 
00508 inline rc_process_handle::rc_process_handle(const rc_process_handle& hproc)
00509 {
00510     p_proc_info = hproc.p_proc_info;
00511     if (p_proc_info != NULL) { ++p_proc_info->ref_count; }
00512 }
00513 
00514 inline rc_process_handle::rc_process_handle(const sc_process_handle& hproc)
00515     : p_proc_info(NULL)
00516 {
00517     rc_process_handle temp =
00518         rc_get_process_registry().get_process_handle(hproc, true);
00519     p_proc_info = temp.p_proc_info;
00520     if (p_proc_info != NULL) { ++p_proc_info->ref_count; }
00521 }
00522 
00523 inline rc_process_handle::~rc_process_handle()
00524 {
00525     if (p_proc_info != NULL) { --p_proc_info->ref_count; }
00526 }
00527 
00528 inline
00529 rc_process_handle&
00530 rc_process_handle::operator=(const rc_process_handle& hproc)
00531 {
00532     if (&hproc != this) {
00533         if (p_proc_info != NULL) { --p_proc_info->ref_count; }
00534         p_proc_info = hproc.p_proc_info;
00535         if (p_proc_info != NULL) { ++p_proc_info->ref_count; }
00536     }
00537     return *this;
00538 }
00539 
00540 inline bool rc_process_handle::is_dont_initialize() const
00541 {
00542     if (p_proc_info != NULL) {
00543         return p_proc_info->dont_initialize;
00544     } else {
00545         return false;
00546     }
00547 }
00548 
00549 inline sc_process_handle rc_process_handle::get_sc_process_handle() const
00550 {
00551     if (p_proc_info != NULL) {
00552         return p_proc_info->handle;
00553     } else {
00554         return sc_process_handle();
00555     }
00556 }
00557 
00558 inline rc_process_handle::operator sc_process_handle() const
00559 {
00560     return get_sc_process_handle();
00561 }
00562 
00563 inline bool rc_process_handle::is_cancelable() const
00564 {
00565     if (p_proc_info != NULL && p_proc_info->handle.valid()) {
00566         return p_proc_info->is_cancelable;
00567     } else {
00568         return false;
00569     }
00570 }
00571 
00572 inline bool rc_process_handle::is_canceled() const
00573 {
00574     if (p_proc_info != NULL) {
00575         if (p_proc_info->terminated_event != NULL
00576         && p_proc_info->is_terminated)
00577         {
00578             return true;
00579         } else if (p_proc_info->handle.valid()
00580         && p_proc_info->is_cancelable
00581         && p_proc_info->cancel_flag != NULL)
00582         {
00583             return *(p_proc_info->cancel_flag);
00584         }
00585     }
00586     return false;
00587 }
00588 
00589 inline bool rc_process_handle::is_cancel_event() const
00590 {
00591     return (p_proc_info != NULL && p_proc_info->handle.valid()
00592         && p_proc_info->is_cancelable
00593         && *(p_proc_info->cancel_delta) == sc_delta_count());
00594 }
00595 
00596 inline const sc_event& rc_process_handle::get_cancel_trigger_event() const
00597 {
00598     if (p_proc_info != NULL && p_proc_info->handle.valid()
00599     && p_proc_info->cancel_event != NULL)
00600     {
00601         return *p_proc_info->cancel_event;
00602     } else {
00603         return s_never_notified;
00604     }
00605 }
00606 
00607 inline
00608 rc_process_behavior_change
00609 rc_process_handle::behavior_change(bool is_cancelable)
00610 {
00611     if (p_proc_info != NULL && p_proc_info->handle.valid()) {
00612         return rc_process_behavior_change(
00613             *p_proc_info, is_cancelable);
00614     } else {
00615         return rc_process_behavior_change();
00616     }
00617 }
00618 
00619 inline
00620 rc_process_behavior_change
00621 rc_process_handle::behavior_change(const rc_process_control& pctrl)
00622 {
00623     if (p_proc_info != NULL && p_proc_info->handle.valid()) {
00624         return rc_process_behavior_change(
00625             *p_proc_info, true, pctrl);
00626     } else {
00627         return rc_process_behavior_change();
00628     }
00629 }
00630 
00631 /*inline
00632 rc_process_behavior_change
00633 rc_process_handle::behavior_change(
00634     bool is_cancelable, const sc_event* cancel_event,
00635     const bool* cancel_flag, const sc_dt::uint64* cancel_delta)
00636 {
00637     if (p_proc_info != NULL && p_proc_info->handle.valid()) {
00638         return rc_process_behavior_change(
00639             *p_proc_info, is_cancelable, cancel_event, cancel_flag,
00640             cancel_delta);
00641     } else {
00642         return rc_process_behavior_change();
00643     }
00644 }*/
00645 
00646 inline
00647 bool rc_process_handle::is_terminatable() const
00648 {
00649     return (p_proc_info != NULL && p_proc_info->terminated_event != NULL);
00650 }
00651 
00652 inline
00653 bool rc_process_handle::is_temporary() const
00654 {
00655     return (p_proc_info != NULL && p_proc_info->is_temporary);
00656 }
00657 
00658 inline bool rc_process_handle::valid() const
00659 {
00660     return (p_proc_info != NULL && p_proc_info->handle.valid());
00661 }
00662 inline const char* rc_process_handle::name() const
00663 {
00664     if (p_proc_info != NULL) {
00665         return p_proc_info->handle.name();
00666     } else {
00667         return NULL;
00668     }
00669 }
00670 inline sc_curr_proc_kind rc_process_handle::proc_kind() const
00671 {
00672     if (p_proc_info != NULL) {
00673         return p_proc_info->handle.proc_kind();
00674     } else {
00675         return SC_NO_PROC_;
00676     }
00677 }
00678 inline
00679 const std::vector<sc_object*>&
00680 rc_process_handle::get_child_objects() const
00681 {
00682     if (p_proc_info != NULL) {
00683         return p_proc_info->handle.get_child_objects();
00684     } else {
00685         return sc_process_handle().get_child_objects();
00686     }
00687 }
00688 inline sc_object* rc_process_handle::get_parent_object() const
00689 {
00690     if (p_proc_info != NULL) {
00691         return p_proc_info->handle.get_parent_object();
00692     } else {
00693         return NULL;
00694     }
00695 }
00696 inline sc_object* rc_process_handle::get_process_object() const
00697 {
00698     if (p_proc_info != NULL) {
00699         return p_proc_info->handle.get_process_object();
00700     } else {
00701         return NULL;
00702     }
00703 }
00704 
00705 inline bool rc_process_handle::dynamic() const
00706 {
00707     if (p_proc_info != NULL) {
00708         return p_proc_info->handle.dynamic();
00709     } else {
00710         return false;
00711     }
00712 }
00713 
00714 inline bool rc_process_handle::terminated() const
00715 {
00716     if (p_proc_info != NULL) {
00717         const bool is_phys_terminated = p_proc_info->handle.terminated();
00718         if (p_proc_info->terminated_event != NULL && !is_phys_terminated) {
00719             return p_proc_info->is_terminated;
00720         } else {
00721             return is_phys_terminated;
00722         }
00723     } else {
00724         return false;
00725     }
00726 }
00727 
00728 inline const sc_event& rc_process_handle::terminated_event() const
00729 {
00730     if (p_proc_info != NULL) {
00731         if (p_proc_info->terminated_event != NULL
00732         && !(p_proc_info->handle.terminated())) {
00733             return *p_proc_info->terminated_event;
00734         } else {
00735             return p_proc_info->handle.terminated_event();
00736         }
00737     } else {
00738         return s_never_notified;
00739     }
00740 }
00741 
00742 inline void rc_process_handle::notify_terminated_event()
00743 {
00744     if (p_proc_info != NULL && p_proc_info->terminated_event != NULL) {
00745         p_proc_info->terminated_event->notify();
00746     }
00747 }
00748 
00749 inline
00750 rc_process_behavior_change::rc_process_behavior_change()
00751     : p_proc_info(NULL),
00752       p_orig_is_cancelable(false), p_orig_cancel_event(NULL),
00753       p_orig_cancel_flag(NULL), p_orig_cancel_delta(NULL),
00754       p_orig_terminated_event(NULL)
00755 { }
00756 
00757 inline
00758 rc_process_behavior_change::rc_process_behavior_change(
00759     rc_process_info& proc_info, bool is_cancelable)
00760     : p_proc_info(&proc_info),
00761       p_orig_is_cancelable(proc_info.is_cancelable),
00762       p_orig_cancel_event(proc_info.cancel_event),
00763       p_orig_cancel_flag(proc_info.cancel_flag),
00764       p_orig_cancel_delta(proc_info.cancel_delta),
00765       p_orig_terminated_event(proc_info.terminated_event)
00766 {
00767     ++proc_info.ref_count;
00768     proc_info.is_cancelable = is_cancelable;
00769     if (is_cancelable == false) {
00770         proc_info.terminated_event = NULL;
00771     }
00772 }
00773 
00774 inline
00775 rc_process_behavior_change::rc_process_behavior_change(
00776     rc_process_info& proc_info, bool is_cancelable,
00777     const rc_process_control& pctrl)
00778     : p_proc_info(&proc_info),
00779       p_orig_is_cancelable(proc_info.is_cancelable),
00780       p_orig_cancel_event(proc_info.cancel_event),
00781       p_orig_cancel_flag(proc_info.cancel_flag),
00782       p_orig_cancel_delta(proc_info.cancel_delta),
00783       p_orig_terminated_event(proc_info.terminated_event)
00784 {
00785     ++proc_info.ref_count;
00786     proc_info.is_cancelable = is_cancelable;
00787     proc_info.cancel_event = &pctrl.p_cancel_event;
00788     proc_info.cancel_flag = &pctrl.p_cancel_flag;
00789     proc_info.cancel_delta = &pctrl.p_cancel_delta;
00790     if (is_cancelable == false) {
00791         proc_info.terminated_event = NULL;
00792     }
00793 }
00794 
00795 inline
00796 rc_process_behavior_change::rc_process_behavior_change(
00797     rc_process_info& proc_info, bool is_cancelable,
00798     const sc_event* cancel_event, const bool* cancel_flag,
00799     const sc_dt::uint64* cancel_delta)
00800     : p_proc_info(&proc_info),
00801       p_orig_is_cancelable(proc_info.is_cancelable),
00802       p_orig_cancel_event(proc_info.cancel_event),
00803       p_orig_cancel_flag(proc_info.cancel_flag),
00804       p_orig_cancel_delta(proc_info.cancel_delta),
00805       p_orig_terminated_event(proc_info.terminated_event)
00806 {
00807     ++proc_info.ref_count;
00808     proc_info.is_cancelable = is_cancelable;
00809     proc_info.cancel_event = cancel_event;
00810     proc_info.cancel_flag = cancel_flag;
00811     proc_info.cancel_delta = cancel_delta;
00812     if (is_cancelable == false) {
00813         proc_info.terminated_event = NULL;
00814     }
00815 }
00816 
00817 inline
00818 rc_process_behavior_change::rc_process_behavior_change(
00819     const rc_process_behavior_change& pbc)
00820 {
00821     p_proc_info = pbc.p_proc_info;
00822     p_orig_is_cancelable = pbc.p_orig_is_cancelable;
00823     p_orig_cancel_event = pbc.p_orig_cancel_event;
00824     p_orig_cancel_flag = pbc.p_orig_cancel_flag;
00825     p_orig_cancel_delta = pbc.p_orig_cancel_delta;
00826     p_orig_terminated_event = pbc.p_orig_terminated_event;
00827     pbc.p_proc_info = NULL;
00828 }
00829 
00830 inline void rc_process_behavior_change::release()
00831 {
00832     if (p_proc_info != NULL) {
00833         p_proc_info->is_cancelable = p_orig_is_cancelable;
00834         p_proc_info->cancel_event = p_orig_cancel_event;
00835         p_proc_info->cancel_flag = p_orig_cancel_flag;
00836         p_proc_info->cancel_delta = p_orig_cancel_delta;
00837         p_proc_info->terminated_event = p_orig_terminated_event;
00838         --p_proc_info->ref_count;
00839         p_proc_info = NULL;
00840     }
00841 }
00842 
00843 inline
00844 rc_process_behavior_change& rc_process_behavior_change::operator=(
00845     const rc_process_behavior_change& pbc)
00846 {
00847     if (&pbc != this) {
00848         this->release();
00849         p_proc_info = pbc.p_proc_info;
00850         p_orig_is_cancelable = pbc.p_orig_is_cancelable;
00851         p_orig_cancel_event = pbc.p_orig_cancel_event;
00852         p_orig_cancel_flag = pbc.p_orig_cancel_flag;
00853         p_orig_cancel_delta = pbc.p_orig_cancel_delta;
00854         p_orig_terminated_event = pbc.p_orig_terminated_event;
00855         pbc.p_proc_info = NULL;
00856     }
00857     return *this;
00858 }
00859 
00860 /* global functions */
00861 
00862 inline bool operator == (
00863     const rc_process_handle& left_, const rc_process_handle& right_)
00864 {
00865     return (left_.p_proc_info != NULL) && (right_.p_proc_info != NULL) &&
00866         (left_.p_proc_info == right_.p_proc_info);
00867 }
00868 
00869 inline bool operator != (
00870     const rc_process_handle& left_, const rc_process_handle& right_)
00871 {
00872     return (left_.p_proc_info == NULL) || (right_.p_proc_info == NULL) ||
00873         (left_.p_proc_info != right_.p_proc_info);
00874 }
00875 
00876 inline rc_process_handle rc_get_current_process_handle()
00877 {
00878     const sc_process_handle handle = sc_get_current_process_handle();
00879     rc_process_registry& preg = rc_get_process_registry();
00880     if (preg.p_cached_hproc.p_proc_info != NULL
00881       && preg.p_cached_hproc.p_proc_info->handle
00882         == handle) {
00883         return preg.p_cached_hproc;
00884     } else {
00885         return preg.get_process_handle(handle);
00886     }
00887 }
00888 
00889 extern void rc_next_trigger();
00890 
00891 extern void rc_next_trigger(const sc_event& e);
00892 
00893 extern void rc_next_trigger(sc_event_or_list& el);
00894 
00895 extern void rc_next_trigger(sc_event_and_list& el);
00896 
00897 extern void rc_next_trigger(const sc_time& t);
00898 
00899 extern void rc_next_trigger(double v, sc_time_unit tu);
00900 
00901 extern void rc_next_trigger(const sc_time& t, const sc_event& e);
00902 
00903 extern void rc_next_trigger(double v, sc_time_unit tu, const sc_event& e);
00904 
00905 extern void rc_next_trigger(const sc_time& t, sc_event_or_list& el);
00906 
00907 extern void rc_next_trigger(
00908     double v, sc_time_unit tu, sc_event_or_list& el);
00909 
00910 extern void rc_next_trigger(const sc_time& t, sc_event_and_list& el);
00911 
00912 extern void rc_next_trigger(
00913     double v, sc_time_unit tu, sc_event_and_list& el);
00914 
00915 extern void rc_wait();
00916 
00917 extern void rc_wait(int n);
00918 
00919 extern void rc_wait(const sc_event& e);
00920 
00921 extern void rc_wait(sc_event_or_list& el);
00922 
00923 extern void rc_wait(sc_event_and_list& el);
00924 
00925 extern void rc_wait(const sc_time& t);
00926 
00927 extern void rc_wait(double v, sc_time_unit tu);
00928 
00929 extern void rc_wait(const sc_time& t, const sc_event& e);
00930 
00931 extern void rc_wait(double v, sc_time_unit tu, const sc_event& e);
00932 
00933 extern void rc_wait(const sc_time& t, sc_event_or_list& el);
00934 
00935 extern void rc_wait(double v, sc_time_unit t, sc_event_or_list& el);
00936 
00937 extern void rc_wait(const sc_time& t, sc_event_and_list& el);
00938 
00939 extern void rc_wait(double v, sc_time_unit tu, sc_event_and_list& el);
00940 
00941 extern bool rc_is_update_phase();
00942 
00943 extern void rc_notify(sc_event& e);
00944 
00945 // note: rc_spawn(..) only makes sense being called from inside a
00946 //       rc_reconfigurable. Thus there is no global rc_spawn(..) function
00947 //       available.
00948 
00949 } // namespace ReChannel
00950 
00951 #define rc_bind    boost::bind
00952 #define rc_ref(x)  boost::ref(x)
00953 #define rc_cref(x) boost::cref(x)
00954 
00955 #endif // RC_PROCESS_H_
00956 
00957 //
00958 // $Id: rc_process.h,v 1.15 2007/12/06 11:42:43 felke Exp $
00959 // $Source: /var/cvs/projekte/ReChannel-v2/src/ReChannel/core/rc_process.h,v $
00960 //

Generated on Tue Jan 1 23:13:41 2008 for ReChannel by  doxygen 1.5.3