[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC 04/25] Replace "/" operand with div64



From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

ARM does not have a division operator: division has to be implemented
in software.
On x86 and ia64 div64 falls back to a do_div based implementation.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 xen/common/keyhandler.c                        |    4 +-
 xen/common/lib.c                               |    9 ++++--
 xen/common/sched_credit.c                      |    7 +++--
 xen/common/sched_credit2.c                     |    5 ++-
 xen/common/sched_sedf.c                        |   30 ++++++++++++------------
 xen/common/timer.c                             |    7 ++++-
 xen/include/asm-ia64/linux/asm-generic/div64.h |    6 ++++
 xen/include/asm-x86/div64.h                    |    6 ++++
 8 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c
index 6071f09..1700b8a 100644
--- a/xen/common/keyhandler.c
+++ b/xen/common/keyhandler.c
@@ -392,10 +392,10 @@ static void read_clocks(unsigned char key)
     count++;
     printk("Synced stime skew: max=%"PRIu64"ns avg=%"PRIu64"ns "
            "samples=%"PRIu32" current=%"PRIu64"ns\n",
-           maxdif_stime, sumdif_stime/count, count, dif_stime);
+           maxdif_stime, div64(sumdif_stime, count), count, dif_stime);
     printk("Synced cycles skew: max=%"PRIu64" avg=%"PRIu64" "
            "samples=%"PRIu32" current=%"PRIu64"\n",
-           maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
+           maxdif_cycles, div64(sumdif_cycles, count), count, dif_cycles);
 }
 
 static struct keyhandler read_clocks_keyhandler = {
diff --git a/xen/common/lib.c b/xen/common/lib.c
index 4ae637c..2b543b0 100644
--- a/xen/common/lib.c
+++ b/xen/common/lib.c
@@ -3,6 +3,7 @@
 #include <xen/lib.h>
 #include <xen/types.h>
 #include <asm/byteorder.h>
+#include <asm/div64.h>
 
 /* for ctype.h */
 const unsigned char _ctype[] = {
@@ -418,14 +419,16 @@ uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 #endif            
         } l;
     } u, res;
-    uint64_t rl, rh;
+    uint64_t rl, rh, t;
 
     u.ll = a;
     rl = (uint64_t)u.l.low * (uint64_t)b;
     rh = (uint64_t)u.l.high * (uint64_t)b;
     rh += (rl >> 32);
-    res.l.high = rh / c;
-    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+
+    t = do_div(rh, c);
+    res.l.high = rh;
+    res.l.low = div64(((t << 32) + (rl & 0xffffffff)), c);
     return res.ll;
 #endif
 }
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 4fa6140..02f77ee 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -22,6 +22,7 @@
 #include <asm/atomic.h>
 #include <xen/errno.h>
 #include <xen/keyhandler.h>
+#include <asm/div64.h>
 
 /*
  * CSCHED_STATS
@@ -241,9 +242,9 @@ static void burn_credits(struct csched_vcpu *svc, s_time_t 
now)
     if ( (delta = now - svc->start_time) <= 0 )
         return;
 
-    credits = (delta*CSCHED_CREDITS_PER_MSEC + MILLISECS(1)/2) / MILLISECS(1);
+    credits = div64((delta*CSCHED_CREDITS_PER_MSEC + MILLISECS(1)/2), 
MILLISECS(1));
     atomic_sub(credits, &svc->credit);
-    svc->start_time += (credits * MILLISECS(1)) / CSCHED_CREDITS_PER_MSEC;
+    svc->start_time += div64(credits * MILLISECS(1), CSCHED_CREDITS_PER_MSEC);
 }
 
 static bool_t __read_mostly opt_tickle_one_idle = 1;
@@ -1570,7 +1571,7 @@ static void csched_tick_resume(const struct scheduler 
*ops, unsigned int cpu)
     prv = CSCHED_PRIV(ops);
 
     set_timer(&spc->ticker, now + MICROSECS(prv->tick_period_us)
-            - now % MICROSECS(prv->tick_period_us) );
+            - do_div(now, MILLISECS(prv->tick_period_us)) );
 }
 
 static struct csched_private _csched_priv;
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 73f7138..46f48db 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -25,6 +25,7 @@
 #include <xen/errno.h>
 #include <xen/trace.h>
 #include <xen/cpu.h>
+#include <asm/div64.h>
 
 #define d2printk(x...)
 //#define d2printk printk
@@ -273,12 +274,12 @@ struct csched_dom {
  */
 static s_time_t t2c(struct csched_runqueue_data *rqd, s_time_t time, struct 
csched_vcpu *svc)
 {
-    return time * rqd->max_weight / svc->weight;
+    return div64(time * rqd->max_weight, svc->weight);
 }
 
 static s_time_t c2t(struct csched_runqueue_data *rqd, s_time_t credit, struct 
csched_vcpu *svc)
 {
-    return credit * svc->weight / rqd->max_weight;
+    return div64(credit * svc->weight, rqd->max_weight);
 }
 
 /*
diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c
index 8bff90c..e8eab31 100644
--- a/xen/common/sched_sedf.c
+++ b/xen/common/sched_sedf.c
@@ -12,6 +12,7 @@
 #include <xen/softirq.h>
 #include <xen/time.h>
 #include <xen/errno.h>
+#include <asm/div64.h>
 
 /*verbosity settings*/
 #define SEDFLEVEL 0
@@ -127,7 +128,7 @@ struct sedf_cpu_info {
 
 #define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)
 
-#define DIV_UP(x,y) (((x) + (y) - 1) / y)
+#define DIV_UP(x,y) div64((x) + (y) - 1, y)
 
 #define extra_runs(inf)      ((inf->status) & 6)
 #define extra_get_cur_q(inf) (((inf->status & 6) >> 1)-1)
@@ -678,8 +679,7 @@ static void desched_extra_dom(s_time_t now, struct vcpu *d)
           utilization and is used somewhat incremental!*/
         if ( !inf->extraweight )
             /*NB: use fixed point arithmetic with 10 bits*/
-            inf->score[EXTRA_UTIL_Q] = (inf->period << 10) /
-                inf->slice;
+            inf->score[EXTRA_UTIL_Q] = div64(inf->period << 10, inf->slice);
         else
             /*conversion between realtime utilisation and extrawieght:
               full (ie 100%) utilization is equivalent to 128 extraweight*/
@@ -996,8 +996,8 @@ static void unblock_short_extra_support(
   
         if ( inf->short_block_lost_tot )
         {
-            inf->score[0] = (inf->period << 10) /
-                inf->short_block_lost_tot;
+            inf->score[0] = div64(inf->period << 10,
+                                     inf->short_block_lost_tot);
 #ifdef SEDF_STATS
             inf->pen_extra_blocks++;
 #endif
@@ -1224,8 +1224,8 @@ static void sedf_dump_domain(struct vcpu *d)
     
 #ifdef SEDF_STATS
     if ( EDOM_INFO(d)->block_time_tot != 0 )
-        printk(" pen=%"PRIu64"%%", (EDOM_INFO(d)->penalty_time_tot * 100) /
-               EDOM_INFO(d)->block_time_tot);
+        printk(" pen=%"PRIu64"%%",
+               div64(EDOM_INFO(d)->penalty_time_tot * 100, 
EDOM_INFO(d)->block_time_tot));
     if ( EDOM_INFO(d)->block_tot != 0 )
         printk("\n   blks=%u sh=%u (%u%%) (shc=%u (%u%%) shex=%i "\
                "shexsl=%i) l=%u (%u%%) avg: b=%"PRIu64" p=%"PRIu64"",
@@ -1237,8 +1237,8 @@ static void sedf_dump_domain(struct vcpu *d)
                EDOM_INFO(d)->pen_extra_slices,
                EDOM_INFO(d)->long_block_tot,
                (EDOM_INFO(d)->long_block_tot * 100) / EDOM_INFO(d)->block_tot,
-               (EDOM_INFO(d)->block_time_tot) / EDOM_INFO(d)->block_tot,
-               (EDOM_INFO(d)->penalty_time_tot) / EDOM_INFO(d)->block_tot);
+               div64(EDOM_INFO(d)->block_time_tot, EDOM_INFO(d)->block_tot),
+               div64(EDOM_INFO(d)->penalty_time_tot, EDOM_INFO(d)->block_tot));
 #endif
     printk("\n");
 }
@@ -1357,9 +1357,9 @@ static int sedf_adjust_weights(struct cpupool *c, struct 
xen_domctl_scheduler_op
                 /*check for overflows*/
                 ASSERT((WEIGHT_PERIOD < ULONG_MAX) 
                        && (EDOM_INFO(p)->slice_orig < ULONG_MAX));
-                sumt[cpu] += 
-                    (WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig) / 
-                    EDOM_INFO(p)->period_orig;
+                sumt[cpu] += div64(
+                    WEIGHT_PERIOD * EDOM_INFO(p)->slice_orig,
+                    EDOM_INFO(p)->period_orig);
             }
         }
     }
@@ -1378,9 +1378,9 @@ static int sedf_adjust_weights(struct cpupool *c, struct 
xen_domctl_scheduler_op
                 EDOM_INFO(p)->period_orig = 
                     EDOM_INFO(p)->period  = WEIGHT_PERIOD;
                 EDOM_INFO(p)->slice_orig  =
-                    EDOM_INFO(p)->slice   = 
-                    (EDOM_INFO(p)->weight *
-                     (WEIGHT_PERIOD - WEIGHT_SAFETY - sumt[cpu])) / sumw[cpu];
+                    EDOM_INFO(p)->slice   = div64(
+                        EDOM_INFO(p)->weight * (WEIGHT_PERIOD - WEIGHT_SAFETY 
- sumt[cpu]),
+                        sumw[cpu]);
             }
         }
     }
diff --git a/xen/common/timer.c b/xen/common/timer.c
index 0547ea3..043250e 100644
--- a/xen/common/timer.c
+++ b/xen/common/timer.c
@@ -23,6 +23,7 @@
 #include <xen/symbols.h>
 #include <asm/system.h>
 #include <asm/desc.h>
+#include <asm/div64.h>
 #include <asm/atomic.h>
 
 /* We program the time hardware this far behind the closest deadline. */
@@ -503,16 +504,18 @@ static void timer_softirq_action(void)
 
 s_time_t align_timer(s_time_t firsttick, uint64_t period)
 {
+    uint64_t n;
     if ( !period )
         return firsttick;
 
-    return firsttick + (period - 1) - ((firsttick - 1) % period);
+    n = firsttick + (period - 1) - (firsttick - 1);
+    return do_div(n, period);
 }
 
 static void dump_timer(struct timer *t, s_time_t now)
 {
     printk("  ex=%8"PRId64"us timer=%p cb=%p(%p)",
-           (t->expires - now) / 1000, t, t->function, t->data);
+           div64(t->expires - now, 1000), t, t->function, t->data);
     print_symbol(" %s\n", (unsigned long)t->function);
 }
 
diff --git a/xen/include/asm-ia64/linux/asm-generic/div64.h 
b/xen/include/asm-ia64/linux/asm-generic/div64.h
index 8f4e319..820c073 100644
--- a/xen/include/asm-ia64/linux/asm-generic/div64.h
+++ b/xen/include/asm-ia64/linux/asm-generic/div64.h
@@ -55,4 +55,10 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t 
divisor);
 
 #endif /* BITS_PER_LONG */
 
+static inline uint64_t div64(uint64_t n, uint32_t base)
+{
+       do_div(n, base);
+       return n;
+}
+
 #endif /* _ASM_GENERIC_DIV64_H */
diff --git a/xen/include/asm-x86/div64.h b/xen/include/asm-x86/div64.h
index 1ce87cd..800ef2a 100644
--- a/xen/include/asm-x86/div64.h
+++ b/xen/include/asm-x86/div64.h
@@ -46,4 +46,10 @@
 
 #endif
 
+static inline uint64_t div64(uint64_t n, uint32_t base)
+{
+       do_div(n, base);
+       return n;
+}
+
 #endif
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.