[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |