[Qemu-devel] [PATCH v2 3/3] host-utils: Simplify pow2ceil()

Markus Armbruster posted 3 patches 8 years, 6 months ago
[Qemu-devel] [PATCH v2 3/3] host-utils: Simplify pow2ceil()
Posted by Markus Armbruster 8 years, 6 months ago
Cc: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 include/qemu/host-utils.h | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 6c6005f..5ac621c 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -381,18 +381,23 @@ static inline uint64_t pow2floor(uint64_t value)
     return 0x8000000000000000ull >> clz64(value);
 }
 
-/* round up to the nearest power of 2 (0 if overflow) */
+/*
+ * Return @value rounded up to the nearest power of two modulo 2^64.
+ * This is *zero* for @value > 2^63, so be careful.
+ */
 static inline uint64_t pow2ceil(uint64_t value)
 {
-    uint8_t nlz = clz64(value);
+    int n = clz64(value - 1);
 
-    if (is_power_of_2(value)) {
-        return value;
+    if (!n) {
+        /*
+         * @value - 1 has no leading zeroes, thus @value - 1 >= 2^63
+         * Therefore, either @value == 0 or @value > 2^63.
+         * If it's 0, return 1, else return 0.
+         */
+        return !value;
     }
-    if (!nlz) {
-        return 0;
-    }
-    return 1ULL << (64 - nlz);
+    return 0x8000000000000000ull >> (n - 1);
 }
 
 /**
-- 
2.7.5


Re: [Qemu-devel] [PATCH v2 3/3] host-utils: Simplify pow2ceil()
Posted by Eric Blake 8 years, 6 months ago
On 07/27/2017 04:46 AM, Markus Armbruster wrote:
> Cc: Radim Krčmář <rkrcmar@redhat.com>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  include/qemu/host-utils.h | 21 +++++++++++++--------
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 

>  
> -/* round up to the nearest power of 2 (0 if overflow) */
> +/*
> + * Return @value rounded up to the nearest power of two modulo 2^64.
> + * This is *zero* for @value > 2^63, so be careful.
> + */
>  static inline uint64_t pow2ceil(uint64_t value)
>  {
> -    uint8_t nlz = clz64(value);
> +    int n = clz64(value - 1);
>  
> -    if (is_power_of_2(value)) {
> -        return value;
> +    if (!n) {
> +        /*
> +         * @value - 1 has no leading zeroes, thus @value - 1 >= 2^63
> +         * Therefore, either @value == 0 or @value > 2^63.
> +         * If it's 0, return 1, else return 0.
> +         */
> +        return !value;

Tricky, but the comment is worth its weight in gold.

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org