diff options
| author | Anand Avati <avati@redhat.com> | 2013-03-06 01:11:59 -0800 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-09-03 11:25:33 -0700 | 
| commit | 0d60175bd684cf6a14f750579d82dbd1ba97fcbc (patch) | |
| tree | 1571f530548196006526442f3fc027cb623bb6fa /contrib/qemu/util/bitops.c | |
| parent | 7dbfbfd3694e02b90e8f3ce509f5279da1523a02 (diff) | |
contrib/qemu: Import qemu block source code
This qemu block format source code and its minimal
dependency files will be used in the next patch to implement
a qemu-block format translator.
Change-Id: Ic87638972f7ea9b3df84d7a0539512a250c11c1c
BUG: 986775
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/5366
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'contrib/qemu/util/bitops.c')
| -rw-r--r-- | contrib/qemu/util/bitops.c | 158 | 
1 files changed, 158 insertions, 0 deletions
diff --git a/contrib/qemu/util/bitops.c b/contrib/qemu/util/bitops.c new file mode 100644 index 00000000000..227c38b883d --- /dev/null +++ b/contrib/qemu/util/bitops.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * Copyright (C) 2008 IBM Corporation + * Written by Rusty Russell <rusty@rustcorp.com.au> + * (Inspired by David Howell's find_next_bit implementation) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "qemu/bitops.h" + +#define BITOP_WORD(nr)		((nr) / BITS_PER_LONG) + +/* + * Find the next set bit in a memory region. + */ +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, +			    unsigned long offset) +{ +    const unsigned long *p = addr + BITOP_WORD(offset); +    unsigned long result = offset & ~(BITS_PER_LONG-1); +    unsigned long tmp; + +    if (offset >= size) { +        return size; +    } +    size -= result; +    offset %= BITS_PER_LONG; +    if (offset) { +        tmp = *(p++); +        tmp &= (~0UL << offset); +        if (size < BITS_PER_LONG) { +            goto found_first; +        } +        if (tmp) { +            goto found_middle; +        } +        size -= BITS_PER_LONG; +        result += BITS_PER_LONG; +    } +    while (size >= 4*BITS_PER_LONG) { +        unsigned long d1, d2, d3; +        tmp = *p; +        d1 = *(p+1); +        d2 = *(p+2); +        d3 = *(p+3); +        if (tmp) { +            goto found_middle; +        } +        if (d1 | d2 | d3) { +            break; +        } +        p += 4; +        result += 4*BITS_PER_LONG; +        size -= 4*BITS_PER_LONG; +    } +    while (size >= BITS_PER_LONG) { +        if ((tmp = *(p++))) { +            goto found_middle; +        } +        result += BITS_PER_LONG; +        size -= BITS_PER_LONG; +    } +    if (!size) { +        return result; +    } +    tmp = *p; + +found_first: +    tmp &= (~0UL >> (BITS_PER_LONG - size)); +    if (tmp == 0UL) {		/* Are any bits set? */ +        return result + size;	/* Nope. */ +    } +found_middle: +    return result + ctzl(tmp); +} + +/* + * This implementation of find_{first,next}_zero_bit was stolen from + * Linus' asm-alpha/bitops.h. + */ +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, +				 unsigned long offset) +{ +    const unsigned long *p = addr + BITOP_WORD(offset); +    unsigned long result = offset & ~(BITS_PER_LONG-1); +    unsigned long tmp; + +    if (offset >= size) { +        return size; +    } +    size -= result; +    offset %= BITS_PER_LONG; +    if (offset) { +        tmp = *(p++); +        tmp |= ~0UL >> (BITS_PER_LONG - offset); +        if (size < BITS_PER_LONG) { +            goto found_first; +        } +        if (~tmp) { +            goto found_middle; +        } +        size -= BITS_PER_LONG; +        result += BITS_PER_LONG; +    } +    while (size & ~(BITS_PER_LONG-1)) { +        if (~(tmp = *(p++))) { +            goto found_middle; +        } +        result += BITS_PER_LONG; +        size -= BITS_PER_LONG; +    } +    if (!size) { +        return result; +    } +    tmp = *p; + +found_first: +    tmp |= ~0UL << size; +    if (tmp == ~0UL) {	/* Are any bits zero? */ +        return result + size;	/* Nope. */ +    } +found_middle: +    return result + ctzl(~tmp); +} + +unsigned long find_last_bit(const unsigned long *addr, unsigned long size) +{ +    unsigned long words; +    unsigned long tmp; + +    /* Start at final word. */ +    words = size / BITS_PER_LONG; + +    /* Partial final word? */ +    if (size & (BITS_PER_LONG-1)) { +        tmp = (addr[words] & (~0UL >> (BITS_PER_LONG +                                       - (size & (BITS_PER_LONG-1))))); +        if (tmp) { +            goto found; +        } +    } + +    while (words) { +        tmp = addr[--words]; +        if (tmp) { +        found: +            return words * BITS_PER_LONG + BITS_PER_LONG - 1 - clzl(tmp); +        } +    } + +    /* Not found */ +    return size; +}  | 
