linux/tools/include/linux/bitmap.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _PERF_BITOPS_H
   3#define _PERF_BITOPS_H
   4
   5#include <string.h>
   6#include <linux/bitops.h>
   7#include <stdlib.h>
   8#include <linux/kernel.h>
   9
  10#define DECLARE_BITMAP(name,bits) \
  11        unsigned long name[BITS_TO_LONGS(bits)]
  12
  13int __bitmap_weight(const unsigned long *bitmap, int bits);
  14void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
  15                 const unsigned long *bitmap2, int bits);
  16int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
  17                 const unsigned long *bitmap2, unsigned int bits);
  18int __bitmap_equal(const unsigned long *bitmap1,
  19                   const unsigned long *bitmap2, unsigned int bits);
  20void bitmap_clear(unsigned long *map, unsigned int start, int len);
  21int __bitmap_intersects(const unsigned long *bitmap1,
  22                        const unsigned long *bitmap2, unsigned int bits);
  23
  24#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
  25#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
  26
  27static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
  28{
  29        if (small_const_nbits(nbits))
  30                *dst = 0UL;
  31        else {
  32                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  33                memset(dst, 0, len);
  34        }
  35}
  36
  37static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
  38{
  39        unsigned int nlongs = BITS_TO_LONGS(nbits);
  40        if (!small_const_nbits(nbits)) {
  41                unsigned int len = (nlongs - 1) * sizeof(unsigned long);
  42                memset(dst, 0xff,  len);
  43        }
  44        dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
  45}
  46
  47static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
  48{
  49        if (small_const_nbits(nbits))
  50                return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
  51
  52        return find_first_bit(src, nbits) == nbits;
  53}
  54
  55static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
  56{
  57        if (small_const_nbits(nbits))
  58                return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
  59
  60        return find_first_zero_bit(src, nbits) == nbits;
  61}
  62
  63static inline int bitmap_weight(const unsigned long *src, unsigned int nbits)
  64{
  65        if (small_const_nbits(nbits))
  66                return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
  67        return __bitmap_weight(src, nbits);
  68}
  69
  70static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
  71                             const unsigned long *src2, unsigned int nbits)
  72{
  73        if (small_const_nbits(nbits))
  74                *dst = *src1 | *src2;
  75        else
  76                __bitmap_or(dst, src1, src2, nbits);
  77}
  78
  79/**
  80 * test_and_set_bit - Set a bit and return its old value
  81 * @nr: Bit to set
  82 * @addr: Address to count from
  83 */
  84static inline int test_and_set_bit(int nr, unsigned long *addr)
  85{
  86        unsigned long mask = BIT_MASK(nr);
  87        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  88        unsigned long old;
  89
  90        old = *p;
  91        *p = old | mask;
  92
  93        return (old & mask) != 0;
  94}
  95
  96/**
  97 * test_and_clear_bit - Clear a bit and return its old value
  98 * @nr: Bit to clear
  99 * @addr: Address to count from
 100 */
 101static inline int test_and_clear_bit(int nr, unsigned long *addr)
 102{
 103        unsigned long mask = BIT_MASK(nr);
 104        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 105        unsigned long old;
 106
 107        old = *p;
 108        *p = old & ~mask;
 109
 110        return (old & mask) != 0;
 111}
 112
 113/**
 114 * bitmap_zalloc - Allocate bitmap
 115 * @nbits: Number of bits
 116 */
 117static inline unsigned long *bitmap_zalloc(int nbits)
 118{
 119        return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
 120}
 121
 122/*
 123 * bitmap_free - Free bitmap
 124 * @bitmap: pointer to bitmap
 125 */
 126static inline void bitmap_free(unsigned long *bitmap)
 127{
 128        free(bitmap);
 129}
 130
 131/*
 132 * bitmap_scnprintf - print bitmap list into buffer
 133 * @bitmap: bitmap
 134 * @nbits: size of bitmap
 135 * @buf: buffer to store output
 136 * @size: size of @buf
 137 */
 138size_t bitmap_scnprintf(unsigned long *bitmap, unsigned int nbits,
 139                        char *buf, size_t size);
 140
 141/**
 142 * bitmap_and - Do logical and on bitmaps
 143 * @dst: resulting bitmap
 144 * @src1: operand 1
 145 * @src2: operand 2
 146 * @nbits: size of bitmap
 147 */
 148static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
 149                             const unsigned long *src2, unsigned int nbits)
 150{
 151        if (small_const_nbits(nbits))
 152                return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
 153        return __bitmap_and(dst, src1, src2, nbits);
 154}
 155
 156#ifdef __LITTLE_ENDIAN
 157#define BITMAP_MEM_ALIGNMENT 8
 158#else
 159#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
 160#endif
 161#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
 162#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
 163
 164static inline int bitmap_equal(const unsigned long *src1,
 165                        const unsigned long *src2, unsigned int nbits)
 166{
 167        if (small_const_nbits(nbits))
 168                return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
 169        if (__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
 170            IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
 171                return !memcmp(src1, src2, nbits / 8);
 172        return __bitmap_equal(src1, src2, nbits);
 173}
 174
 175static inline int bitmap_intersects(const unsigned long *src1,
 176                        const unsigned long *src2, unsigned int nbits)
 177{
 178        if (small_const_nbits(nbits))
 179                return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
 180        else
 181                return __bitmap_intersects(src1, src2, nbits);
 182}
 183
 184#endif /* _PERF_BITOPS_H */
 185