bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr)
{
    unsigned long *p = map + BIT_WORD(start);
    const long size = start + nr;
    int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
    unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
    unsigned long dirty = 0;
    unsigned long old_bits;
    /* First word */
    if (nr - bits_to_clear > 0) {
        old_bits = atomic_fetch_and(p, ~mask_to_clear);
        dirty |= old_bits & mask_to_clear;
        nr -= bits_to_clear;
        bits_to_clear = BITS_PER_LONG;
        mask_to_clear = ~0UL;
        p++;
    }
    /* Full words */
    if (bits_to_clear == BITS_PER_LONG) {
        while (nr >= BITS_PER_LONG) {
            if (*p) {
                old_bits = atomic_xchg(p, 0);
                dirty |= old_bits;
            }
            nr -= BITS_PER_LONG;
            p++;
        }
    }
    /* Last word */
    if (nr) {
        mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
        old_bits = atomic_fetch_and(p, ~mask_to_clear);
        dirty |= old_bits & mask_to_clear;
    } else {
        if (!dirty) {
            smp_mb();
        }
    }
    return dirty != 0;
}
bool bitmap_test_and_clear_atomic(unsigned long *map, long start, long nr)
{
    unsigned long *p = map + BIT_WORD(start);
    const long size = start + nr;
    int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
    unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
    unsigned long dirty = 0;
    unsigned long old_bits;
    
    if (nr - bits_to_clear > 0) {
        old_bits = atomic_fetch_and(p, ~mask_to_clear);
        dirty |= old_bits & mask_to_clear;
        nr -= bits_to_clear;
        bits_to_clear = BITS_PER_LONG;
        mask_to_clear = ~0UL;
        p++;
    }
    
    if (bits_to_clear == BITS_PER_LONG) {
        while (nr >= BITS_PER_LONG) {
            if (*p) {
                old_bits = atomic_xchg(p, 0);
                dirty |= old_bits;
            }
            nr -= BITS_PER_LONG;
            p++;
        }
    }
    
    if (nr) {
        mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
        old_bits = atomic_fetch_and(p, ~mask_to_clear);
        dirty |= old_bits & mask_to_clear;
    } else {
        if (!dirty) {
            smp_mb();
        }
    }
    return dirty != 0;
}
bool FUNC_0(unsigned long *map, long start, long nr)
{
    unsigned long *VAR_0 = map + BIT_WORD(start);
    const long VAR_1 = start + nr;
    int VAR_2 = BITS_PER_LONG - (start % BITS_PER_LONG);
    unsigned long VAR_3 = BITMAP_FIRST_WORD_MASK(start);
    unsigned long VAR_4 = 0;
    unsigned long VAR_5;
    
    if (nr - VAR_2 > 0) {
        VAR_5 = atomic_fetch_and(VAR_0, ~VAR_3);
        VAR_4 |= VAR_5 & VAR_3;
        nr -= VAR_2;
        VAR_2 = BITS_PER_LONG;
        VAR_3 = ~0UL;
        VAR_0++;
    }
    
    if (VAR_2 == BITS_PER_LONG) {
        while (nr >= BITS_PER_LONG) {
            if (*VAR_0) {
                VAR_5 = atomic_xchg(VAR_0, 0);
                VAR_4 |= VAR_5;
            }
            nr -= BITS_PER_LONG;
            VAR_0++;
        }
    }
    
    if (nr) {
        VAR_3 &= BITMAP_LAST_WORD_MASK(VAR_1);
        VAR_5 = atomic_fetch_and(VAR_0, ~VAR_3);
        VAR_4 |= VAR_5 & VAR_3;
    } else {
        if (!VAR_4) {
            smp_mb();
        }
    }
    return VAR_4 != 0;
}
bool FUNC_0(unsigned long *map, long start, long nr)
{ unsigned long *VAR_0 = map + BIT_WORD(start); const long VAR_1 = start + nr; int VAR_2 = BITS_PER_LONG - (start % BITS_PER_LONG); unsigned long VAR_3 = BITMAP_FIRST_WORD_MASK(start); unsigned long VAR_4 = 0; unsigned long VAR_5; if (nr - VAR_2 > 0) { VAR_5 = atomic_fetch_and(VAR_0, ~VAR_3); VAR_4 |= VAR_5 & VAR_3; nr -= VAR_2; VAR_2 = BITS_PER_LONG; VAR_3 = ~0UL; VAR_0++; } if (VAR_2 == BITS_PER_LONG) { while (nr >= BITS_PER_LONG) { if (*VAR_0) { VAR_5 = atomic_xchg(VAR_0, 0); VAR_4 |= VAR_5; } nr -= BITS_PER_LONG; VAR_0++; } } if (nr) { VAR_3 &= BITMAP_LAST_WORD_MASK(VAR_1); VAR_5 = atomic_fetch_and(VAR_0, ~VAR_3); VAR_4 |= VAR_5 & VAR_3; } else { if (!VAR_4) { smp_mb(); } } return VAR_4 != 0; }