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);
  18
  19#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
  20
  21#define BITMAP_LAST_WORD_MASK(nbits)                                    \
  22(                                                                       \
  23        ((nbits) % BITS_PER_LONG) ?                                     \
  24                (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL               \
  25)
  26
  27#define small_const_nbits(nbits) \
  28        (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
  29
  30static inline void bitmap_zero(unsigned long *dst, int nbits)
  31{
  32        if (small_const_nbits(nbits))
  33                *dst = 0UL;
  34        else {
  35                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  36                memset(dst, 0, len);
  37        }
  38}
  39
  40static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
  41{
  42        unsigned int nlongs = BITS_TO_LONGS(nbits);
  43        if (!small_const_nbits(nbits)) {
  44                unsigned int len = (nlongs - 1) * sizeof(unsigned long);
  45                memset(dst, 0xff,  len);
  46        }
  47        dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
  48}
  49
  50static inline int bitmap_empty(const unsigned long *src, unsigned nbits)
  51{
  52        if (small_const_nbits(nbits))
  53                return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
  54
  55        return find_first_bit(src, nbits) == nbits;
  56}
  57
  58static inline int bitmap_full(const unsigned long *src, unsigned int nbits)
  59{
  60        if (small_const_nbits(nbits))
  61                return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
  62
  63        return find_first_zero_bit(src, nbits) == nbits;
  64}
  65
  66static inline int bitmap_weight(const unsigned long *src, int nbits)
  67{
  68        if (small_const_nbits(nbits))
  69                return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
  70        return __bitmap_weight(src, nbits);
  71}
  72
  73static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
  74                             const unsigned long *src2, int nbits)
  75{
  76        if (small_const_nbits(nbits))
  77                *dst = *src1 | *src2;
  78        else
  79                __bitmap_or(dst, src1, src2, nbits);
  80}
  81
  82/**
  83 * test_and_set_bit - Set a bit and return its old value
  84 * @nr: Bit to set
  85 * @addr: Address to count from
  86 */
  87static inline int test_and_set_bit(int nr, unsigned long *addr)
  88{
  89        unsigned long mask = BIT_MASK(nr);
  90        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  91        unsigned long old;
  92
  93        old = *p;
  94        *p = old | mask;
  95
  96        return (old & mask) != 0;
  97}
  98
  99/**
 100 * bitmap_alloc - Allocate bitmap
 101 * @nr: Bit to set
 102 */
 103static inline unsigned long *bitmap_alloc(int nbits)
 104{
 105        return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
 106}
 107
 108/*
 109 * bitmap_scnprintf - print bitmap list into buffer
 110 * @bitmap: bitmap
 111 * @nbits: size of bitmap
 112 * @buf: buffer to store output
 113 * @size: size of @buf
 114 */
 115size_t bitmap_scnprintf(unsigned long *bitmap, int nbits,
 116                        char *buf, size_t size);
 117
 118/**
 119 * bitmap_and - Do logical and on bitmaps
 120 * @dst: resulting bitmap
 121 * @src1: operand 1
 122 * @src2: operand 2
 123 * @nbits: size of bitmap
 124 */
 125static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
 126                             const unsigned long *src2, unsigned int nbits)
 127{
 128        if (small_const_nbits(nbits))
 129                return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
 130        return __bitmap_and(dst, src1, src2, nbits);
 131}
 132
 133#endif /* _PERF_BITOPS_H */
 134