diff --git a/actsim.cc b/actsim.cc index 0d1a0f6..dae40b3 100644 --- a/actsim.cc +++ b/actsim.cc @@ -46,13 +46,6 @@ */ -struct chpsimgraph_info { - ChpSimGraph *g; - Expr *e; /* for probes, if needed */ - int max_count; - int max_stats; -}; - struct process_info { process_info() { chp = NULL; hse = NULL; prs = NULL; } chpsimgraph_info *chp, *hse; @@ -344,24 +337,18 @@ ChpSim *ActSimCore::_add_chp (act_chp *c) b->v = pgi; } if (!pgi->chp) { - NEW (pgi->chp, chpsimgraph_info); if (c->c && c->c->type == ACT_CHP_COMMA) { setInternalParallel (1); } else { setInternalParallel (0); } - pgi->chp->g = ChpSimGraph::buildChpSimGraph (this, c->c); - pgi->chp->e = NULL; - pgi->chp->max_count = ChpSimGraph::max_pending_count; - pgi->chp->max_stats = ChpSimGraph::max_stats; + pgi->chp = ChpSimGraph::buildChpSimGraph (this, c->c); } - x = new ChpSim (pgi->chp->g, pgi->chp->max_count, - pgi->chp->max_stats, - c->c, this, _curproc); + x = new ChpSim (pgi->chp, c->c, this, _curproc); } else { - x = new ChpSim (NULL, 0, 0, NULL, this, _curproc); + x = new ChpSim (NULL, NULL, this, _curproc); } x->setName (_curinst); x->setOffsets (&_curoffset); @@ -413,21 +400,15 @@ ChpSim *ActSimCore::_add_hse (act_chp *c) } if (!pgi->hse) { - NEW (pgi->hse, chpsimgraph_info); - if (c->c && c->c->type == ACT_CHP_COMMA) { setInternalParallel (1); } else { setInternalParallel (0); } - pgi->hse->g = ChpSimGraph::buildChpSimGraph (this, c->c); - pgi->hse->max_count = ChpSimGraph::max_pending_count; - pgi->hse->max_stats = ChpSimGraph::max_stats; + pgi->hse = ChpSimGraph::buildChpSimGraph (this, c->c); } - ChpSim *x = new ChpSim (pgi->hse->g, pgi->hse->max_count, - pgi->hse->max_stats, - c->c, this, _curproc); + ChpSim *x = new ChpSim (pgi->hse, c->c, this, _curproc); x->setHseMode (); x->setName (_curinst); x->setOffsets (&_curoffset); @@ -2035,12 +2016,14 @@ void ActSim::runInit () for (int i=0; i < num; i++) { if (lia[i] && list_next (lia[i])) { act_chp_lang_t *c = (act_chp_lang_t *) list_value (lia[i]); - ChpSimGraph *sg = ChpSimGraph::buildChpSimGraph (this, c); + chpsimgraph_info *ci = ChpSimGraph::buildChpSimGraph (this, c); ChpSim *sim_init = - new ChpSim (sg, ChpSimGraph::max_pending_count, 0, c, this, NULL); + new ChpSim (ci, c, this, NULL); list_append (_init_simobjs, sim_init); - list_append (_init_simobjs, sg); + list_append (_init_simobjs, ci->g); + + delete ci; lia[i] = list_next (lia[i]); @@ -2065,12 +2048,15 @@ void ActSim::runInit () for (int i=0; i < num; i++) { if (lia[i]) { act_chp_lang_t *c = (act_chp_lang_t *) list_value (lia[i]); - ChpSimGraph *sg = ChpSimGraph::buildChpSimGraph (this, c); + chpsimgraph_info *ci = ChpSimGraph::buildChpSimGraph (this, c); + ChpSim *sim_init = - new ChpSim (sg, ChpSimGraph::max_pending_count, 0, c, this, NULL); + new ChpSim (ci, c, this, NULL); list_append (_init_simobjs, sim_init); - list_append (_init_simobjs, sg); + list_append (_init_simobjs, ci->g); + + delete ci; lia[i] = list_next (lia[i]); } diff --git a/channel.cc b/channel.cc index 98bb893..dfba636 100644 --- a/channel.cc +++ b/channel.cc @@ -391,7 +391,7 @@ int ChanMethods::runProbe (ActSimCore *sim, int idx) { if (!ch->_dummy) { - ch->_dummy = new ChpSim (NULL, 0, 0, NULL, sim, NULL); + ch->_dummy = new ChpSim (NULL, NULL, sim, NULL); ch->_dummy->setFrag (ch); } @@ -425,7 +425,7 @@ int ChanMethods::runMethod (ActSimCore *sim, BigInt r; if (!ch->_dummy) { - ch->_dummy = new ChpSim (NULL, 0, 0, NULL, sim, NULL); + ch->_dummy = new ChpSim (NULL, NULL, sim, NULL); ch->_dummy->setFrag (ch); } diff --git a/chpsim.cc b/chpsim.cc index 1d5483a..55c6c5a 100644 --- a/chpsim.cc +++ b/chpsim.cc @@ -35,6 +35,7 @@ class ChpSim; int ChpSimGraph::cur_pending_count = 0; int ChpSimGraph::max_pending_count = 0; int ChpSimGraph::max_stats = 0; +struct Hashtable *ChpSimGraph::labels = NULL; extern ActSim *glob_sim; @@ -358,12 +359,25 @@ static void _clrhash () _ZEROHASH = NULL; } -ChpSim::ChpSim (ChpSimGraph *g, int max_cnt, int max_stats, +ChpSim::ChpSim (chpsimgraph_info *cgi, act_chp_lang_t *c, ActSimCore *sim, Process *p) : ActSimObj (sim, p) { + ChpSimGraph *g; + int max_cnt, max_stats; char buf[1024]; + if (cgi) { + g = cgi->g; + max_cnt = cgi->max_count; + max_stats = cgi->max_stats; + } + else { + g = NULL; + max_cnt = 0; + max_stats = 0; + } + _deadlock_pc = NULL; _stalled_pc = list_new (); _probe = NULL; @@ -455,7 +469,9 @@ ChpSim::ChpSim (ChpSimGraph *g, int max_cnt, int max_stats, _pc[0] = g; _statestk = list_new (); _initEvent (); - + if (cgi) { + _labels = cgi->labels; + } } else { _pc = NULL; @@ -4513,13 +4529,20 @@ static chpsimstmt *gc_to_chpsim (act_chp_gc_t *gc, ActSimCore *s) return ret; } -ChpSimGraph *ChpSimGraph::buildChpSimGraph (ActSimCore *sc, - act_chp_lang_t *c) +chpsimgraph_info *ChpSimGraph::buildChpSimGraph (ActSimCore *sc, + act_chp_lang_t *c) { ChpSimGraph *stop; + chpsimgraph_info *gi; + cur_pending_count = 0; max_pending_count = 0; max_stats = 0; + labels = NULL; + + if (!c) return NULL; + + gi = new chpsimgraph_info; if (c->type == ACT_HSE_FRAGMENTS) { int len = 0; @@ -4628,10 +4651,21 @@ ChpSimGraph *ChpSimGraph::buildChpSimGraph (ActSimCore *sc, stop = frags[0]; FREE (frags); FREE (nstop); - return stop; + gi->g = stop; + gi->max_count = max_pending_count; + gi->max_stats = max_stats; + gi->labels = labels; + gi->e = NULL; + return gi; } stop = new ChpSimGraph (sc); - return _buildChpSimGraph (sc, c, &stop); + gi->g = _buildChpSimGraph (sc, c, &stop); + gi->max_count = max_pending_count; + gi->max_stats = max_stats; + gi->e = NULL; + gi->labels = labels; + + return gi; } static ChpSimGraph *_gen_nop (ActSimCore *sc) @@ -4645,6 +4679,24 @@ static ChpSimGraph *_gen_nop (ActSimCore *sc) return ret; } +static void _update_label (struct Hashtable **H, + const char *l, ChpSimGraph *ptr) +{ + if (!l) return; + + if (!(*H)) { + *H = hash_new (2); + } + if (hash_lookup (*H, l)) { + warning ("Duplicate label `%s'; ignored", l); + } + else { + hash_bucket_t *b; + b = hash_add (*H, l); + b->v = ptr; + } +} + ChpSimGraph *ChpSimGraph::_buildChpSimGraph (ActSimCore *sc, act_chp_lang_t *c, ChpSimGraph **stop) @@ -4656,6 +4708,7 @@ ChpSimGraph *ChpSimGraph::_buildChpSimGraph (ActSimCore *sc, int width; int used_slots = 0; ChpSimGraph *ostop; + hash_bucket_t *b; if (!c) return NULL; @@ -4663,9 +4716,11 @@ ChpSimGraph *ChpSimGraph::_buildChpSimGraph (ActSimCore *sc, case ACT_CHP_SEMI: count = cur_pending_count; if (list_length (c->u.semi_comma.cmd)== 1) { - return _buildChpSimGraph + ret = _buildChpSimGraph (sc, (act_chp_lang_t *)list_value (list_first (c->u.semi_comma.cmd)), stop); + _update_label (&labels, c->label, ret); + return ret; } used_slots = cur_pending_count; for (listitem_t *li = list_first (c->u.semi_comma.cmd); @@ -4690,9 +4745,11 @@ ChpSimGraph *ChpSimGraph::_buildChpSimGraph (ActSimCore *sc, case ACT_CHP_COMMA: if (list_length (c->u.semi_comma.cmd)== 1) { - return _buildChpSimGraph + ret = _buildChpSimGraph (sc, (act_chp_lang_t *)list_value (list_first (c->u.semi_comma.cmd)), stop); + _update_label (&labels, c->label, ret); + return ret; } ret = new ChpSimGraph (sc); ostop = *stop; @@ -5134,6 +5191,7 @@ ChpSimGraph *ChpSimGraph::_buildChpSimGraph (ActSimCore *sc, fatal_error ("Unknown chp type %d\n", c->type); break; } + _update_label (&labels, c->label, ret); return ret; } @@ -6059,3 +6117,38 @@ void ChpSim::skipChannelAction (int is_send, int offset) c->recv_here = 0; } } + +int ChpSim::jumpTo (const char *l) +{ + hash_bucket_t *b; + if (!_labels) { + fprintf (stderr, ">> goto operation failed; no labels in process!\n"); + return 0; + } + b = hash_lookup (_labels, l); + if (!b) { + fprintf (stderr, ">> goto operation failed; label `%s' does not exist!\n", l); + return 0; + } + if (_pcused > 1) { + fprintf (stderr, ">> goto operation failed; multiple (%d) active threads of execution.\n", _pcused); + return 0; + } + int slot = -1; + for (int i=0; i < _npc; i++) { + if (_pc[i]) { + if (slot == -1) { + slot = i; + } + else { + warning ("Internal issue with goto operation!"); + } + } + } + if (slot == -1) { + fprintf (stderr, ">> goto operation failed; no active program counter?\n"); + return 0; + } + _pc[slot] = (ChpSimGraph *) b->v; + return 1; +} diff --git a/chpsim.h b/chpsim.h index b033da4..d2554cb 100644 --- a/chpsim.h +++ b/chpsim.h @@ -24,6 +24,7 @@ #include #include "actsim.h" +#include /*--- CHP simulation data structures ---*/ @@ -103,6 +104,30 @@ struct chpsimstmt { /* --- Each unique process has a CHP sim graph associated with it --- */ +/** + * The overall information about the chpsim graph + * - g : the entry point into the graph + * - e : ? + * - max_count : number of slots needed to keep track of internal joins + * - max_stats : number of slots needed to keep track of any run-time + * - labels : map from label to chpsimgraph pointer + * statistics. + */ +class ChpSimGraph; + +struct chpsimgraph_info { + chpsimgraph_info() { + g = NULL; labels = NULL; e = NULL; max_count = 0; max_stats = 0; + } + ~chpsimgraph_info() { } + ChpSimGraph *g; + Expr *e; /* for probes, if needed */ + int max_count; + int max_stats; + struct Hashtable *labels; +}; + + class ChpSimGraph { public: ChpSimGraph (ActSimCore *); @@ -119,9 +144,10 @@ class ChpSimGraph { ChpSimGraph *completed (int pc, int *tot, int *done); void printStmt (FILE *fp, Process *p); - static ChpSimGraph *buildChpSimGraph (ActSimCore *, act_chp_lang_t *); + static chpsimgraph_info *buildChpSimGraph (ActSimCore *, act_chp_lang_t *); static int max_pending_count; static int max_stats; + static struct Hashtable *labels; static void checkFragmentation (ActSimCore *, ChpSim *, act_chp_lang_t *); static void checkFragmentation (ActSimCore *, ChpSim *, Expr *); @@ -136,18 +162,23 @@ class ChpSimGraph { }; + + + + /* --- each unique instance has a ChpSim object associated with it --- */ class ChpSim : public ActSimObj { public: - ChpSim (ChpSimGraph *, int maxcnt, int maxstats, - act_chp_lang_t *, ActSimCore *sim, Process *p); + ChpSim (chpsimgraph_info *, act_chp_lang_t *, ActSimCore *sim, Process *p); /* initialize simulation, and create initial event */ ~ChpSim (); int Step (Event *ev); /* run a step of the simulation */ void reStart (ChpSimGraph *g, int maxcnt); + + int jumpTo (const char *s); void computeFanout (); @@ -183,6 +214,9 @@ class ChpSim : public ActSimObj { int _npc; /* # of program counters */ int _pcused; /* # of _pc[] slots currently being used */ + + struct Hashtable *_labels; /* label map */ + ChpSimGraph **_pc; /* current PC state of simulation */ int *_holes; /* available slots in the _pc array */ int *_tot; /* current pending concurrent count */ @@ -244,6 +278,7 @@ class ChpSim : public ActSimObj { void _initEvent (); void _zeroAllIntsChans (ChpSimGraph *g); void _zeroStructure (struct chpsimderef *d); + }; diff --git a/config.in b/config.in index 0abbe2b..70dd51c 100644 --- a/config.in +++ b/config.in @@ -1 +1 @@ -N_CIR_XyceCInterface +#N_CIR_XyceCInterface diff --git a/main.cc b/main.cc index 7c3d02c..87bf140 100644 --- a/main.cc +++ b/main.cc @@ -489,6 +489,47 @@ int process_coverage (int argc, char **argv) return LISP_RET_TRUE; } +int process_goto (int argc, char **argv) +{ + ActId *id; + FILE *fp; + if (argc != 3 && argc != 2) { + fprintf (stderr, "Usage: %s []