00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_BARRIER_TREE_TRIGGERED_H
00014 #define COMPONENTS_TRIG_CPU_BARRIER_TREE_TRIGGERED_H
00015
00016 #include "algorithm.h"
00017 #include "trig_cpu.h"
00018 #include "portals.h"
00019
00020 class barrier_tree_triggered : public algorithm {
00021 public:
00022 barrier_tree_triggered(trig_cpu *cpu) : algorithm(cpu), init(false)
00023 {
00024 radix = cpu->getRadix();
00025 ptl = cpu->getPortalsHandle();
00026
00027
00028 boost::tie(my_root, my_children) = buildBinomialTree(radix);
00029 num_children = my_children.size();
00030 }
00031
00032 bool
00033 operator()(Event *ev)
00034 {
00035 ptl_md_t md;
00036 ptl_me_t me;
00037
00038 crBegin();
00039
00040 if (!init) {
00041
00042 ptl->PtlCTAlloc(PTL_CT_OPERATION, up_tree_ct_h);
00043 crReturn();
00044 me.start = NULL;
00045 me.length = 0;
00046 me.match_bits = 0;
00047 me.ignore_bits = 0;
00048 me.ct_handle = up_tree_ct_h;
00049 ptl->PtlMEAppend(PT_UP, me, PTL_PRIORITY_LIST, NULL, up_tree_me_h);
00050 crReturn();
00051
00052 ptl->PtlCTAlloc(PTL_CT_OPERATION, down_tree_ct_h);
00053 crReturn();
00054 me.start = NULL;
00055 me.length = 0;
00056 me.match_bits = 0;
00057 me.ignore_bits = 0;
00058 me.ct_handle = down_tree_ct_h;
00059 ptl->PtlMEAppend(PT_DOWN, me, PTL_PRIORITY_LIST, NULL, down_tree_me_h);
00060 crReturn();
00061
00062 md.start = NULL;
00063 md.length = 0;
00064 md.eq_handle = PTL_EQ_NONE;
00065 md.ct_handle = PTL_CT_NONE;
00066 ptl->PtlMDBind(md, &my_md_h);
00067 crReturn();
00068
00069 init = true;
00070 }
00071
00072
00073 start_time = cpu->getCurrentSimTimeNano();
00074 cpu->addBusyTime("200ns");
00075 crReturn();
00076
00077 if (num_children == 0) {
00078 ptl->PtlPut(my_md_h, 0, 0, 0, my_root, PT_UP, 0, 0, NULL, 0);
00079 crReturn();
00080 } else {
00081 if (my_id != my_root) {
00082 ptl->PtlTriggeredPut(my_md_h, 0, 0, 0, my_root, PT_UP, 0, 0, NULL, 0,
00083 up_tree_ct_h, num_children);
00084 crReturn();
00085 } else {
00086 ptl->PtlTriggeredCTInc(down_tree_ct_h, 1, up_tree_ct_h, num_children);
00087 crReturn();
00088 }
00089 ptl->PtlTriggeredCTInc(up_tree_ct_h, -num_children,
00090 up_tree_ct_h, num_children);
00091 crReturn();
00092
00093 for (i = 0 ; i < num_children ; ++i) {
00094 ptl->PtlTriggeredPut(my_md_h, 0, 0, 0, my_children[i], PT_DOWN,
00095 0, 0, NULL, 0, down_tree_ct_h, 1);
00096 crReturn();
00097 }
00098 }
00099
00100 while (!ptl->PtlCTWait(down_tree_ct_h, 1)) { crReturn(); }
00101 crReturn();
00102 ptl->PtlTriggeredCTInc(down_tree_ct_h, -1, down_tree_ct_h, 1);
00103 crReturn();
00104
00105 trig_cpu::addTimeToStats(cpu->getCurrentSimTimeNano()-start_time);
00106
00107 crFinish();
00108 return true;
00109 }
00110
00111 private:
00112 barrier_tree_triggered();
00113 barrier_tree_triggered(const algorithm& a);
00114 void operator=(barrier_tree_triggered const&);
00115
00116 portals *ptl;
00117
00118 SimTime_t start_time;
00119 int radix;
00120 bool init;
00121
00122 ptl_handle_ct_t up_tree_ct_h;
00123 ptl_handle_me_t up_tree_me_h;
00124
00125 ptl_handle_ct_t down_tree_ct_h;
00126 ptl_handle_me_t down_tree_me_h;
00127
00128 ptl_handle_md_t my_md_h;
00129
00130 int i;
00131 int my_root;
00132 std::vector<int> my_children;
00133 int num_children;
00134
00135 static const int PT_UP = 0;
00136 static const int PT_DOWN = 1;
00137 };
00138
00139 #endif // COMPONENTS_TRIG_CPU_BARRIER_TREE_TRIGGERED_H