└───liblfds711 ├───inc │ └───liblfds711 │ lfds711_freelist.h └───src └───lfds711_stack lfds711_freelist_init.c
struct lfds711_freelist_element; struct lfds711_freelist_state;
void lfds711_freelist_init_valid_on_current_logical_core( struct lfds711_freelist_state *fs, struct lfds711_freelist_element * volatile (*elimination_array)[LFDS711_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS], lfds711_pal_uint_t elimination_array_size_in_elements, void *user_state );
struct lfds711_freelist_state *fs
- A pointer to a user-allocated LFDS711_PAL_ATOMIC_ISOLATION_IN_BYTES aligned struct lfds711_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 lfds711_freelist_element * volatile (*elimination_array)[LFDS711_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS]
- A pointer to an array of struct lfds711_freelist_element * volatile, where each element in that array is itself an array containing LFDS711_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 liblfds711_freelist_element *. (LFDS711_FREELIST_ELIMINATION_ARRAY_ELEMENT_SIZE_IN_FREELIST_ELEMENTS is a convenience define and is in fact LFDS711_PAL_ATOMIC_ISOLATION_IN_BYTES (which is the cache line length or equivelent thereof) divided by the size of a struct lfds711_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 LFDS711_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 lfds711_prng_st_state * arguments to lfds711_freelist_push and lfds711_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 LFDS711_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 LFDS711_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE.