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