Compare commits
3 Commits
b50f3a7098
...
d5c37f5d48
| Author | SHA1 | Date | |
|---|---|---|---|
| d5c37f5d48 | |||
| 1c10926cf9 | |||
| 94c6b2eec5 |
@@ -14,6 +14,7 @@
|
||||
#define BITS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* next include will define __WORDSIZE: 32 or 64
|
||||
*/
|
||||
@@ -262,7 +263,231 @@ static __always_inline int popcount32(u32 n)
|
||||
# endif
|
||||
}
|
||||
|
||||
/* rolXX are taken from kernel's <linux/bitops.h> are are:
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* rol64 - rotate a 64-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u64 rol64(u64 word, unsigned int shift)
|
||||
{
|
||||
return (word << (shift & 63)) | (word >> ((-shift) & 63));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror64 - rotate a 64-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u64 ror64(u64 word, unsigned int shift)
|
||||
{
|
||||
return (word >> (shift & 63)) | (word << ((-shift) & 63));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol32 - rotate a 32-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u32 rol32(u32 word, unsigned int shift)
|
||||
{
|
||||
return (word << (shift & 31)) | (word >> ((-shift) & 31));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror32 - rotate a 32-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u32 ror32(u32 word, unsigned int shift)
|
||||
{
|
||||
return (word >> (shift & 31)) | (word << ((-shift) & 31));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol16 - rotate a 16-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u16 rol16(u16 word, unsigned int shift)
|
||||
{
|
||||
return (word << (shift & 15)) | (word >> ((-shift) & 15));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror16 - rotate a 16-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u16 ror16(u16 word, unsigned int shift)
|
||||
{
|
||||
return (word >> (shift & 15)) | (word << ((-shift) & 15));
|
||||
}
|
||||
|
||||
/**
|
||||
* rol8 - rotate an 8-bit value left
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u8 rol8(u8 word, unsigned int shift)
|
||||
{
|
||||
return (word << (shift & 7)) | (word >> ((-shift) & 7));
|
||||
}
|
||||
|
||||
/**
|
||||
* ror8 - rotate an 8-bit value right
|
||||
* @word: value to rotate
|
||||
* @shift: bits to roll
|
||||
*/
|
||||
static inline u8 ror8(u8 word, unsigned int shift)
|
||||
{
|
||||
return (word >> (shift & 7)) | (word << ((-shift) & 7));
|
||||
}
|
||||
|
||||
/**
|
||||
* ilog2 -
|
||||
*/
|
||||
static __always_inline __attribute__((const))
|
||||
int __ilog2_u32(u32 n)
|
||||
{
|
||||
return fls32(n) - 1;
|
||||
}
|
||||
|
||||
static __always_inline __attribute__((const))
|
||||
int __ilog2_u64(u64 n)
|
||||
{
|
||||
return fls64(n) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_power_of_2() - check if a value is a power of two
|
||||
* @n: the value to check
|
||||
*
|
||||
* Determine whether some value is a power of two, where zero is
|
||||
* *not* considered a power of two.
|
||||
* Return: true if @n is a power of 2, otherwise false.
|
||||
*/
|
||||
static inline __attribute__((const))
|
||||
bool is_power_of_2(unsigned long n)
|
||||
{
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* ilog2 - log base 2 of 32-bit or a 64-bit unsigned value
|
||||
* @n: parameter
|
||||
*
|
||||
* constant-capable log of base 2 calculation
|
||||
* - this can be used to initialise global variables from constant data, hence
|
||||
* the massive ternary operator construction
|
||||
*
|
||||
* selects the appropriately-sized optimised version depending on sizeof(n)
|
||||
*/
|
||||
#define ilog2(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? \
|
||||
((n) < 2 ? 0 : \
|
||||
63 - __builtin_clzll(n)) : \
|
||||
(sizeof(n) <= 4) ? \
|
||||
__ilog2_u32(n) : \
|
||||
__ilog2_u64(n) \
|
||||
)
|
||||
|
||||
/**
|
||||
* roundup_pow_of_two - round the given value up to nearest power of two
|
||||
* @n: parameter
|
||||
*
|
||||
* round the given value up to the nearest power of two
|
||||
* - the result is undefined when n == 0
|
||||
* - this can be used to initialise global variables from constant data
|
||||
*/
|
||||
#define roundup_pow_of_two(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
((n) == 1) ? 1 : \
|
||||
(1UL << (ilog2((n) - 1) + 1)) \
|
||||
) : \
|
||||
__roundup_pow_of_two(n) \
|
||||
)
|
||||
|
||||
/**
|
||||
* rounddown_pow_of_two - round the given value down to nearest power of two
|
||||
* @n: parameter
|
||||
*
|
||||
* round the given value down to the nearest power of two
|
||||
* - the result is undefined when n == 0
|
||||
* - this can be used to initialise global variables from constant data
|
||||
*/
|
||||
#define rounddown_pow_of_two(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
(1UL << ilog2(n))) : \
|
||||
__rounddown_pow_of_two(n) \
|
||||
)
|
||||
|
||||
static inline __attribute_const__
|
||||
int __order_base_2(unsigned long n)
|
||||
{
|
||||
return n > 1 ? ilog2(n - 1) + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* order_base_2 - calculate the (rounded up) base 2 order of the argument
|
||||
* @n: parameter
|
||||
*
|
||||
* The first few values calculated by this routine:
|
||||
* ob2(0) = 0
|
||||
* ob2(1) = 0
|
||||
* ob2(2) = 1
|
||||
* ob2(3) = 2
|
||||
* ob2(4) = 2
|
||||
* ob2(5) = 3
|
||||
* ... and so on.
|
||||
*/
|
||||
#define order_base_2(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
((n) == 0 || (n) == 1) ? 0 : \
|
||||
ilog2((n) - 1) + 1) : \
|
||||
__order_base_2(n) \
|
||||
)
|
||||
|
||||
static inline __attribute__((const))
|
||||
int __bits_per(unsigned long n)
|
||||
{
|
||||
if (n < 2)
|
||||
return 1;
|
||||
if (is_power_of_2(n))
|
||||
return order_base_2(n) + 1;
|
||||
return order_base_2(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* bits_per - calculate the number of bits required for the argument
|
||||
* @n: parameter
|
||||
*
|
||||
* This is constant-capable and can be used for compile time
|
||||
* initializations, e.g bitfields.
|
||||
*
|
||||
* The first few values calculated by this routine:
|
||||
* bf(0) = 1
|
||||
* bf(1) = 1
|
||||
* bf(2) = 2
|
||||
* bf(3) = 2
|
||||
* bf(4) = 3
|
||||
* ... and so on.
|
||||
*/
|
||||
#define bits_per(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
((n) == 0 || (n) == 1) \
|
||||
? 1 : ilog2(n) + 1 \
|
||||
) : \
|
||||
__bits_per(n) \
|
||||
)
|
||||
|
||||
/** bit_for_each - iterate over an u64/u32 bits
|
||||
* @pos: an int used as current bit
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#define ___PASTE(x, y) x##y
|
||||
#define __PASTE(x, y) ___PASTE(x, y)
|
||||
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
||||
//__##prefix##__COUNTER__
|
||||
|
||||
/* see https://lkml.org/lkml/2018/3/20/845 for explanation of this monster
|
||||
*/
|
||||
@@ -70,6 +69,8 @@
|
||||
__cmp(x, y, op), \
|
||||
__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
|
||||
|
||||
#define __pure __attribute__((__pure__))
|
||||
|
||||
/**
|
||||
* min - return minimum of two values of the same or compatible types
|
||||
* @x: first value
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
#include "likely.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* inspired by Linux kernel's <asm/bug.h> */
|
||||
/* BUG functions inspired by Linux kernel's <asm/bug.h>
|
||||
*/
|
||||
|
||||
#define panic() exit(0xff)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#ifndef _BR_HASH_H
|
||||
#define _BR_HASH_H
|
||||
/* adaptation of Linux kernel's <linux/hash.h>
|
||||
/* adaptation of Linux kernel's <linux/hash.h> and <linux/stringhash.h>
|
||||
*/
|
||||
|
||||
/* Fast hashing routine for ints, longs and pointers.
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <asm/types.h>
|
||||
#include <asm/bitsperlong.h>
|
||||
#include "bits.h"
|
||||
#include "br.h"
|
||||
|
||||
/*
|
||||
* The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and
|
||||
* fs/inode.c. It's not actually prime any more (the previous primes
|
||||
@@ -98,4 +100,74 @@ static inline u32 hash32_ptr(const void *ptr)
|
||||
return (u32)val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines for hashing strings of bytes to a 32-bit hash value.
|
||||
*
|
||||
* These hash functions are NOT GUARANTEED STABLE between kernel
|
||||
* versions, architectures, or even repeated boots of the same kernel.
|
||||
* (E.g. they may depend on boot-time hardware detection or be
|
||||
* deliberately randomized.)
|
||||
*
|
||||
* They are also not intended to be secure against collisions caused by
|
||||
* malicious inputs; much slower hash functions are required for that.
|
||||
*
|
||||
* They are optimized for pathname components, meaning short strings.
|
||||
* Even if a majority of files have longer names, the dynamic profile of
|
||||
* pathname components skews short due to short directory names.
|
||||
* (E.g. /usr/lib/libsesquipedalianism.so.3.141.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Version 1: one byte at a time. Example of use:
|
||||
*
|
||||
* unsigned long hash = init_name_hash;
|
||||
* while (*p)
|
||||
* hash = partial_name_hash(tolower(*p++), hash);
|
||||
* hash = end_name_hash(hash);
|
||||
*
|
||||
* Although this is designed for bytes, fs/hfsplus/unicode.c
|
||||
* abuses it to hash 16-bit values.
|
||||
*/
|
||||
|
||||
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
|
||||
#define init_name_hash(salt) (unsigned long)(salt)
|
||||
|
||||
/* partial hash update function. Assume roughly 4 bits per character */
|
||||
static inline unsigned long
|
||||
partial_name_hash(unsigned long c, unsigned long prevhash)
|
||||
{
|
||||
return (prevhash + (c << 4) + (c >> 4)) * 11;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally: cut down the number of bits to a int value (and try to avoid
|
||||
* losing bits). This also has the property (wanted by the dcache)
|
||||
* that the msbits make a good hash table index.
|
||||
*/
|
||||
static inline unsigned int end_name_hash(unsigned long hash)
|
||||
{
|
||||
return hash_long(hash, 32);
|
||||
}
|
||||
|
||||
/*
|
||||
* Version 2: One word (32 or 64 bits) at a time.
|
||||
* If CONFIG_DCACHE_WORD_ACCESS is defined (meaning <asm/word-at-a-time.h>
|
||||
* exists, which describes major Linux platforms like x86 and ARM), then
|
||||
* this computes a different hash function much faster.
|
||||
*
|
||||
* If not set, this falls back to a wrapper around the preceding.
|
||||
*/
|
||||
extern unsigned int __pure hash_string(const void *salt, const char *, unsigned int);
|
||||
|
||||
/*
|
||||
* A hash_len is a u64 with the hash of a string in the low
|
||||
* half and the length in the high half.
|
||||
*/
|
||||
#define hashlen_hash(hashlen) ((u32)(hashlen))
|
||||
#define hashlen_len(hashlen) ((u32)((hashlen) >> 32))
|
||||
#define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
|
||||
|
||||
/* Return the "hash_len" (hash and length) of a null-terminated string */
|
||||
extern u64 __pure hashlen_string(const void *salt, const char *name);
|
||||
|
||||
#endif /* _BR_HASH_H */
|
||||
|
||||
Reference in New Issue
Block a user