Pulling on a thread (thread – see? geddit? see what I did there?)

Sometimes, the only thing to say is this : gaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhh!!!

So, I had an innocent little thing on my small to-do list; “lfds700_list_asu_get_start_and_then_next() should be a macro, not a function”.

See, the lists have this convenience function, for iterating over the list. It takes the list state and a pointer to a list element, which is initialized before calling the function to NULL. If the pointer to the list element is NULL, then it is set to point to the first element in the list, otherwise, it is moved to point to the element after itself.

So you use it like this;

struct lfds700_asu_element
*le = NULL;

while( lfds700_list_asu_get_start_and_then_next(ls, &le) )
// TRD : do work

The problem of course is you’re making a function call per iteration, which is totally not okay.

Now, there exist already a pair of macros, LFDS700_LIST_ASU_GET_START and LFDS700_LIST_ASU_GET_NEXT. That function uses them.

Now, given the expected usage, inside a while loop, we cannot in the macro version of the function use curley braces.

Problem is, those two macros, they both issue a load barrier – and that load barrier, on some platforms, is an atomic exchange – and that means we need some store, two temporary variables, and to get them… we’re using curley braces.

In fact this work touches upon this larger issue – I would like to be able to use all these macros inside while() brackets.

Exchange is not the only atomic operation which currently needs store – given the normalized form I’ve selected for CAS and DCAS, some platforms need store for those ops as well.

The only way I can see to get round this is to have these macros as inline functions.

That means changing the liblfds header files to be C files, and #including them rather than the header files.