updat code

This commit is contained in:
Nick Peng
2018-04-24 00:24:44 +08:00
parent c6af293927
commit d3960e1018
14 changed files with 744 additions and 175 deletions

View File

@@ -2,6 +2,7 @@
#ifndef _GENERIC_ATOMIC_H
#define _GENERIC_ATOMIC_H
/* Check GCC version, just to be safe */
#if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC_MINOR__ < 1)
# error atomic.h works only with GCC newer than version 4.1

View File

@@ -5,6 +5,8 @@
#include <string.h>
#include <stdlib.h>
#include "bitops.h"
#include "findbit.h"
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
@@ -101,7 +103,7 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
*/
static inline unsigned long *bitmap_alloc(int nbits)
{
return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
return (unsigned long *)calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long));
}
/*

View File

@@ -2,6 +2,10 @@
#ifndef _GENERIC_BITOPS_H_
#define _GENERIC_BITOPS_H_
#include <unistd.h>
#include <stdint.h>
#include "gcc_builtin.h"
#ifndef __WORDSIZE
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
#endif
@@ -24,6 +28,164 @@ extern unsigned int __sw_hweight32(unsigned int w);
extern unsigned long __sw_hweight64(uint64_t w);
#define ffz(x) __ffs(~(x))
/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline unsigned long __ffs(unsigned long word)
{
int num = 0;
#if __BITS_PER_LONG == 64
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}
static inline int fls(int x)
{
int r = 32;
if (!x)
return 0;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u)) {
x <<= 1;
r -= 1;
}
return r;
}
/**
* fls64 - find last set bit in a 64-bit word
* @x: the word to search
*
* This is defined in a similar way as the libc and compiler builtin
* ffsll, but returns the position of the most significant set bit.
*
* fls64(value) returns 0 if value is 0 or the position of the last
* set bit if value is nonzero. The last (most significant) bit is
* at position 64.
*/
#if BITS_PER_LONG == 32
static inline int fls64(uint64_t x)
{
uint32_t h = x >> 32;
if (h)
return fls(h) + 32;
return fls(x);
}
#elif BITS_PER_LONG == 64
static inline int fls64(uint64_t x)
{
if (x == 0)
return 0;
return __fls(x) + 1;
}
#else
#error BITS_PER_LONG not 32 or 64
#endif
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
*
* The Hamming Weight of a number is the total number of bits set in it.
*/
static inline unsigned int hweight32(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res + (res >> 4)) & 0x0F0F0F0F;
res = res + (res >> 8);
return (res + (res >> 16)) & 0x000000FF;
}
static inline unsigned int hweight16(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x5555);
res = (res & 0x3333) + ((res >> 2) & 0x3333);
res = (res + (res >> 4)) & 0x0F0F;
return (res + (res >> 8)) & 0x00FF;
}
static inline unsigned int hweight8(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55);
res = (res & 0x33) + ((res >> 2) & 0x33);
return (res + (res >> 4)) & 0x0F;
}
static inline unsigned long hweight64(uint64_t w)
{
#if BITS_PER_LONG == 32
return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
#elif BITS_PER_LONG == 64
#ifdef ARCH_HAS_FAST_MULTIPLIER
w -= (w >> 1) & 0x5555555555555555ul;
w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);
w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;
return (w * 0x0101010101010101ul) >> 56;
#else
uint64_t res = w - ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
res = res + (res >> 8);
res = res + (res >> 16);
return (res + (res >> 32)) & 0x00000000000000FFul;
#endif
#endif
}
#define for_each_set_bit(bit, addr, size) \
for ((bit) = find_first_bit((addr), (size)); \
(bit) < (size); \

78
include/findbit.h Normal file
View File

@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
#ifndef find_next_bit
/**
* find_next_bit - find the next set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*
* Returns the bit number for the next set bit
* If no bits are set, returns @size.
*/
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
size, unsigned long offset);
#endif
#ifndef find_next_and_bit
/**
* find_next_and_bit - find the next set bit in both memory regions
* @addr1: The first address to base the search on
* @addr2: The second address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*
* Returns the bit number for the next set bit
* If no bits are set, returns @size.
*/
extern unsigned long find_next_and_bit(const unsigned long *addr1,
const unsigned long *addr2, unsigned long size,
unsigned long offset);
#endif
#ifndef find_next_zero_bit
/**
* find_next_zero_bit - find the next cleared bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*
* Returns the bit number of the next zero bit
* If no bits are zero, returns @size.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset);
#endif
#ifndef find_first_bit
/**
* find_first_bit - find the first set bit in a memory region
* @addr: The address to start the search at
* @size: The maximum number of bits to search
*
* Returns the bit number of the first set bit.
* If no bits are set, returns @size.
*/
extern unsigned long find_first_bit(const unsigned long *addr,
unsigned long size);
#endif /* find_first_bit */
#ifndef find_first_zero_bit
/**
* find_first_zero_bit - find the first cleared bit in a memory region
* @addr: The address to start the search at
* @size: The maximum number of bits to search
*
* Returns the bit number of the first cleared bit.
* If no bits are zero, returns @size.
*/
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
#endif
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */

118
include/gcc_builtin.h Normal file
View File

@@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _TOOLS_LINUX_COMPILER_H_
#define _TOOLS_LINUX_COMPILER_H_
#ifndef __compiletime_error
# define __compiletime_error(message)
#endif
/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")
#ifndef __always_inline
# define __always_inline inline __attribute__((always_inline))
#endif
#ifndef noinline
#define noinline
#endif
/* Are two types/vars the same type (ignoring qualifiers)? */
#ifndef __same_type
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#endif
#ifdef __ANDROID__
/*
* FIXME: Big hammer to get rid of tons of:
* "warning: always_inline function might not be inlinable"
*
* At least on android-ndk-r12/platforms/android-24/arch-arm
*/
#undef __always_inline
#define __always_inline inline
#endif
#define __user
#define __rcu
#define __read_mostly
#ifndef __attribute_const__
# define __attribute_const__
#endif
#ifndef __maybe_unused
# define __maybe_unused __attribute__((unused))
#endif
#ifndef __used
# define __used __attribute__((__unused__))
#endif
#ifndef __packed
# define __packed __attribute__((__packed__))
#endif
#ifndef __force
# define __force
#endif
#ifndef __weak
# define __weak __attribute__((weak))
#endif
#ifndef likely
# define likely(x) __builtin_expect(!!(x), 1)
#endif
#ifndef unlikely
# define unlikely(x) __builtin_expect(!!(x), 0)
#endif
#ifndef __init
# define __init
#endif
#ifndef noinline
# define noinline
#endif
#define uninitialized_var(x) x = *(&(x))
#ifndef __fallthrough
# define __fallthrough
#endif
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#ifndef max
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#endif
#ifndef min
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#endif
#ifndef roundup
#define roundup(x, y) ( \
{ \
const typeof(y) __y = y; \
(((x) + (__y - 1)) / __y) * __y; \
} \
)
#endif
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))
#endif /* _TOOLS_LINUX_COMPILER_H */

View File

@@ -1,6 +1,7 @@
#ifndef _GENERIC_HASH_H
#define _GENERIC_HASH_H
#include "bitmap.h"
#include "jhash.h"
/* Fast hashing routine for ints, longs and pointers.
@@ -113,6 +114,17 @@ int __ilog2_u64(uint64_t n)
__ilog2_u64(n) \
)
#if BITS_PER_LONG == 32
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
#define hash_long(val, bits) hash_32(val, bits)
#elif BITS_PER_LONG == 64
#define hash_long(val, bits) hash_64(val, bits)
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
#else
#error Wordsize not 32 or 64
#endif
/*
* This hash multiplies the input by a large odd number and takes the
* high bits. Since multiplication propagates changes to the most

View File

@@ -9,7 +9,6 @@
#include "list.h"
#include "hash.h"
#include "bitmap.h"
#ifndef __same_type
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
@@ -149,5 +148,4 @@ static inline void hash_del(struct hlist_node *node)
hlist_for_each_entry_safe(obj, tmp,\
&name[hash_min(key, HASH_BITS(name))], member)
#endif

View File

@@ -79,7 +79,7 @@ static inline uint32_t __get_unaligned_cpu32(const void *p)
static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval)
{
uint32_t a, b, c;
const uint8_t *k = key;
const uint8_t *k = (uint8_t *)key;
/* Set up the internal state */
a = b = c = JHASH_INITVAL + length + initval;

View File

@@ -60,46 +60,46 @@ static inline void INIT_LIST_HEAD(struct list_head *list)
}
/*
* Insert a new entry between two known consecutive entries.
* Insert a add entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
static inline void __list_add(struct list_head *add,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
next->prev = add;
add->next = next;
add->prev = prev;
prev->next = add;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* list_add - add a add entry
* @add: add entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* Insert a add entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
static inline void list_add(struct list_head *add, struct list_head *head)
{
__list_add(new, head, head->next);
__list_add(add, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* list_add_tail - add a add entry
* @add: add entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* Insert a add entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
static inline void list_add_tail(struct list_head *add, struct list_head *head)
{
__list_add(new, head->prev, head);
__list_add(add, head->prev, head);
}
/*
@@ -129,30 +129,30 @@ static inline void __list_del_entry(struct list_head *entry)
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
entry->next = (struct list_head *)LIST_POISON1;
entry->prev = (struct list_head *)LIST_POISON2;
}
/**
* list_replace - replace old entry by new one
* list_replace - replace old entry by add one
* @old : the element to be replaced
* @new : the new element to insert
* @add : the add element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(struct list_head *old,
struct list_head *new)
struct list_head *add)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
add->next = old->next;
add->next->prev = add;
add->prev = old->prev;
add->prev->next = add;
}
static inline void list_replace_init(struct list_head *old,
struct list_head *new)
struct list_head *add)
{
list_replace(old, new);
list_replace(old, add);
INIT_LIST_HEAD(old);
}
@@ -265,7 +265,7 @@ static inline void __list_cut_position(struct list_head *list,
/**
* list_cut_position - cut a list into two
* @list: a new list to add all removed entries
* @list: a add list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
* and if so we won't cut the list
@@ -307,7 +307,7 @@ static inline void __list_splice(const struct list_head *list,
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @list: the add list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(const struct list_head *list,
@@ -319,7 +319,7 @@ static inline void list_splice(const struct list_head *list,
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @list: the add list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
@@ -331,7 +331,7 @@ static inline void list_splice_tail(struct list_head *list,
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @list: the add list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
@@ -347,7 +347,7 @@ static inline void list_splice_init(struct list_head *list,
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @list: the add list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
@@ -644,8 +644,8 @@ static inline void __hlist_del(struct hlist_node *n)
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);
n->next = LIST_POISON1;
n->pprev = LIST_POISON2;
n->next = (struct hlist_node *)LIST_POISON1;
n->pprev = (struct hlist_node **)LIST_POISON2;
}
static inline void hlist_del_init(struct hlist_node *n)
@@ -703,11 +703,11 @@ static inline bool hlist_fake(struct hlist_node *h)
* reference of the first entry if it exists.
*/
static inline void hlist_move_list(struct hlist_head *old,
struct hlist_head *new)
struct hlist_head *add)
{
new->first = old->first;
if (new->first)
new->first->pprev = &new->first;
add->first = old->first;
if (add->first)
add->first->pprev = &add->first;
old->first = NULL;
}