Reference Guide Appendix: A3
A3. Source code for Hierarchical Clock Model Test Programs
/*
* testblk
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <strio.h>
#include <num_ent.h>
#include <block.h>
#include <digraph.h>
#include “genr.h”
#include “transd.h”
#include “scell.h”
int main(int argc, char ** argv)
{
int i, j;
float amount;
scell *nc;
digraph *tmpdig;
int maxiter, maxsimtime, pause;
// **************************************************
// relationship between genr & transd
// **************************************************
genr * g;
transd * t;
g = new genr(“g”,5); // int_arr_time
t = new transd(“t”,20); // int_arr_time
block * top1, top2;
top1 = new block(“top1”);
top2 = new block(“top2”);
int rowmin, rownum, colmin, colnum;
rowmin = 1;
rownum = 4;
colmin = 1;
colnum = 4;
for (i=rownum;i>=rowmin;i–) { // left half cells
for (j=(colnum+colmin-1)/2;j>=colmin;j–) {
top1->add(new scell(name_gen(“c”,i,j),new addrclass(i,j)));
}
}
for (i=rownum;i>=rowmin;i–) { // right half cells
for (j=colnum;j>=(1+colnum+colmin)/2;j–) {
top2->add(new scell(name_gen(“c”,i,j),new addrclass(i,j)));
}
}
// **************************************************
// relationship between ef and genr & transd
// **************************************************
digraph *efsim, *ef;
efsim = new digraph(“efsim”);
ef = new digraph(“ef”);
ef->add(g);
ef->add(t);
efsim->add(ef);
efsim->add(top1);
efsim->add(top2);
top1->add_coupling(“out”, “in”);
top1->add_coupling(“in”, “in”);
top2->add_coupling(“out”, “in”);
top2->add_coupling(“in”, “in”);
efsim->get_inports()->add(“start”);
ef->get_inports()->add(“start”);
g->get_inports()->add(“stop”);
efsim->add_coupling(efsim, “start”, ef, “start”);
ef->add_coupling(ef, “start”, g, “start”);
g->add_coupling(g, “out”, t, “ariv”);
g->add_coupling(g, “out”, ef, “out”);
t->add_coupling(t, “out”, g, “stop”);
ef->add_coupling(ef, “out”, top1, “in”);
top1->add_coupling(top1, “out”, top2, “in”);
top2->add_coupling(top2, “out”, ef, “in”);
ef->add_coupling(ef, “in”, t, “solved”);
efsim->initialize();
efsim->inject(“start”, new entity(“a”));
efsim->start_sim(argc, argv);
return 0;
}
/*
* scell.h
*/
#ifndef _SCELL_H_
#define _SCELL_H_
#include <cell.h>
class scell:public cell {
protected:
int processing_time;
entity * store;
public:
scell(char * name, addrclass * location);
void deltint(timetype e);
void deltext(timetype e,message * x);
message * out(timetype e );
};
#endif
/*
* scell.C
*/
#include <string.h>
#include <num_ent.h>
#include “scell.h”
extern int rownum,colnum, rowmin, colmin;
scell::scell(char * name,addrclass * location):cell(name,location) {
phases->add(“busy”);
this->processing_time = 1 ;
passivate();
}
//
// External Transition Function
//
void scell::deltext(timetype e,message * x) {
if(x->empty()) return; // for timing sync
Continue();
element *el, *elnext;
for (el=x->get_head(); el!=NULL;el=elnext) {
elnext = el->get_right();
x->remove(el);
content *con;
con = (content *)el->get_ent();
if(strcmp(con->p,”stop”)==0) passivate();
if(strcmp(con->p,”in”)==0) {
store = con->val;
hold_in(“busy”,processing_time);
}
}
}
/*
* Internal transition Function
*/
void scell::deltint() {
passivate();
}
message * scell::out() {
message * m;
addrclass * addr;
content * con;
m = new message();
addr = new addrclass(my_location->i + 1, my_location->j);
con = make_content_address(“out”,(entity *)store, addr);
store = NULL;
m->add(con);
m->show_message();
return m;
}
/*
* genr.h
*/
#ifndef _GENRH_
#define _GENRH_
#include <atomic.h>
class genr:public atomic {
protected:
timetype int_arr_time;
entity * ent;
int num;
public:
genr(char * name,timetype int_arr_time) ;
void deltext(timetype,message *) ;
void deltint(timetype e) ;
message * out(timetype e );
};
#endif
/*
* genr.C
*/
#include “genr.h”
#include <element.h>
#include <bag.h>
#include <string.h>
#include <strio.h>
genr::genr(char * name,timetype int_arr_time):atomic(name) {
this->int_arr_time = int_arr_time ;
num = 0;
phases->add(“active”);
passivate();
}
void genr::deltext(timetype e,message * x) {
Continue();
element *el, *elnext;
for (el=x->get_head(); el!=NULL;el=elnext) {
elnext = el->get_right();
x->remove(el);
content *con;
con = (content *)el->get_ent();
if(strcmp(con->p,”stop”)==0) passivate();
if(strcmp(con->p,”start”)==0) hold_in(“active”,int_arr_time);
}
}
void genr::deltint(timetype e) {
hold_in(“active”,int_arr_time);
}
message * genr::out(timetype e ) {
message * m = new message();
char * s;
content *con;
num++;
con = make_content_address(“out”, new entity(name_gen(“job”,num)),
new addrclass(1,1));
m->add(con);
return m;
}
/*
* transd.h
*/
#ifndef _TRANSDH_
#define _TRANSDH_
#include <atomic.h>
#include <relation.h>
class transd:public atomic{
protected:
relation *arrived, *solved;
timetype clock,total_ta,observation_time;
public:
transd(char * name,timetype observ_time);
void deltcon(timetype,message *);
void deltext(timetype,message *);
void deltint(timetype e);
message * out(timetype e );
};
#endif
/*
* transd.C
*/
#include “transd.h”
class number:public entity {
private:
float NUMBER;
public:
number(float i):NUMBER(i){}
float get_number(){return NUMBER;}
void print(){cout << “number: ” << NUMBER;}
};
transd::transd(char * name,timetype observation_time):atomic(name) {
inports->add(“ariv”);
inports->add(“solved”);
outports->add(“stop”);
phases->add(“active”);
arrived = new relation();
solved = new relation();
this->observation_time = observation_time;
clock = 0.0;
total_ta = 0.0;
hold_in(“active”,observation_time);
}
void transd::deltcon(timetype e,message * x) {
deltint(e);
deltext(e, x);
}
void transd::deltext(timetype e,message * x) {
clock = clock + e;
element *el, *elnext;
content *con;
for (el = x->get_head();el != NULL;el = elnext) {
elnext = el->get_right();
con = (content *) el->get_ent();
if (strcmp(con->p,”ariv”) == 0) {
arrived->add(con->val,new number(clock));
}
else if (strcmp(con->p,”solved”) == 0) {
if (arrived->key_name_is_in(con->val->get_name())) {
entity * ent;
number * num;
timetype arrival_time, turn_around_time;
ent = arrived->assoc(con->val->get_name());
num = (number *) ent;
arrival_time = num->get_number();
turn_around_time = clock – arrival_time;
total_ta = total_ta + turn_around_time;
solved->add(con->val, new number(clock));
}
else {
cerr << “arriving job ” ; con->val->print();cout << ” did not arrived!”;
exit(1);
}
}
else {
cout << “port error” << endl;
exit(1);
}
delete (addrclass *)con->address;
delete con;
}
Continue();
}
void transd::deltint(timetype e) {
passivate();
}
message * transd::out(timetype e ) {
timetype avg_ta_time;
avg_ta_time = 0;
if (!solved->empty()) avg_ta_time = total_ta/solved->get_length();
float throughput;
if (clock > 0) throughput = solved->get_length()/clock;
else throughput = 0;
char a[10], b[10];
strcpy(a, arrived->get_head()->get_ent()->get_name());
strcpy(b, solved->get_head()->get_ent()->get_name());
if ( strcmp(a,b)==0 ) {
cout << endl;
cout << “*** TEST SATISFIED ***” << endl;
cout << endl;
}
else {
cout << endl;
cout << “test NOT satisfied” << endl;
cout << endl;
}
cout << “jobs arrived :” ;
arrived->print();
cout << “jobs solved :” ;
solved->print();
cout << endl;
cout << “AVG TA = ” << avg_ta_time <<endl;
cout << “THROUGHPUT = ” << throughput <<endl;
cout << endl;
message * m;
content * con;
m = new message();
con = make_content(“out”,new entity(“finished”));
m->add(con);
return m;
}