Introduction

Release 7.1.0 is from a minor release in terms of upgrading from 7.0.0. The requirement for a per-thread state has been removed, and there have been superficial name changes to two APIs, and a change to the freelist init prototype. Internally, a lot of work has been done - the test programme has been refactored into libraries, libshared and libtest, leaving the test programme a thin command line veneer, and a benchmark programme has been added, again, in the form of a library, libbenchmark, with a thin command line veneer, benchmark. The benchmark compares locking mechanims (mutexs, etc) against both the current and previous versions of liblfds.

Upgrade Paths

It is not possible to upgrade from 6.x.x to 7.x.x. Code has to be rewritten. However, 6.0.1 and 6.1.1 can be compiled and linked into the same code base as 7.x.x, so existing code does not need to be migrated.

Upgrading from 7.0.0 to 7.1.0 involves accomodating the API name change for the singly-linked ordered list and the queue, and the change to the freelist init function to accomodate the new elimination array.

User-Visible Changes

liblfds

Per-thread state no longer required.

Library-wide init/cleanup functions removed.

The source code layout has changed in that all versions of liblfds are now released together (this is needed for benchmark, which benchmarks earlier versions).

"list_aos" has renamed to "list_aso".

"queue" has been renamed to "queue_umm".

freelist init function prototype has changed.

New API, PRNG, for random number generation.

New queue API, queue_bmm, bounded, many-producer, many-consumer.

Makefile rewritten to adhere more closely to gnumake standards (CFLAGS, etc, now work as expected).

Per-Thread State

In 7.0.0, all API functions which performed a lock-free operation took as their final argument a struct lfds700_misc_prng_state *ps, a per-thread state used to produce random numbers for exponential backoff.

Experimentation has shown it's simply not necessary. As long as the backoff is exponential in nature, rather than linear, having or not having the random component of the backoff period selection simply did not make a difference to performance. Probably the inherently random timing of the operations themselves does the job already.

As such, this - onerous! being per-thread - argument has been removed.

Library Wide Init/Cleanup

The library wide init/cleanup came into existance in 7.0.0 to initialize the exponential backoff code - initializing the master PRNG which generated the seeds for the per-thread PRNGs, and initializing the global CAS and DWCAS backoff values. Version 7.1.0 now has autotuning backoff code (which really does seem to work - at least according to the benchmarks!) and the pre-thread PRNGs have gone, which also removes the master PRNG, so there's no work for a library wide init to perform, so they've gone.

API Renames

Before

After

list_aos

list_aso

queue

queue_umm

So for example everything which formerly was lfds700_queue_[blah] - all the struct names, enums, function prototypes, etc - is now lfds710_queue_umm_[blah]. (umm being short for Unbounded, Many Producer, Many Consumer - given that there are now three queues, each of a different type, they had to be identified in their name).

Freelist

The freelist now implements an "elimination array", to improve performance. This is optional (whether or not it is used is specified in the freelist init call) but if it is used, the number of elements in the freelist must be increased by the size of the elimination array (on 32 bit platforms, this comes to four elements per logical processor, on 64 bit platforms, eight elements per logical processor).