Compare commits
4 Commits
7be875ac70
...
485e04c6fd
| Author | SHA1 | Date | |
|---|---|---|---|
| 485e04c6fd | |||
| 5294dbe371 | |||
| 15cc0e54e9 | |||
| 3fe7315f7c |
12
c/debug.c
12
c/debug.c
@@ -19,12 +19,13 @@
|
|||||||
#define DEBUG_DEBUG
|
#define DEBUG_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "bits.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define NANOSEC 1000000000 /* nano sec in sec */
|
#define NANOSEC 1000000000 /* nano sec in sec */
|
||||||
#define MILLISEC 1000000 /* milli sec in sec */
|
#define MILLISEC 1000000 /* milli sec in sec */
|
||||||
|
|
||||||
static s64 timer_start; /* in nanosecond */
|
static long long timer_start; /* in nanosecond */
|
||||||
static u32 debug_level=0;
|
static u32 debug_level=0;
|
||||||
|
|
||||||
void debug_level_set(u32 level)
|
void debug_level_set(u32 level)
|
||||||
@@ -48,7 +49,7 @@ void debug_init(u32 level)
|
|||||||
log(0, "timer started.\n");
|
log(0, "timer started.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static s64 timer_elapsed()
|
inline static long long timer_elapsed()
|
||||||
{
|
{
|
||||||
struct timespec timer;
|
struct timespec timer;
|
||||||
|
|
||||||
@@ -56,7 +57,6 @@ inline static s64 timer_elapsed()
|
|||||||
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
|
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* void debug - log function
|
/* void debug - log function
|
||||||
* @timestamp : boolean
|
* @timestamp : boolean
|
||||||
* @indent : indent level (2 spaces each)
|
* @indent : indent level (2 spaces each)
|
||||||
@@ -75,9 +75,9 @@ void debug(u32 level, bool timestamp, u32 indent, const char *src,
|
|||||||
printf("%*s", 2*(indent-1), "");
|
printf("%*s", 2*(indent-1), "");
|
||||||
|
|
||||||
if (timestamp) {
|
if (timestamp) {
|
||||||
s64 diff = timer_elapsed();
|
long long diff = timer_elapsed();
|
||||||
printf("%ld.%03ld ", diff/NANOSEC, (diff/1000000)%1000);
|
printf("%lld.%03lld ", diff/NANOSEC, (diff/1000000)%1000);
|
||||||
printf("%010ld ", diff);
|
printf("%010lld ", diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
|
|||||||
@@ -25,10 +25,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* no plan to support 32bits for now...
|
/* no plan to support 32bits for now...
|
||||||
|
* #if __WORDSIZE != 64
|
||||||
|
* #error "Only 64 bits word size supported."
|
||||||
|
* #endif
|
||||||
*/
|
*/
|
||||||
#if __WORDSIZE != 64
|
|
||||||
#error "Only 64 bits word size supported."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* fixed-size types
|
/* fixed-size types
|
||||||
*/
|
*/
|
||||||
@@ -44,11 +44,30 @@ typedef uint8_t u8;
|
|||||||
|
|
||||||
/* convenience types
|
/* convenience types
|
||||||
*/
|
*/
|
||||||
|
typedef long long int llong;
|
||||||
|
typedef unsigned long long int ullong;
|
||||||
typedef unsigned long int ulong;
|
typedef unsigned long int ulong;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
|
/* define common types sizes
|
||||||
|
*/
|
||||||
|
#define BITS_PER_CHAR 8
|
||||||
|
|
||||||
|
#ifndef BITS_PER_SHORT
|
||||||
|
#define BITS_PER_SHORT (BITS_PER_CHAR * sizeof (short))
|
||||||
|
#endif
|
||||||
|
#ifndef BITS_PER_INT
|
||||||
|
#define BITS_PER_INT (BITS_PER_CHAR * sizeof (int))
|
||||||
|
#endif
|
||||||
|
#ifndef BITS_PER_LONG
|
||||||
|
#define BITS_PER_LONG (BITS_PER_CHAR * sizeof (long))
|
||||||
|
#endif
|
||||||
|
#ifndef BITS_PER_LLONG
|
||||||
|
#define BITS_PER_LLONG (BITS_PER_CHAR * sizeof (long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* count set bits: 10101000 -> 3
|
/* count set bits: 10101000 -> 3
|
||||||
* ^ ^ ^
|
* ^ ^ ^
|
||||||
*/
|
*/
|
||||||
@@ -73,6 +92,27 @@ static __always_inline int popcount64(u64 n)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __always_inline int popcount32(u32 n)
|
||||||
|
{
|
||||||
|
# if __has_builtin(__builtin_popcount)
|
||||||
|
# ifdef DEBUG_BITS
|
||||||
|
log_f(1, "builtin.\n");
|
||||||
|
# endif
|
||||||
|
return __builtin_popcount(n);
|
||||||
|
|
||||||
|
# else
|
||||||
|
# ifdef DEBUG_BITS
|
||||||
|
log_f(1, "emulated.\n");
|
||||||
|
# endif
|
||||||
|
int count = 0;
|
||||||
|
while (n) {
|
||||||
|
count++;
|
||||||
|
n &= (n - 1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
/* char is a special case, as it can be signed or unsigned
|
/* char is a special case, as it can be signed or unsigned
|
||||||
*/
|
*/
|
||||||
typedef signed char schar;
|
typedef signed char schar;
|
||||||
@@ -242,27 +282,6 @@ static __always_inline uint ffs32(u32 n)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline int popcount32(u32 n)
|
|
||||||
{
|
|
||||||
# if __has_builtin(__builtin_popcount)
|
|
||||||
# ifdef DEBUG_BITS
|
|
||||||
log_f(1, "builtin.\n");
|
|
||||||
# endif
|
|
||||||
return __builtin_popcount(n);
|
|
||||||
|
|
||||||
# else
|
|
||||||
# ifdef DEBUG_BITS
|
|
||||||
log_f(1, "emulated.\n");
|
|
||||||
# endif
|
|
||||||
int count = 0;
|
|
||||||
while (n) {
|
|
||||||
count++;
|
|
||||||
n &= (n - 1);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rolXX are taken from kernel's <linux/bitops.h> are are:
|
/* rolXX are taken from kernel's <linux/bitops.h> are are:
|
||||||
* SPDX-License-Identifier: GPL-2.0
|
* SPDX-License-Identifier: GPL-2.0
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#ifndef _BR_H
|
#ifndef _BR_H
|
||||||
#define _BR_H
|
#define _BR_H
|
||||||
|
|
||||||
|
#include "struct-group.h"
|
||||||
|
|
||||||
/* Indirect stringification. Doing two levels allows the parameter to be a
|
/* Indirect stringification. Doing two levels allows the parameter to be a
|
||||||
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
|
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
|
||||||
* converts to "bar".
|
* converts to "bar".
|
||||||
@@ -31,6 +33,17 @@
|
|||||||
#define __PASTE(x, y) ___PASTE(x, y)
|
#define __PASTE(x, y) ___PASTE(x, y)
|
||||||
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
|
||||||
|
|
||||||
|
/* unused/used parameters/functions
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute
|
||||||
|
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute
|
||||||
|
*/
|
||||||
|
#define __unused __attribute__((__unused__))
|
||||||
|
#define __used __attribute__((__used__))
|
||||||
|
|
||||||
/* see https://lkml.org/lkml/2018/3/20/845 for explanation of this monster
|
/* see https://lkml.org/lkml/2018/3/20/845 for explanation of this monster
|
||||||
*/
|
*/
|
||||||
#define __is_constexpr(x) \
|
#define __is_constexpr(x) \
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#ifdef DEBUG_DEBUG
|
#ifdef DEBUG_DEBUG
|
||||||
void debug_init(u32 level);
|
void debug_init(u32 level);
|
||||||
void debug_level_set(u32 level);
|
void debug_level_set(u32 level);
|
||||||
|
u32 debug_level_get(void);
|
||||||
void _printf debug(u32 level, bool timestamp,
|
void _printf debug(u32 level, bool timestamp,
|
||||||
u32 indent, const char *src,
|
u32 indent, const char *src,
|
||||||
u32 line, const char *, ...);
|
u32 line, const char *, ...);
|
||||||
|
|||||||
53
c/include/pjwhash-inline.h
Normal file
53
c/include/pjwhash-inline.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* pjwhash-inline.h - PJW hash function, inline version.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PJWHASH_INLINE_H
|
||||||
|
#define _PJWHASH_INLINE_H
|
||||||
|
|
||||||
|
#include "bits.h"
|
||||||
|
|
||||||
|
#define THREE_QUARTERS ((int) ((BITS_PER_INT * 3) / 4))
|
||||||
|
#define ONE_EIGHTH ((int) (BITS_PER_INT / 8))
|
||||||
|
#define HIGH_BITS ( ~((uint)(~0) >> ONE_EIGHTH ))
|
||||||
|
|
||||||
|
#ifndef _pjw_inline
|
||||||
|
#define _pjw_inline static inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsigned int pjwhash - PJW hash function
|
||||||
|
* @key: the key address.
|
||||||
|
* @length: the length of key.
|
||||||
|
*
|
||||||
|
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
|
||||||
|
* https://en.wikipedia.org/wiki/PJW_hash_function
|
||||||
|
*
|
||||||
|
* Return: the PJW hash.
|
||||||
|
*/
|
||||||
|
_pjw_inline uint pjwhash(const void* key, uint length)
|
||||||
|
{
|
||||||
|
uint hash = 0, high;
|
||||||
|
const u8 *k = key;
|
||||||
|
|
||||||
|
for (uint i = 0; i < length; ++k, ++i) {
|
||||||
|
hash = (hash << ONE_EIGHTH) + *k;
|
||||||
|
high = hash & HIGH_BITS;
|
||||||
|
if (high != 0) {
|
||||||
|
hash ^= high >> THREE_QUARTERS;
|
||||||
|
hash &= ~high;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _PJWHASH_INLINE_H */
|
||||||
30
c/include/pjwhash.h
Normal file
30
c/include/pjwhash.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* pjwhash.h - PJW hash function, extern version.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PJWHASH_H
|
||||||
|
#define _PJWHASH_H
|
||||||
|
|
||||||
|
#include "bits.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsigned int pjwhash - PJW hash function
|
||||||
|
* @key: the key address.
|
||||||
|
* @length: the length of key.
|
||||||
|
*
|
||||||
|
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
|
||||||
|
* https://en.wikipedia.org/wiki/PJW_hash_function
|
||||||
|
*
|
||||||
|
* Return: the PJW hash.
|
||||||
|
*/
|
||||||
|
extern uint pjwhash (const void* key, uint length);
|
||||||
|
|
||||||
|
#endif /* _PJWHASH_H */
|
||||||
105
c/include/struct-group.h
Normal file
105
c/include/struct-group.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/* struct-group.h - mirrored structure macros.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*
|
||||||
|
* Some parts are taken from Linux's kernel <linux/stddef.h> and others, and are :
|
||||||
|
* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STRUCT_GROUP_H
|
||||||
|
#define _STRUCT_GROUP_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __struct_group() - Create a mirrored named and anonyomous struct
|
||||||
|
*
|
||||||
|
* @TAG: The tag name for the named sub-struct (usually empty)
|
||||||
|
* @NAME: The identifier name of the mirrored sub-struct
|
||||||
|
* @ATTRS: Any struct attributes (usually empty)
|
||||||
|
* @MEMBERS: The member declarations for the mirrored structs
|
||||||
|
*
|
||||||
|
* Used to create an anonymous union of two structs with identical layout
|
||||||
|
* and size: one anonymous and one named. The former's members can be used
|
||||||
|
* normally without sub-struct naming, and the latter can be used to
|
||||||
|
* reason about the start, end, and size of the group of struct members.
|
||||||
|
* The named struct can also be explicitly tagged for layer reuse, as well
|
||||||
|
* as both having struct attributes appended.
|
||||||
|
*/
|
||||||
|
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
|
||||||
|
union { \
|
||||||
|
struct { MEMBERS } ATTRS; \
|
||||||
|
struct TAG { MEMBERS } ATTRS NAME; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
|
||||||
|
*
|
||||||
|
* @TYPE: The type of each flexible array element
|
||||||
|
* @NAME: The name of the flexible array member
|
||||||
|
*
|
||||||
|
* In order to have a flexible array member in a union or alone in a
|
||||||
|
* struct, it needs to be wrapped in an anonymous struct with at least 1
|
||||||
|
* named member, but that member can be empty.
|
||||||
|
*/
|
||||||
|
#define DECLARE_FLEX_ARRAY(TYPE, NAME) \
|
||||||
|
struct { \
|
||||||
|
struct { } __empty_ ## NAME; \
|
||||||
|
TYPE NAME[]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct_group() - Wrap a set of declarations in a mirrored struct
|
||||||
|
*
|
||||||
|
* @NAME: The identifier name of the mirrored sub-struct
|
||||||
|
* @MEMBERS: The member declarations for the mirrored structs
|
||||||
|
*
|
||||||
|
* Used to create an anonymous union of two structs with identical
|
||||||
|
* layout and size: one anonymous and one named. The former can be
|
||||||
|
* used normally without sub-struct naming, and the latter can be
|
||||||
|
* used to reason about the start, end, and size of the group of
|
||||||
|
* struct members.
|
||||||
|
*/
|
||||||
|
#define struct_group(NAME, MEMBERS...) \
|
||||||
|
__struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct_group_attr() - Create a struct_group() with trailing attributes
|
||||||
|
*
|
||||||
|
* @NAME: The identifier name of the mirrored sub-struct
|
||||||
|
* @ATTRS: Any struct attributes to apply
|
||||||
|
* @MEMBERS: The member declarations for the mirrored structs
|
||||||
|
*
|
||||||
|
* Used to create an anonymous union of two structs with identical
|
||||||
|
* layout and size: one anonymous and one named. The former can be
|
||||||
|
* used normally without sub-struct naming, and the latter can be
|
||||||
|
* used to reason about the start, end, and size of the group of
|
||||||
|
* struct members. Includes structure attributes argument.
|
||||||
|
*/
|
||||||
|
#define struct_group_attr(NAME, ATTRS, MEMBERS...) \
|
||||||
|
__struct_group(/* no tag */, NAME, ATTRS, MEMBERS)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct_group_tagged() - Create a struct_group with a reusable tag
|
||||||
|
*
|
||||||
|
* @TAG: The tag name for the named sub-struct
|
||||||
|
* @NAME: The identifier name of the mirrored sub-struct
|
||||||
|
* @MEMBERS: The member declarations for the mirrored structs
|
||||||
|
*
|
||||||
|
* Used to create an anonymous union of two structs with identical
|
||||||
|
* layout and size: one anonymous and one named. The former can be
|
||||||
|
* used normally without sub-struct naming, and the latter can be
|
||||||
|
* used to reason about the start, end, and size of the group of
|
||||||
|
* struct members. Includes struct tag argument for the named copy,
|
||||||
|
* so the specified layout can be reused later.
|
||||||
|
*/
|
||||||
|
#define struct_group_tagged(TAG, NAME, MEMBERS...) \
|
||||||
|
__struct_group(TAG, NAME, /* no attrs */, MEMBERS)
|
||||||
|
|
||||||
|
#endif /* _STRUCT_GROUP_H */
|
||||||
20
c/pjwhash.c
Normal file
20
c/pjwhash.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* pjwhash.c - PJW hash function.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _pjw_inline extern
|
||||||
|
|
||||||
|
//#include "bits.h"
|
||||||
|
//extern unsigned int pjwhash (const void* key, uint length);
|
||||||
|
|
||||||
|
#include "pjwhash.h"
|
||||||
|
#include "pjwhash-inline.h"
|
||||||
Reference in New Issue
Block a user