// C++/CSIM Model fork-join queue

#include "cpp.h"			// class definitions

#define NARS 50000
#define IAR_TM 2.0
#define SRV_TM 1.0

event done("done");			// the event named done
facility_set  f("facility", 2);         // the facility named f
table tbl("resp tms");			// table of response times
int cnt;				// count of remaining processes

void traffic();
void customer();
void task(int i, event *ev);

extern "C" void sim(int, char **);

void sim(int argc, char *argv[])
{
	set_model_name("Two Servers with JSQ");
	create("sim");

	cnt = NARS;
	
	traffic();			// generate traffic

	done.wait();			// wait for last customer to depart
	report();			// model report
	mdlstat();			// model statistics
}

void traffic()
{
	int i;

	create("traffic");    


        for (i=1; i<= NARS;i++){ 
              hold(expntl(IAR_TM));
	      customer();
        }
}
	
void customer()				// arriving customer
{
	double t1;
        int i, count;

	create("cust");
     
        event task_done_event("task_done"); // create event for task synchronization
        count = 0;

	t1 = clock;			// record start time

	for (i=0; i < 2; i++)
            task(i, &task_done_event);

	while (count != 2){ // wait for all tasks to complete 
          task_done_event.clear();
          task_done_event.wait();
          count++;
        }

        // the customer can leave the system 
        tbl.record(clock-t1);
        if (--cnt == 0)
           done.set();
}


void task(int i, event *task_done_event)
{
	create("task");

	f[i].reserve();      // task is assigned to server i
	   hold(expntl(SRV_TM));
	f[i].release();
	task_done_event->set();
}

