mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-07 16:06:09 +00:00
96 lines
2.7 KiB
C
96 lines
2.7 KiB
C
#ifndef _FLEX_ARRAY_H
|
|
#define _FLEX_ARRAY_H
|
|
|
|
typedef unsigned char u8;
|
|
typedef unsigned short u16;
|
|
typedef unsigned int u32;
|
|
typedef unsigned int uint32_t;
|
|
typedef unsigned long long u64;
|
|
typedef unsigned long long uint64_t;
|
|
typedef int gfp_t;
|
|
#define PAGE_SIZE 4096
|
|
#define FLEX_ARRAY_PART_SIZE PAGE_SIZE
|
|
#define FLEX_ARRAY_BASE_SIZE PAGE_SIZE
|
|
|
|
struct reciprocal_value {
|
|
u32 m;
|
|
u8 sh1, sh2;
|
|
};
|
|
|
|
static inline u32 reciprocal_divide(u32 a, struct reciprocal_value R)
|
|
{
|
|
u32 t = (u32)(((u64)a * R.m) >> 32);
|
|
return (t + ((a - t) >> R.sh1)) >> R.sh2;
|
|
}
|
|
|
|
|
|
#define min(x, y) ({ \
|
|
typeof(x) _min1 = (x); \
|
|
typeof(y) _min2 = (y); \
|
|
(void) (&_min1 == &_min2); \
|
|
_min1 < _min2 ? _min1 : _min2; })
|
|
|
|
#define max(x, y) ({ \
|
|
typeof(x) _max1 = (x); \
|
|
typeof(y) _max2 = (y); \
|
|
(void) (&_max1 == &_max2); \
|
|
_max1 > _max2 ? _max1 : _max2; })
|
|
|
|
#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */
|
|
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
|
|
struct flex_array_part;
|
|
|
|
struct flex_array {
|
|
union {
|
|
struct {
|
|
int element_size;
|
|
int total_nr_elements;
|
|
int elems_per_part;
|
|
struct reciprocal_value reciprocal_elems;
|
|
struct flex_array_part *parts[];
|
|
};
|
|
/*
|
|
* This little trick makes sure that
|
|
* sizeof(flex_array) == PAGE_SIZE
|
|
*/
|
|
char padding[FLEX_ARRAY_BASE_SIZE];
|
|
};
|
|
};
|
|
|
|
#define FLEX_ARRAY_BASE_BYTES_LEFT \
|
|
(FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts))
|
|
|
|
#define FLEX_ARRAY_NR_BASE_PTRS \
|
|
(FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *))
|
|
|
|
#define FLEX_ARRAY_ELEMENTS_PER_PART(size) \
|
|
(FLEX_ARRAY_PART_SIZE / size)
|
|
|
|
#define DEFINE_FLEX_ARRAY(__arrayname, __element_size, __total) \
|
|
struct flex_array __arrayname = { { { \
|
|
.element_size = (__element_size), \
|
|
.total_nr_elements = (__total), \
|
|
} } }; \
|
|
static inline void __arrayname##_invalid_parameter(void) \
|
|
{ \
|
|
BUILD_BUG_ON((__total) > FLEX_ARRAY_NR_BASE_PTRS * \
|
|
FLEX_ARRAY_ELEMENTS_PER_PART(__element_size)); \
|
|
}
|
|
|
|
struct flex_array *flex_array_alloc(int element_size, unsigned int total, gfp_t flags);
|
|
int flex_array_prealloc(struct flex_array *fa, unsigned int start, unsigned int nr_elements, gfp_t flags);
|
|
void flex_array_free(struct flex_array *fa);
|
|
void flex_array_free_parts(struct flex_array *fa);
|
|
int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
|
|
gfp_t flags);
|
|
int flex_array_clear(struct flex_array *fa, unsigned int element_nr);
|
|
void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
|
|
int flex_array_shrink(struct flex_array *fa);
|
|
|
|
#define flex_array_put_ptr(fa, nr, src, gfp) \
|
|
flex_array_put(fa, nr, (void *)&(src), gfp)
|
|
|
|
void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr);
|
|
|
|
#endif /* _FLEX_ARRAY_H */
|