Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Functions
flex_array.h File Reference
#include <linux/types.h>
#include <asm/page.h>

Go to the source code of this file.

Data Structures

struct  flex_array
 

Macros

#define FLEX_ARRAY_PART_SIZE   PAGE_SIZE
 
#define FLEX_ARRAY_BASE_SIZE   PAGE_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)
 
#define flex_array_put_ptr(fa, nr, src, gfp)   flex_array_put(fa, nr, (void *)&(src), gfp)
 

Functions

struct flex_arrayflex_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)
 
voidflex_array_get (struct flex_array *fa, unsigned int element_nr)
 
int flex_array_shrink (struct flex_array *fa)
 
voidflex_array_get_ptr (struct flex_array *fa, unsigned int element_nr)
 

Macro Definition Documentation

#define DEFINE_FLEX_ARRAY (   __arrayname,
  __element_size,
  __total 
)
Value:
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)); \
}

Definition at line 52 of file flex_array.h.

#define FLEX_ARRAY_BASE_BYTES_LEFT   (FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts))

Definition at line 37 of file flex_array.h.

#define FLEX_ARRAY_BASE_SIZE   PAGE_SIZE

Definition at line 8 of file flex_array.h.

#define FLEX_ARRAY_ELEMENTS_PER_PART (   size)    (FLEX_ARRAY_PART_SIZE / size)

Definition at line 45 of file flex_array.h.

#define FLEX_ARRAY_NR_BASE_PTRS   (FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *))

Definition at line 41 of file flex_array.h.

#define FLEX_ARRAY_PART_SIZE   PAGE_SIZE

Definition at line 7 of file flex_array.h.

#define flex_array_put_ptr (   fa,
  nr,
  src,
  gfp 
)    flex_array_put(fa, nr, (void *)&(src), gfp)

Definition at line 75 of file flex_array.h.

Function Documentation

struct flex_array* flex_array_alloc ( int  element_size,
unsigned int  total,
gfp_t  flags 
)
read

flex_array_alloc - allocate a new flexible array : the size of individual elements in the array : total number of elements that this should hold : page allocation flags to use for base array

Note: all locking must be provided by the caller.

is used to size internal structures. If the user ever accesses any array indexes >=, it will produce errors.

The maximum number of elements is defined as: the number of elements that can be stored in a page times the number of page pointers that we can fit in the base structure or (using integer math):

(PAGE_SIZE/element_size) * (PAGE_SIZE-8)/sizeof(void *)

Here's a table showing example capacities. Note that the maximum index that the get/put() functions is just nr_objects-1. This basically means that you get 4MB of storage on 32-bit and 2MB on 64-bit.

Element size | Objects | Objects | PAGE_SIZE=4k | 32-bit | 64-bit | ------------------------------—| 1 bytes | 4177920 | 2088960 | 2 bytes | 2088960 | 1044480 | 3 bytes | 1392300 | 696150 | 4 bytes | 1044480 | 522240 | 32 bytes | 130560 | 65408 | 33 bytes | 126480 | 63240 | 2048 bytes | 2040 | 1020 | 2049 bytes | 1020 | 510 | void * | 1044480 | 261120 |

Since 64-bit pointers are twice the size, we lose half the capacity in the base structure. Also note that no effort is made to efficiently pack objects across page boundaries.

Definition at line 88 of file flex_array.c.

int flex_array_clear ( struct flex_array fa,
unsigned int  element_nr 
)

flex_array_clear - clear element in array at : the flex array of the element. : index of the position to clear.

Locking must be provided by the caller.

Definition at line 225 of file flex_array.c.

void flex_array_free ( struct flex_array fa)

Definition at line 143 of file flex_array.c.

void flex_array_free_parts ( struct flex_array fa)

flex_array_free_parts - just free the second-level pages : the flex array from which to free parts

This is to be used in cases where the base 'struct flex_array' has been statically allocated and should not be free.

Definition at line 132 of file flex_array.c.

void* flex_array_get ( struct flex_array fa,
unsigned int  element_nr 
)

flex_array_get - pull data back out of the array : the flex array from which to extract data : index of the element to fetch from the array

Returns a pointer to the data at index . Note that this is a copy of the data that was passed in. If you are using this to store pointers, you'll get back &ptr. You may instead wish to use the flex_array_get_ptr helper.

Locking must be provided by the caller.

Definition at line 310 of file flex_array.c.

void* flex_array_get_ptr ( struct flex_array fa,
unsigned int  element_nr 
)

flex_array_get_ptr - pull a ptr back out of the array : the flex array from which to extract data : index of the element to fetch from the array

Returns the pointer placed in the flex array at element_nr using flex_array_put_ptr(). This function should not be called if the element in question was not set using the _put_ptr() helper.

Definition at line 340 of file flex_array.c.

int flex_array_prealloc ( struct flex_array fa,
unsigned int  start,
unsigned int  nr_elements,
gfp_t  flags 
)

flex_array_prealloc - guarantee that array space exists : the flex array for which to preallocate parts : index of first array element for which space is allocated : number of elements for which space is allocated : page allocation flags

This will guarantee that no future calls to flex_array_put() will allocate memory. It can be used if you are expecting to be holding a lock or in some atomic context while writing data into the array.

Locking must be provided by the caller.

Definition at line 263 of file flex_array.c.

int flex_array_put ( struct flex_array fa,
unsigned int  element_nr,
void src,
gfp_t  flags 
)

flex_array_put - copy data into the array at : the flex array to copy data into : index of the position in which to insert the new element. : address of data to copy into the array : page allocation flags to use for array expansion

Note that this copies the contents of into the array. If you are trying to store an array of pointers, make sure to pass in &ptr instead of ptr. You may instead wish to use the flex_array_put_ptr() helper function.

Locking must be provided by the caller.

Definition at line 193 of file flex_array.c.

int flex_array_shrink ( struct flex_array fa)

flex_array_shrink - free unused second-level pages : the flex array to shrink

Frees all second-level pages that consist solely of unused elements. Returns the number of pages freed.

Locking must be provided by the caller.

Definition at line 371 of file flex_array.c.