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