└───liblfds710 ├───inc │ └───liblfds710 │ lfds710_freelist.h └───src └───lfds710_stack lfds710_freelist_init.c
struct lfds710_freelist_element; struct lfds710_freelist_state;
void lfds710_freelist_init_valid_on_current_logical_core( struct lfds710_freelist_state *fs, struct lfds710_freelist_element * volatile (*elimination_array)[LFDS710_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS], lfds710_pal_uint_t elimination_array_size_in_elements, void *user_state );
struct lfds710_freelist_state *fs
- A pointer to a user-allocated LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES aligned struct lfds710_freelist_state. Stack declared variables will automatically be correctly aligned by the compiler, due to the information in the structure definitions; nothing has to be done. Heap allocated variables however will by no means be correctly aligned and an aligned malloc must be used.
struct lfds710_freelist_element * volatile (*elimination_array)[LFDS710_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS]
- A pointer to an array of struct lfds710_freelist_element * volatile, where each element in that array is itself an array containing LFDS710_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS number elements. To put it less precisely but more understandably, the idea is to have an array where each element is the size of a cache line, where each line in the array is being used to hold struct liblfds710_freelist_element *. (LFDS710_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS is a convenience define and is in fact LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES (which is the cache line length or equivelent thereof) divided by the size of a struct lfds710_freelist_element *). The number of cache lines in the array is chosen by the user (but must be a power of two), with a recommended value being the smallest value equal to or larger than one per thread which will be accessing the freelist (so if four threads might use the freelist at the same time, four elements. The array must be aligned to LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES (and given each line is that long too, each line will then therefore also be similarly aligned, which is what the API needs). This argument can be NULL, in which case the elimination array is not used, and the struct lfds710_prng_st_state * arguments to lfds710_freelist_push and lfds710_freelist_push will be ignored.
- The number of elements (cache lines) in the array pointed to by elimination_array. If elimination_array is set to NULL, set this argument to 0. This argument must be a power of two (i.e. 2, 4, 8, 16, 32, 64, etc).
- A void pointer for arbitrary user state. This is stored in the freelist state and can be retrieved later at any time from the stack state using the LFDS710_FREELIST_GET_USER_STATE_FROM_STATE macro, in particular in callbacks, when they receive the freelist state as one of their arguments.
As the function name indicates, the initialization work performed on the freelist state is only valid on the current logical core. To make this work valid on other logical cores, threads on other cores must call LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE.