1
0
mirror of https://github.com/ioacademy-jikim/debugging synced 2025-06-07 16:06:09 +00:00
debugging/05_day/flex_array/flex_array.h
2015-12-13 22:34:58 +09:00

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 */