Signed-off-by: Nicolas Morey-Chaisemartin 
<[email protected]>
---
 opensm/opensm/osm_ucast_ftree.c |  107 ++++++++++++++++++++++++++-------------
 1 files changed, 72 insertions(+), 35 deletions(-)

diff --git a/opensm/opensm/osm_ucast_ftree.c b/opensm/opensm/osm_ucast_ftree.c
index b00cf4a..501c269 100644
--- a/opensm/opensm/osm_ucast_ftree.c
+++ b/opensm/opensm/osm_ucast_ftree.c
@@ -81,7 +81,6 @@ typedef enum {
  **  Forward references
  **
  ***************************************************/
-
 struct ftree_sw_t_;
 struct ftree_hca_t_;
 struct ftree_port_t_;
@@ -174,6 +173,7 @@ typedef struct ftree_sw_t_ {
        boolean_t is_leaf;
        unsigned down_port_groups_idx;
        uint32_t min_counter_down;
+       boolean_t counter_up_changed;
 } ftree_sw_t;
 
 /***************************************************
@@ -1905,7 +1905,7 @@ static void __osm_ftree_set_sw_fwd_table(IN cl_map_item_t 
* const p_map_item,
                                    p_sw->p_osm_sw);
 }
 
-static void
+static inline void
 __osm_ftree_recalculate_min_counter_down(ftree_sw_t *p_sw){
        uint32_t min= (1<<30);
        uint32_t i;
@@ -1918,23 +1918,16 @@ __osm_ftree_recalculate_min_counter_down(ftree_sw_t 
*p_sw){
        return;
 }
 
-static uint32_t
+static inline uint32_t
 __osm_ftree_find_lowest_loaded_group_on_sw(ftree_sw_t *p_sw){
-       /*uint32_t min= (1<<30);
-               uint32_t i;
-       for(i=0;i < p_sw->down_port_groups_num; i++) {
-               if(p_sw->down_port_groups[i]->counter_down < min){
-                       min = p_sw->down_port_groups[i]->counter_down;
-               }
-               }*/
        return p_sw->min_counter_down;
 }
 
 /* This is for downgoing_by_going_up.
  * If load are equals, let's have a look at the remote switches and find the 
less loaded one */
-static int
-__osm_ftree_port_group_compare_load_down(const void* p1,const void* p2){
-       int temp = (*((ftree_port_group_t**)p1))->counter_down 
-(*((ftree_port_group_t**)p2))->counter_down ;
+static inline int
+__osm_ftree_port_group_compare_load_down(const ftree_port_group_t *p1,const 
ftree_port_group_t *p2){
+       int temp = p1->counter_down -p2->counter_down ;
        if(temp > 0)
                return 1;
        if(temp < 0)
@@ -1942,32 +1935,78 @@ __osm_ftree_port_group_compare_load_down(const void* 
p1,const void* p2){
 
        /* Find the less loaded remote sw and choose this one */
        do{
-               uint32_t 
load1=__osm_ftree_find_lowest_loaded_group_on_sw((*((ftree_port_group_t**)p1))->remote_hca_or_sw.p_sw);
-               uint32_t 
load2=__osm_ftree_find_lowest_loaded_group_on_sw((*((ftree_port_group_t**)p2))->remote_hca_or_sw.p_sw);
+               uint32_t 
load1=__osm_ftree_find_lowest_loaded_group_on_sw(p1->remote_hca_or_sw.p_sw);
+               uint32_t 
load2=__osm_ftree_find_lowest_loaded_group_on_sw(p2->remote_hca_or_sw.p_sw);
                temp = load1-load2;
                if(temp > 0)
                        return 1;
-               if(temp < 0)
-                       return -1;
+               return 0;
        }while(0);
 
-       /* If they are both equal, choose the biggest GUID */
-       if(((*((ftree_port_group_t**)p1)))->remote_port_guid > 
((*((ftree_port_group_t**)p2)))->remote_port_guid)
-               return 1;
+}
 
-       return -1;
+static inline void
+__osm_ftree_bubble_sort_up(ftree_port_group_t **p_group_array, uint32_t nmemb)
+{
+        uint32_t i   = 0; /* Indice de répétition du tri */
+        uint32_t j   = 0; /* Variable de boucle */
+        ftree_port_group_t *tmp = p_group_array[0]; /* Variable de stockage 
temporaire et de fin de tri*/
+       if(tmp->hca_or_sw.p_sw->counter_up_changed == FALSE){
+               return;
+       }
+        /* Boucle de répétition du tri et le test qui
+           arrête le tri dès que le tableau est ordonné */
+        for(i = 0 ; tmp ; i++)
+        {
+                /* Supposons le tableau ordonné */
+                tmp = NULL;
+                /* Vérification des éléments des places j et j-1 */
+                for(j = 1 ; j < (nmemb - i) ; j++)
+                {
+                        /* Si les 2 éléments sont mal triés */
+                        if( p_group_array[j]->counter_up < 
p_group_array[j-1]->counter_up)
+                        {
+                                /* Inversion des 2 éléments */
+                                tmp = p_group_array[j-1];
+                                p_group_array[j-1] = p_group_array[j];
+                               p_group_array[j] = tmp;
+
+                        }
+                }
+        }
+        p_group_array[0]->hca_or_sw.p_sw->counter_up_changed = FALSE;
 }
 
-/* This is for upgoing_by_going_down. There is not much equilibration to do so 
don't bother looking at the next rank */
-static int
-__osm_ftree_port_group_compare_load_up(const void* p1,const void* p2){
-       int temp = (*((ftree_port_group_t**)p1))->counter_up 
-(*((ftree_port_group_t**)p2))->counter_up ;
-       if(temp > 0)
-               return 1;
-       if(temp < 0)
-               return -1;
-       return 0;
+static inline void
+__osm_ftree_bubble_sort_down(ftree_port_group_t **p_group_array, uint32_t 
nmemb)
+{
+        uint32_t i   = 0; /* Indice de répétition du tri */
+        uint32_t j   = 0; /* Variable de boucle */
+        ftree_port_group_t *tmp = p_group_array[0]; ; /* Variable de stockage 
temporaire et de fin de tri*/
+
+        /* Boucle de répétition du tri et le test qui
+           arrête le tri dès que le tableau est ordonné */
+        for(i = 0 ; tmp ; i++)
+        {
+                /* Supposons le tableau ordonné */
+                tmp = NULL;
+                /* Vérification des éléments des places j et j-1 */
+                for(j = 1 ; j < (nmemb - i) ; j++)
+                {
+                        /* Si les 2 éléments sont mal triés */
+                        if( 
__osm_ftree_port_group_compare_load_down(p_group_array[j],p_group_array[j-1]) < 
0 )
+                       {
+                                /* Inversion des 2 éléments */
+                                tmp = p_group_array[j-1];
+                                p_group_array[j-1] = p_group_array[j];
+                                p_group_array[j] = tmp;
+
+                        }
+                }
+        }
 }
+
+
 /***************************************************
  ***************************************************/
 
@@ -2013,10 +2052,7 @@ __osm_ftree_fabric_route_upgoing_by_going_down(IN 
ftree_fabric_t * p_ftree,
                return FALSE;
 
        /* foreach down-going port group (in indexing order) */
-
-       
qsort(p_sw->down_port_groups,p_sw->down_port_groups_num,sizeof(*(p_sw->down_port_groups)),
 __osm_ftree_port_group_compare_load_up);
-
-
+       
__osm_ftree_bubble_sort_up(p_sw->down_port_groups,p_sw->down_port_groups_num);
        for (k = 0; k < p_sw->down_port_groups_num; k++) {
 
                p_group = p_sw->down_port_groups[k];
@@ -2158,6 +2194,7 @@ __osm_ftree_fabric_route_upgoing_by_going_down(IN 
ftree_fabric_t * p_ftree,
                if(routed)
                        p_min_port->counter_up++;
                        p_group->counter_up++;
+                       p_group->hca_or_sw.p_sw->counter_up_changed = TRUE;
                }
 
        /* done scanning all the down-going port groups */
@@ -2257,7 +2294,7 @@ __osm_ftree_fabric_route_downgoing_by_going_up(IN 
ftree_fabric_t * p_ftree,
 
        /* We should generate a list of port sorted by load so we can find 
easily the least
         * going port and explore the other pots on secondary routes more 
easily (and quickly) */
-       
qsort(p_sw->up_port_groups,p_sw->up_port_groups_num,sizeof(*(p_sw->up_port_groups)),
 __osm_ftree_port_group_compare_load_down);
+       
__osm_ftree_bubble_sort_down(p_sw->up_port_groups,p_sw->up_port_groups_num);
 
        p_min_group = p_sw->up_port_groups[0];
 
-- 
1.6.2-rc2.GIT

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to