p.print("      BUFFER_"+_s2+"_"+_d2+"[(HEAD_"+_s2+"_"+_d2+" + "+y+") & __BUF_SIZE_MASK_"+_s2+"_"+_d2+"] = \n");
p.print("      BUFFER_"+_s2+"_"+_d2+"[(HEAD_"+_s2+"_"+_d2+" + "+offs+") & __BUF_SIZE_MASK_"+_s2+"_"+_d2+"] = \n");
    public static void generateJoiner(FlatNode node) {    		SIRJoiner joiner = (SIRJoiner)node.contents;	if (joiner.getSumOfWeights() == 0) {	    // The joiner is not doing any work	    	    return;	}	int init_counts, steady_counts;	Integer init_int = (Integer)ClusterBackend.initExecutionCounts.get(node);	if (init_int==null) {	    init_counts = 0;	} else {	    init_counts = init_int.intValue();	}	steady_counts = ((Integer)ClusterBackend.steadyExecutionCounts.get(node)).intValue();	CType baseType = Util.getBaseType(Util.getJoinerType(node));	int thread_id = NodeEnumerator.getSIROperatorId(node.contents);	Vector in = (Vector)RegisterStreams.getNodeInStreams(node.contents);	Vector out_v = (Vector)RegisterStreams.getNodeOutStreams(node.contents);	NetStream out = (NetStream)out_v.elementAt(0);	TabbedPrintWriter p;	StringWriter str; 		str = new StringWriter();        p = new TabbedPrintWriter(str);			ClusterCodeGenerator gen = new ClusterCodeGenerator(joiner, new JFieldDeclaration[0]);	p.print("// init counts: "+init_counts+" steady counts: "+steady_counts+"\n"); 	p.print("\n");	//  +=============================+	//  | Preamble                    |	//  +=============================+     	Vector pre = gen.generatePreamble();	for (int i = 0; i < pre.size(); i++) {	    p.print(pre.elementAt(i).toString());	}	//  +=============================+	//  | Joiner Pop                  |	//  +=============================+	int sum_of_weights = joiner.getSumOfWeights();	p.print(baseType.toString()+" "+out.pop_buffer()+"["+sum_of_weights+"];\n");	p.print("int "+out.pop_index()+" = "+sum_of_weights+";\n");	p.print("\n");	p.print(baseType.toString()+" "+out.pop_name()+"() {\n");	p.print("  if ("+out.pop_index()+" == "+sum_of_weights+") {\n");	int _offs = 0;	for (int i = 0; i < in.size(); i++) {	    int num = joiner.getWeight(i);	    NetStream s = (NetStream)in.elementAt(i);	    FlatNode source = NodeEnumerator.getFlatNode(s.getSource());	    if (ClusterFusion.fusedWith(node).contains(source)) {		for (int y = 0; y < num; y++) {		    p.print("    "+out.pop_buffer()+"["+(_offs + y)+"] = "+s.pop_name()+"();\n");		}	    } else {		p.print("    "+s.consumer_name()+".pop_items(&"+out.pop_buffer()+"["+_offs+"], "+num+");\n");	    }	    _offs += num;	}	p.print("    "+out.pop_index()+" = 0;\n");	p.print("  }\n");		p.print("  return "+out.pop_buffer()+"["+out.pop_index()+"++];\n");	p.print("}\n");	p.print("\n");	//  +=============================+	//  | Joiner Work                 |	//  +=============================+	int _s = out.getSource();	int _d = out.getDest();	p.print("#ifdef __FUSED_"+_s+"_"+_d+"\n");	p.print("extern "+baseType.toString()+" BUFFER_"+_s+"_"+_d+"[];\n");	p.print("extern int HEAD_"+_s+"_"+_d+";\n");	p.print("extern int TAIL_"+_s+"_"+_d+";\n");	p.print("#endif\n");	for (int o = 0; o < in.size(); o++) {	    _s = ((NetStream)in.elementAt(o)).getSource();	    _d = ((NetStream)in.elementAt(o)).getDest();	    p.print("#ifdef __FUSED_"+_s+"_"+_d+"\n");	    p.print("extern "+baseType.toString()+" BUFFER_"+_s+"_"+_d+"[];\n");	    p.print("extern int HEAD_"+_s+"_"+_d+";\n");	    p.print("extern int TAIL_"+_s+"_"+_d+";\n");	    p.print("#endif\n");	}	p.print("\n");	p.print("void __joiner_"+thread_id+"_work(int ____n) {\n");	p.print("  for (;____n > 0; ____n--) {\n");	FlatNode dest_flat = NodeEnumerator.getFlatNode(out.getSource());	if (joiner.getType().equals(SIRJoinType.ROUND_ROBIN) || 	    joiner.getType().equals(SIRJoinType.WEIGHTED_RR)) {	    if (joiner.getParent() instanceof SIRFeedbackLoop) {				//		// Joiner is a part of feedback Loop		//		p.print("  "+baseType.toString()+" tmp;\n");				for (int i = 0; i < in.size(); i++) {		    		    NetStream s = (NetStream)in.elementAt(i);				    int num = joiner.getWeight(i);		    		    for (int ii = 0; ii < num; ii++) {						if (i == 1 && joiner.getParent() instanceof SIRFeedbackLoop) {			    int delay =  ((SIRFeedbackLoop)joiner.getParent()).getDelayInt();			    p.print("  if (__init_counter_"+thread_id+" < "+delay+") {\n");			    p.print("    tmp = __Init_Path_"+thread_id+"(__init_counter_"+thread_id+");\n");			    p.print("    __init_counter_"+thread_id+"++;\n");			    p.print("  } else\n");			    p.print("    tmp = "+s.consumer_name()+".pop();\n");			    			} else {			    			    p.print("  tmp = "+s.consumer_name()+".pop();\n");			}						p.print("  "+out.producer_name()+".push(tmp);\n");		    }		    		}	    } else {		//		// Joiner is NOT a part of feedback Loop		//		int sum = joiner.getSumOfWeights();		int offs = 0;		int _s2 = out.getSource();		int _d2 = out.getDest();		for (int i = 0; i < in.size(); i++) {		    int num = joiner.getWeight(i);		    NetStream s = (NetStream)in.elementAt(i);				    int _s1 = s.getSource();		    int _d1 = s.getDest();		    for (int y = 0; y < num; y++) {			// Destination	    			p.print("  #ifdef __FUSED_"+_s2+"_"+_d2+"\n");			p.print("    #ifdef __NOPEEK_"+_s2+"_"+_d2+"\n");			p.print("      BUFFER_"+_s2+"_"+_d2+"[HEAD_"+_s2+"_"+_d2+" + "+y+"] = \n");			p.print("    #else\n");			p.print("      BUFFER_"+_s2+"_"+_d2+"[(HEAD_"+_s2+"_"+_d2+" + "+y+") & __BUF_SIZE_MASK_"+_s2+"_"+_d2+"] = \n");			p.print("    #endif\n");			p.print("  #else\n");			if (ClusterFusion.fusedWith(node).contains(dest_flat)) {			    p.print("    "+out.push_name()+"(\n");			} else {			    p.print("    "+out.producer_name()+".push(\n");			}			p.print("  #endif\n");						// Source						p.print("  #ifdef __FUSED_"+_s1+"_"+_d1+"\n");			p.print("    #ifdef __NOPEEK_"+_s1+"_"+_d1+"\n");			p.print("      BUFFER_"+_s1+"_"+_d1+"[TAIL_"+_s1+"_"+_d1+" + "+y+"]\n");			p.print("    #else\n");			p.print("      BUFFER_"+_s1+"_"+_d1+"[(TAIL_"+_s1+"_"+_d1+" + "+y+") & __BUF_SIZE_MASK_"+_s1+"_"+_d1+"]\n");			p.print("    #endif\n");			p.print("  #else\n");			p.print("    "+s.consumer_name()+".pop()\n");			p.print("  #endif\n");						// Close Assignement to Dest or Push Operator						p.print("  #ifdef __FUSED_"+_s2+"_"+_d2+"\n");			p.print("    ; // assignement\n");			p.print("  #else\n");		    			p.print("    ); // push()\n");			p.print("  #endif\n");						offs++;		    }		    		    p.print("  TAIL_"+_s1+"_"+_d1+" += "+num+";\n");		    p.print("  #ifndef __NOPEEK_"+_s1+"_"+_d1+"\n");		    p.print("  TAIL_"+_s1+"_"+_d1+" &= __BUF_SIZE_MASK_"+_s1+"_"+_d1+";\n");		    p.print("  #endif\n");		    		}				p.print("  HEAD_"+_s2+"_"+_d2+" += "+sum+";\n");		p.print("  #ifndef __NOPEEK_"+_s2+"_"+_d2+"\n");		p.print("  HEAD_"+_s2+"_"+_d2+" &= __BUF_SIZE_MASK_"+_s2+"_"+_d2+";\n");		p.print("  #endif\n");		/*		int sum = joiner.getSumOfWeights();		int offs = 0;				p.print("  "+baseType.toString()+" tmp["+sum+"];\n");		p.print("\n");		for (int i = 0; i < in.size(); i++) {		    int num = joiner.getWeight(i);		    NetStream s = (NetStream)in.elementAt(i);				    _s = s.getSource();		    _d = s.getDest();		    p.print("  #ifdef __FUSED_"+_s+"_"+_d+"\n");		    for (int y = 0; y < num; y++) {			p.print("    #ifdef __NOPEEK_"+_s+"_"+_d+"\n");			p.print("    tmp["+(offs+y)+"] = BUFFER_"+_s+"_"+_d+"[TAIL_"+_s+"_"+_d+"];TAIL_"+_s+"_"+_d+"++;\n");			p.print("    #else\n");			p.print("    tmp["+(offs+y)+"] = BUFFER_"+_s+"_"+_d+"[TAIL_"+_s+"_"+_d+"];TAIL_"+_s+"_"+_d+"++;TAIL_"+_s+"_"+_d+"&=__BUF_SIZE_MASK_"+_s+"_"+_d+";\n");			p.print("    #endif\n");					    }		    p.print("  #else\n");		    p.print("  "+s.consumer_name()+".pop_items(&tmp["+offs+"], "+num+");\n");		    p.print("  #endif\n");		    		    offs += num;		    		}		p.print("\n");		_s = out.getSource();		_d = out.getDest();		p.print("  #ifdef __FUSED_"+_s+"_"+_d+"\n");		for (int y = 0; y < sum; y++) {		    p.print("    #ifdef __NOPEEK_"+_s+"_"+_d+"\n");		    p.print("    BUFFER_"+_s+"_"+_d+"[HEAD_"+_s+"_"+_d+"]=tmp["+y+"];HEAD_"+_s+"_"+_d+"++;\n");		    p.print("    #else\n");		    p.print("    BUFFER_"+_s+"_"+_d+"[HEAD_"+_s+"_"+_d+"]=tmp["+y+"];HEAD_"+_s+"_"+_d+"++;HEAD_"+_s+"_"+_d+"&=__BUF_SIZE_MASK_"+_s+"_"+_d+";\n");		    p.print("    #endif\n");		}		p.print("  #else\n");				p.print("  "+out.producer_name()+".push_items(tmp, "+sum+");\n");		p.print("  #endif\n");		*/	    }	}	p.print("  }\n");	p.print("}\n");	p.print("\n");	//  +=============================+	//  | Joiner Main                 |	//  +=============================+	p.print("void __joiner_"+thread_id+"_main() {\n");	p.print("  int i, ii;\n");		p.print("  if (__steady_"+thread_id+" == 0) {\n");	p.print("    for (i = 0; i < "+init_counts+"; i++) {\n");	p.print("      check_thread_status(__state_flag_"+thread_id+",__thread_"+thread_id+");\n");	p.print("      __joiner_"+thread_id+"_work(1);\n");	p.print("    }\n");	p.print("  }\n");	p.print("  __steady_"+thread_id+"++;\n");	p.print("  for (i = 1; i <= __number_of_iterations_"+thread_id+"; i++, __steady_"+thread_id+"++) {\n");		p.print("    for (ii = 0; ii < "+steady_counts+"; ii++) {\n");	p.print("      check_thread_status(__state_flag_"+thread_id+",__thread_"+thread_id+");\n");	p.print("      __joiner_"+thread_id+"_work(1);\n");	p.print("    }\n");	p.print("    if (__frequency_of_chkpts != 0 && i % __frequency_of_chkpts == 0) save_state::save_to_file(__thread_"+thread_id+", __steady_"+thread_id+", __write_thread__"+thread_id+");\n");	p.print("  }\n");	p.print("}\n");		//  +=============================+	//  | Run Function                |	//  +=============================+	Vector run = gen.generateRunFunction(null, "__joiner_"+thread_id+"_main");	for (int i = 0; i < run.size(); i++) {	    p.print(run.elementAt(i).toString());	}	//  +=============================+	//  | Write Joiner to File        |	//  +=============================+	try {	    FileWriter fw = new FileWriter("thread"+thread_id+".cpp");	    fw.write(str.toString());	    fw.close();	}	catch (Exception e) {	    System.err.println("Unable to write joiner code to file thread"+thread_id+".cpp");	}	System.out.println("Code for " + node.contents.getName() +			   " written to thread"+thread_id+".cpp");    }