Fixed memory leak inside ComlibStrategy/OneTimeMulticastStrategy. The message would
[charm.git] / src / ck-com / RingMulticastStrategy.C
1 /** 
2     @addtogroup ComlibCharmStrategy
3     @{
4     @file 
5 */
6
7 #include "RingMulticastStrategy.h"
8
9
10 void RingMulticastStrategy::createObjectOnSrcPe(ComlibSectionHashObject *obj, int npes, ComlibMulticastIndexCount *pelist) {
11
12   int next_pe = CkNumPes();
13   int acount = 0;
14   int min_dest = CkNumPes();
15     
16   //Equivalent to sorting the list of destination processors and
17   //sending the message to the next processor greater than MyPE.
18   //If MyPE is the largest processor send it to minpe
19   for(acount = 0; acount < npes; acount++){
20         
21     int p = pelist[acount].pe;
22         
23     //Find the smallest destination
24     if(p < min_dest) min_dest = p;
25         
26     //If there is a processor greater than me and less than next_pe
27     //then he is my next_pe
28     if(p > CkMyPe() && next_pe > p) next_pe = p;       
29
30   }
31   
32   //Recycle the destination pelist and start from the begining
33   if(next_pe == CkNumPes() && min_dest != CkMyPe()) next_pe = min_dest;
34   
35   if(next_pe == CkNumPes()) next_pe = -1;
36
37   if(next_pe != -1) {
38     obj->pelist = new int[1];
39     obj->npes = 1;
40     obj->pelist[0] = next_pe;
41   }
42   else {
43     obj->pelist = NULL;
44     obj->npes = 0;
45   }
46 }
47
48 void RingMulticastStrategy::createObjectOnIntermediatePe(ComlibSectionHashObject *obj,  int npes, ComlibMulticastIndexCount *counts, int src_pe) {
49
50   obj->pelist = new int[1];
51   obj->npes = 1;
52   obj->pelist[0] = CkMyPe(); // this is neutral for the if inside next loop
53
54   // find the next processor in the ring
55   for (int i=0; i<npes; ++i) {
56     if (obj->pelist[0] > CkMyPe()) { // we have already found a processor greater
57                                      // than us, find the smallest among them
58       if (counts[i].pe > CkMyPe() && counts[i].pe < obj->pelist[0])
59         obj->pelist[0] = counts[i].pe;
60     } else {  // we have not yet found a processor greater than us, stick with
61               // the smallest, or one greater than us
62       if (counts[i].pe < obj->pelist[0] || counts[i].pe > CkMyPe())
63         obj->pelist[0] = counts[i].pe;
64     }
65   }
66     
67   //here we check if have reached the end of the ring
68   if(obj->npes > 0 && isEndOfRing(*obj->pelist, src_pe)) {
69     delete [] obj->pelist;
70     obj->pelist = NULL;
71     obj->npes = 0;
72   }
73 }
74
75 //We need to end the ring, 
76 //    if next_pe is the same as the source_pe, or
77 //    if next_pe is the first processor in the ring, greater than srouce_pe.
78 //Both these comparisons are done in a 'cyclic' way with wraparounds.
79
80 int RingMulticastStrategy::isEndOfRing(int next_pe, int src_pe){
81     
82     if(next_pe < 0)
83         return 1;
84     
85     ComlibPrintf("[%d] isEndofring %d, %d\n", CkMyPe(), next_pe, src_pe);
86     
87     if(next_pe > CkMyPe()){
88         if(src_pe <= next_pe && src_pe > CkMyPe())
89             return 1;
90         
91         return 0;
92     }
93     
94     if(src_pe > CkMyPe() || src_pe <= next_pe)
95         return 1;
96     
97     return 0;
98 }
99
100 /*@}*/