

C11 Lock-free Stack - signa11
http://nullprogram.com/blog/2014/09/02/

======
haberman
The biggest bummer of lock-free data structures from my perspective is the
reclamation problem.

Hazard pointers solve the problem but they are API-intrusive. Notably, hazard
pointers require thread-local state, as well as some global structure that
contains the entire list of threads. That means you have to
register/deregister threads when when they are created/destroyed.

So essentially your API needs to look like this:

    
    
        mylib_perthread_t *perthread = mythread_perthread_new();
    
        // Later:
        mylib_lockfreestack_push(obj, perthread, val);
    
        // When the thread shuts down:
        mylib_perthread_free(perthread);
    

But this is API-intrusive:

    
    
        1. each thread must call mylib_perthread_new()
        2. the thread needs thread-local storage for "perthread"
        3. the thread must call mylib_perthread_free() before exiting
    

C11 and C++11 have thread-local storage, which solves (2), but (1) and (3) are
still API-intrusive. Having to explicitly initialize/uninitialize a library
per-thread resource is very uncommon. Worse, it doesn't compose well.

Until this problem has a convenient and idiomatic solution, it's hard to
imagine hazard pointers being very useful in idiomatic C and C++ APIs.

Without hazard pointers, your only real options are:

    
    
        1. use a fixed-size structure (specify up front its max size)
        2. don't free any nodes until the structure itself is deleted
    

The first is what this article does. The second is what boost.lockfree does.
But without hazard pointers, you also need to solve the ABA problem, which
requires either DCAS (double compare-and-swap), or a fixed-size structure that
you index by offset instead of by pointer.

It just occurred to me that a flow-chart of all these options and variations
could be interesting.

~~~
throwawayaway
maybe i'm a clown(i certainly haven't written any libraries).

but with pthreads for example you you put the new()and free() into a wrapper
around the function you want to call?

void wrapper() {

    
    
      new();
    
      job();
    
      free();
    

}

pthread_t thread;

int yes = 0;

pthread_create(&thread, NULL, wrapper, (void *) &yes);

~~~
haberman
That works if you are the application, or a framework that is in control of
all thread creation.

If you are just trying to be a thread-safe library though, you aren't at
liberty to do that. For example, say someone wrote a thread-safe stack, like
the article author. As the user of that thread-safe, lock-free stack, you
don't want to put it in charge of all your threading, it's just one little
library you're using.

------
justincormack
There is a C11 threads implementation, in Musl libc[1]. It is not committed
yet, but looks like it will be in the next release - there are patches on the
mailing list.

[1] [http://www.musl-libc.org/](http://www.musl-libc.org/)

------
voidlogic
While it is true that lock free data structures provide much better throughput
in highly contended environments people forget that in the many reads/few
writers situations they often are slower the Read/Write mutexes. Maybe some of
the upcoming transactional memory instructions will improve this, but for the
time being, and probably always- benchmark your code!

~~~
readerrrr
In that case you can add signals and send threads to sleep if there is not
enough elements on the stack, and wake them up if the stack starts growing
faster.

~~~
jacquesm
But you're _still_ burning more cycles, this isn't just about spinning read
threads without input.

------
bithush
If you are on Windows I highly recommend Pelles C
[http://www.smorgasbordet.com/pellesc/](http://www.smorgasbordet.com/pellesc/)

------
verroq
>C11 hasn't received anywhere near the same amount of fanfare as C++11

Well did C11 add lambdas? Didn't think so.

