News for hackers. Stuff that matters.
Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @09:54AM (#11806487)
The documentation is viewed via an embedded frame. So you can't save URLs to the documentation. This is a known bad practice for web sites.

The API changes with every release. WTF?

struct lfds710_freelist_element;

Really? Just... really? In order to use a newer version this library, you have to change your entire application for the updated function names.

And many of the lock-free structures are add-only. The binary tree is unbalanced. Which makes it not a very good binary tree.

This looks like it was written by somone who heard "lock free", and went "cool, I'll write a library!"

And he missed the last 40 years of software best practices.

The web site is bad, the APIs are bad, the functions aren't very useful, the library isn't very portable, etc.

People shouldn't use this library for anything.

[edit] Updated the comment about "someone" being a 16 year-old student.

Re:Liblfds, a portable, license-free, lock-free data structu... by nneonneo on Tuesday May 31, 2016 @12:32PM (#11807547)
The library also uses some absurdly long identifiers which are bound to clutter your code one way or another. To iterate a binary tree, use

while(lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(state, &element, LFDS710_BTREE_AU_SMALLEST_IN_TREE, LFDS710_BTREE_AU_INORDER_WALK_FROM_SMALLEST_TO_LARGEST))

It's not going to be possible to remember what names to use when you need to iterate. Or, take the initialization routine. You first call

lfds710_btree_au_init_valid_on_current_logical_core( &state, key_compare_function, LFDS710_BTREE_AU_EXISTING_KEY_FAIL, NULL );

on one core, which is perhaps reasonable, but then you call

LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE()

on other cores. That is one hell of a #define, and it's not even clear from the name what it's doing. It seems like "LFDS710_MISC_SYNC_INITS" or something along those lines would be clearer and easier to remember.

Re:Liblfds, a portable, license-free, lock-free data structu... by Sir_Cmpwn on Tuesday May 31, 2016 @02:54PM (#11809073)
Holy shit! That's 71 characters, which leaves you 9 characters for your code. 4 of that goes to indentation, 3 of that goes to (); and you have 2 characters left for the parameters before you break the 80 character limit. That's horrifying.
Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @05:07PM (#11810246)
OTOH, you do know exactly what it does, without having to read any docs.

I am of course open to suggestions for improvement.

Re:Liblfds, a portable, license-free, lock-free data structu... by mjevans on Tuesday May 31, 2016 @09:54PM (#11811622)
Encourage the adoption of a line-width that is longer than ancient terminals (at least it isn't 40 cols across).

Also I'm much less concerned with absolute line width in my own code than I am with indentation steps or number of arguments something takes without flowing on to multiple lines.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:11PM (#11807978)
Yes, some of the identifiers are very long. The aim was to make the APIs self-explanatory. It should be possible to read an API and know what it does. It's challanging to explain an inorder walk, and its direction, in a shorter form.

The goal of course is for all identifiers to be as short as possible.

Re:Liblfds, a portable, license-free, lock-free data structu... by ch on Tuesday May 31, 2016 @05:07PM (#11810248)
What about replacing FROM_SMALLEST_TO_LARGEST with ASCENDING?
Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @07:29PM (#11811094)
That could work. ASCENDING and DESCENDING. I'll think it over (in the morning - I'm about comatose right now).
Re:Liblfds, a portable, license-free, lock-free data structu... by jhpriestley on Tuesday May 31, 2016 @11:26AM (#11807075)
The criticism of the documentation is fair, but it's an incredibly trivial point. You can save URLs to the documentation if you right-click the link.

For example, here is the link to the rationale for the versioned naming scheme:

http://liblfds.org/mediawiki/index.php?title=Introduction#Co...

Do you even understand the significance of "lock-free" in the title here? Do you have some basis to think that the weaknesses of the data structures, like unbalanced trees and add-only collections, can be remedied without using locks? If you do then that would be an interesting criticism, but as it is it looks like you just opened the page, looked around for a few things to criticize, and then wrote this sour, shallow, dismissive comment.

Re:Liblfds, a portable, license-free, lock-free data structu... by openasocket on Tuesday May 31, 2016 @11:43AM (#11807199)
A quick google shows that there are lock-free implementations of AVL trees and red-black trees. And every paper I've ever read about lock-free data structures includes both addition and removal operations.
Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:20PM (#11808090)
Yes. I have seen the white paper for the red-black tree, and the approach used should work for AVL (I've not seen that paper). I've just not had time to implement yet. A full O(log n) data structure is necessary for the library to be really useful piece of work - but there's a lot of other things which are necessary for that, too, and they have so far taken up most of the development time.

About 10% of the effort so far has gone into coding the actual data structures - almost all the work goes into testing, benchmarking, performance tuning, documentation, porting to new platforms, fundamental improvements in the basic design and so on. The benchmark app alone has taken all in all about six full months to write. I thought it'd be simple, it turned out to be a tar-pit!

Re:Liblfds, a portable, license-free, lock-free data structu... by openasocket on Tuesday May 31, 2016 @01:36PM (#11808298)
Honestly, I wouldn't bother with red-black or AVL. I'm not sure about the current state of lock-free data structures, but I prefer a B-Tree to a red-black or AVL tree. At least in the single-threaded case B-Tree operations tend to be faster, have better cache locality, etc. Google reveals there are lock-free implementations of B-Trees, so maybe look into those instead?
Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @02:09PM (#11808653)
Could be. I will look into the choice before I commit - figuring out how one of these complex lock-free data structures works and implmenting it correctly and writing all the tests cases is a major undertaking. It's something you want to make sure you're making the right choice about before you invest the time.

As an aside, binary trees turn out to be really great with lock-free. In the obvious locking implementations, there's one lock per tree. You can use read-writer locks to get parallelism on read, but even so, the mere existance of a single lock of any kind induces memory contention which eliminates scaling as processor counts rise.

I'm sure there are in the locking literature better solutions, but I'm up to speed with lock-free, rather than locking, solutions, so I don't much know about them.

Regarding lock-free, there is no single lock, and btrees are beautiful because they naturally distribute memory accesses throughout the tree. Performance basically scales linearly. There's a gnuplot on the site from a 16 core Amazon VM, and that property can clearly be seen. Every new core simply adds another 200k benchmark ops per second. For the other, non-scaling data structures, new cores are death.

Re:Liblfds, a portable, license-free, lock-free data structu... by nothrabannosir on Tuesday May 31, 2016 @10:21AM (#11806652)
> This looks like it was written by a 16 year-old student who heard "lock free", and went "cool, I'll write a library!"

Nothing wrong with that, though. In fact, that's great.

Word to the 16-year-olds (or any-year-olds) doing that: put a disclaimer in your README to avoid this kind of reply being top comment in a HN thread about your work :)

Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @10:23AM (#11806668)
I wrote code when I was 16. There's nothing wrong with being that age.

What is wrong is not learning from others. This library follows many practices which are well known as "worst practices" in the industry.

Re:Liblfds, a portable, license-free, lock-free data structu... by partycoder on Tuesday May 31, 2016 @02:31PM (#11808848)
Can you elaborate more on those "worst practices"?
Re:Liblfds, a portable, license-free, lock-free data structu... by huhtenberg on Tuesday May 31, 2016 @10:15AM (#11806608)
Who peed in your espresso this morning?
Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @10:25AM (#11806678)
The best response to a technical review of software is an ad hominem.

Good to know.

Re:Liblfds, a portable, license-free, lock-free data structu... by DiabloD3 on Tuesday May 31, 2016 @10:49AM (#11806811)
Well, what we should be doing is a double blind test to find out if pee in espresso improves performance, and what the minimum effective dose is.
Re:Liblfds, a portable, license-free, lock-free data structu... by ma2rten on Tuesday May 31, 2016 @11:17AM (#11807010)
Well, ... your technical review was ad hominem in the first place.
Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @12:33PM (#11807552)
Because saying someone looks 16 is an insult?
Re:Liblfds, a portable, license-free, lock-free data structu... by loeg on Tuesday May 31, 2016 @01:13PM (#11807999)
When you say it like you did initially, yes!
Re:Liblfds, a portable, license-free, lock-free data structu... by arcticbull on Tuesday May 31, 2016 @06:42PM (#11810851)
I think that's actually the definition of an ad hominem attack :)
Re:Liblfds, a portable, license-free, lock-free data structu... by jotux on Tuesday May 31, 2016 @11:58AM (#11807287)
Comments like this are exactly why people are afraid to release projects to the public and contribute to open source.
Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @12:32PM (#11807546)
If you're afraid of negative feedback, you will never do anything, and you will never learn anything.

In this case, I'm astonished at just how many bad practices the author has engaged in. Do most software projects have structs / functions / whatever where the names are versioned?

It's one thing for TempleOS to invent his own OS, build system, programming language, GUI, etc. He made some odd choices, but at least he's clear he doesn't care (much) about other people using his code. And, it's clear his code works, and does something useful.

The author of this library has invented many of his own programming practices... which are clearly worse than current industry practices. Why? I can't say. But I can say that they are worse.

I just don't understand this attitude that all feedback has to be couched carefully to avoid hurting anyones feelings. If it's bad, it's bad.

Perhaps you could be productive, and post your review of his code. If it's in any way negative, (by your standards), I should jump on the review as being overly negative, and "you're the reason why people don't do open source."

Adults should be able to take criticism. If they can't, I have very little sympathy for them.

Re:Liblfds, a portable, license-free, lock-free data structu... by jotux on Tuesday May 31, 2016 @01:47PM (#11808421)
>I just don't understand this attitude that all feedback has to be couched carefully to avoid hurting anyones feelings.

>Adults should be able to take criticism. If they can't, I have very little sympathy for them.

Again, your outlook is toxic to newcomers. Yes people should be able to handle criticism but you should be capable of crafting that criticism in a way that isn't mean spirited and rude.

I wish more projects and communities had code of conduct rules similar to the rust language: https://www.rust-lang.org/conduct.html

Which includes rules your comment would obviously violate:

    Please be kind and courteous. There’s no need to be mean or rude.
Re:Liblfds, a portable, license-free, lock-free data structu... by cyphar on Tuesday May 31, 2016 @06:41PM (#11810841)
> >I just don't understand this attitude that all feedback has to be couched carefully to avoid hurting anyones feelings.

> >Adults should be able to take criticism. If they can't, I have very little sympathy for them.

> Again, your outlook is toxic to newcomers. Yes people should be able to handle criticism but you should be capable of crafting that criticism in a way that isn't mean spirited and rude.

I don't think that's a fair statement. If someone has done something badly, they've done it badly and they should be told that. You're not doing anyone any benefit by sugar coating it by first saying "great job on trying". Personally, I prefer getting a frank and honest review of my work rather than having to tease out why someone doesn't like it but they won't state it plainly because they'll "hurt my feelings". We're discussing code, and if code is bad then we should make it clear that it's bad, say how to do it better, and move on.

Re:Liblfds, a portable, license-free, lock-free data structu... by jotux on Tuesday May 31, 2016 @07:01PM (#11810955)
I agree completely with what you're saying but this:

>This looks like it was written by a 16 year-old student who heard "lock free", and went "cool, I'll write a library!" And he missed the last 40 years of software best practices.

Is not constructive criticism, it's just being rude.

Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Wednesday June 01, 2016 @10:03AM (#11814398)
You're unwilling to give constructive criticism yourself. I suspect because you know that by your standards, any negative criticism can be labeled as "mean and rude".

You've been given multiple opportunities to give positive criticism yourself. And you've refused. Your position is entirely negative.

For something where you are more offended than the author of the library. He's an adult, and he can defend himself. You're infantilizing him by protecting him from things where he doesn't want protection.

The code of conduct you linked to would seem to prohibit your overly negative behavior.

i.e. your comments have come across (to use a common phrase here), as toxic.

Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @07:28PM (#11811090)
> Again, your outlook is toxic to newcomers.

I disagree.

> you should be capable of crafting that criticism in a way that isn't mean spirited and rude.

As I suggested, perhaps you could give some positive criticism of your own, and give your review. Not doing that means you're demanding I do something which you won't do.

This is not a trivial point. I'll bet that you'll find it difficult to craft a technical review which points out the flaws in his software, without anyone being able to claim it's being "mean and rude".

Try it. Please.

> I wish more projects and communities had code of conduct rules

That's nice. But I wish more projects had code of conduct rules on people asking questions. I've been doing open source for 20+ years. There is a large subset of people who don't read the documentation, don't ask good questions, who ignore all attempts to help them...

... but ...

their behavior is superficially polite. Until they get frustrated that "no one is helping them", and they start complaining that everyone is being mean to them.

That behavior is toxic, and I have no patience for it.

Yet strangely, I've yet to see a "code of conduct" which deals with this issue. It's open source... you shouldn't demand that other people help you, no matter how politely you make that request.

And (as with most such arguments I've had), I'll note that you're more offended by my comments than the author is. Such over-sensitivity seems to me "problematic". The author is an adult. He can clearly take criticism. Perhaps learning from his example would be good.

Re:Liblfds, a portable, license-free, lock-free data structu... by devishard on Tuesday May 31, 2016 @01:22PM (#11808119)
So? I don't think the world needs more bad open-source code. If people only open-source good code, then that saves everyone the trouble of sifting through the junk like this. People being afraid to open source bad code would be a good thing.

And having a top comment on HN warning me that the code is pretty bad saves me time, too, because I don't have to read the code or try using it to find that out. So I really appreciate people publicly pointing out that the code is bad.

I'd feel more positive about this code if it had been submitted with a request for code review and feedback rather than being presented as a "a portable, license-free, lock-free data structure library written in C" with a whole website advertising it as being ready for use.

Re:Liblfds, a portable, license-free, lock-free data structu... by cyphar on Tuesday May 31, 2016 @06:42PM (#11810856)
I think making all code free software would allow bad code to be fixed, which would result in a much better state of affairs than having proprietary software that won't ever be made free because the author won't fix it.
Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:01PM (#11807842)
> The documentation is viewed via an embedded frame. So you > can't save URLs to the documentation. This is a known bad > practice for web sites.

Yes and no. The site currently is arranged with a set of tabs on the left and a frame on the right. It had to be a frame because some of the web-based apps, such as the mediawiki used for documentation, generate output encapsulated in the "<HTML>" tag. As such, their output cannot be captured and placed into a div; it has to go into its own frame.

However, the documentation can be opened in a new tab (right click, open in new tab) and then where it has its own browser window, the URL is displayed as normal.

Of course, this is not the default behaviour - the user has to do something to get it, and to realise that it is possible. That is a problem. The only obvious solution is to have the documentation automatically open in a new window. That's a bit unpleasent though - new windows popping up unexpectedly is not good for the user experience.

> The API changes with every release. WTF? Really? Just... really? In order to use a newer version this library, you have to change your entire application for the updated function names.

No. All versions of the library can concurrently be included and linked against. The reason for this is so that any code which using an existing version of the library does not have to be modified at all - and so does not need to be revalidated - when a new version is published.

IME, once code is written, and given that it works, it tends quite strongly not to change. It works, so why spend time and effort merely to change it? however, if a new version of a library comes out, anything could have happened - so existing code has to be revalidated. It's extra work. This is avoided by supporting concurrent use of multiple library versions.

> And many of the lock-free structures are add-only. The binary tree is unbalanced. Which makes it not a very > good binary tree.

The add-onlys were thrown together in a week or so many months ago, just to get those classes of data strutures out there, as writing the full versions of them will take some time. There is in fact for eaxmple a full, balanced binary tree, in the literature. That's on the list!

Regarding being unbalanced, one way to address this is to hash the key before inserting a new node.

> This looks like it was written by somone who heard "lock free", and went "cool, I'll write a library!"

That's a bit unfair. The library is eight years old now. It's not a flash in the pan.

> The web site is bad, the APIs are bad, the functions aren't very useful, the library isn't very portable, > etc.

It's actually as portable as it is possible for a lock-free library to be. Only a fairly few platforms provide atomic instrinsics. As far as GCC provides support, they are all suppoted, and I believe GCC supports all of them.

Re:Liblfds, a portable, license-free, lock-free data structu... by devishard on Tuesday May 31, 2016 @01:35PM (#11808289)
> No. All versions of the library can concurrently be included and linked against. The reason for this is so that any code which using an existing version of the library does not have to be modified at all - and so does not need to be revalidated - when a new version is published.

This is what having consistent interfaces is for. Keep your interface consistent, not your implementation.

This is also a strong argument for not releasing code and advertising it on HN if it's not mature.

> The add-onlys were thrown together in a week or so many months ago, just to get those classes of data strutures out there, as writing the full versions of them will take some time. There is in fact for eaxmple a full, balanced binary tree, in the literature. That's on the list!

Which begs the question why you included immature implementations in your library.

> That's a bit unfair. The library is eight years old now. It's not a flash in the pan.

Which doesn't negate the criticism in any way.

> It's actually as portable as it is possible for a lock-free library to be. Only a fairly few platforms provide atomic instrinsics. As far as GCC provides support, they are all suppoted, and I believe GCC supports all of them.

There are working examples (ConcurrencyKit) of lock-free data structures that target more architectures and more compilers, so "It's actually as portable as it is possible for a lock-free library to be." is provably false.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:47PM (#11808416)
> This is what having consistent interfaces is for. Keep > your interface consistent, not your implementation.

I have to disagree. If the underlying library used has changed, then the code which uses the library has to be revalidated. You cannot assume it simply continues to work - to do so is to fully rely on the library provider getting it right, introducing no bugs, or anything unexpected. This is not viable for serious projects.

The and the ONLY way in which existing code does not have to be revalidated is if it is completely and wholly unchanged.

> Which begs the question why you included immature implementations in your library.

There's nothing immature about them, and I don't know why you are saying there is. They were written about a year ago and writing them means also writing their test suite, which they pass.

The choices you disagree with in the library seem to be being taken to justify the charge of "code immaturity". Those choices may be right, or they may be wrong, and so could potentially be mistakes, but this is an entirely different matter to maturity.

> There are working examples (ConcurrencyKit) of lock-free data > structures that target more architectures and more compilers, so > "It's actually as portable as it is possible for a lock-free > library to be." is provably false.

I was thinking of processor support, rather than compiler support. Processor support is the main part of the work - all of the code has to be written with it in mind. Compiler support is much easier; it's just a matter of porting their atomic instrinsics, which basically means writing about a dozen straightfoward macros.

Re:Liblfds, a portable, license-free, lock-free data structu... by devishard on Tuesday May 31, 2016 @03:33PM (#11809459)
> I have to disagree. If the underlying library used has changed, then the code which uses the library has to be revalidated. You cannot assume it simply continues to work - to do so is to fully rely on the library provider getting it right, introducing no bugs, or anything unexpected. This is not viable for serious projects.

> The and the ONLY way in which existing code does not have to be revalidated is if it is completely and wholly unchanged.

And when I integrate a new release, how do I verify that you didn't accidentally change one of the older numbered versions of your code? I'm going to have to test either way when I integrate a new version of your code, so I might as well get any performance improvements or whatever you introduced into the implementation. Versioning your interface does not solve the problem you claim it does.

> There's nothing immature about them, and I don't know why you are saying there is. They were written about a year ago and writing them means also writing their test suite, which they pass.

I am saying they're immature because you said they were immature. You said, "The add-onlys were thrown together in a week or so many months ago, just to get those classes of data strutures out there, as writing the full versions of them will take some time."

> I was thinking of processor support, rather than compiler support.

I was also thinking of both processor support--you're the only one who mentioned any compilers. Given this supports only 2 processors and ConcurrencyKit supports 5, your claim that this is "actually as portable as it is possible for a lock-free library to be" is still provably wrong.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Wednesday June 01, 2016 @01:55AM (#11812306)
> And when I integrate a new release, how do I verify that > you didn't accidentally change one of the older numbered > versions of your code?

They're only released once. No release is changed after its release. Once it's out, it's out. The archive is never touched again.

When a release is made, the source code is exported, archived and uploaded to the library web-site. To accidentally change that code, I would have to accidentally repeat that manual process. It's the same with github - I actually use SVN at home, and I make a new repos per release and upload the code, once, to that repos. Github is a release only, write-once source control system, for me.

> I'm going to have to test either way when I integrate a new version of your code

Well, now I'm confused. If that's so, what's the problem? you keep using the old code, it's not changed, either the API or the library binary, so you don't have to test that; and for any new code, you can use the new release version. To the extent the APIs are unchanged, moving fully from one release to another is a matter of issuing a global search-and-replace for the string "liblfdsNNN" to "liblfdsMMM".

> Given this supports only 2 processors and ConcurrencyKit > supports 5

The library supports on Linux almost every processor GCC offers atomic instrincs for - ARM32, IA64, POWERPC32/64, SPARC32/64, MIPS32/64, x64 and x86. I'm pretty sure the library does not support Alpha, however. Of those platforms, I only have access to actual hardware for ARM32, MIPS32 and x64, so only those platforms actually have the test code compiled and run and being seen to pass.

On Windows, support is provided for ARM32, x86, x64 and IA64. Again, of these, I only have access to x64.

Re:Liblfds, a portable, license-free, lock-free data structu... by devishard on Wednesday June 01, 2016 @09:15PM (#11819657)
Ugh, your problem thinking runs too deep for me to power through.

1. Let's say I do things the way you suggest: I use different versions of your code simultaneously. 3 years in I have 5 versions of your code and I find a bug in my code in an area from the second version. Now I have to know 5 libraries to understand the code and I'm constantly getting tripped up by the subtle differences between versions 2 and 3.

2. So to fix this plan I finally persuade my boss to give me a week to address tech debt. With your search-and-replace plan, except I forget to do it in the library that Bob the contractor kept in a separate repo before we fired him. And then there's the separate problem of when I passed it into a function that took a function pointer and so the name is different and not find-and-replacable as being the same function. And then there's the place where Joe, who is a good programmer but kind of inexperienced, poor kid, he thought he'd simplify things by creating a macro that inserts the number, and this got past code review because I reviewed it right after a meeting with the client from hell. So now nothing is working after the find-replace, it takes us the entire week to figure out why, and we don't get to spend any of our tech debt time fixing the place where Bob the contractor decided it would be a good idea to "optimize" the graph generation functions.

For the record, I'm speaking from experience here. The way you wrote this code is an ideology I've worked with before and it's miserable to consume libraries written in this style. You can argue for the "benefits" all you want but I've eaten this dog food before and I'm not going to eat it again.

Re:Liblfds, a portable, license-free, lock-free data structu... by anarazel on Tuesday May 31, 2016 @02:43PM (#11808961)
> I was thinking of processor support, rather than compiler support. Processor support is the main part of the work - all of the code has to be written with it in mind. Compiler support is much easier; it's just a matter of porting their atomic instrinsics, which basically means writing about a dozen straightfoward macros.

There's actually rather few alive platforms that don't either have ll/sc or cas. The original i386, armv5, sparcv8 (leon IIRC added cas though), pa-risc come to mind (that's the postgres platforms for which fallback atomics support is used). Once you have CAS it's easy to provide fallback implementation for other atomics. It's also not all that hard to provide a "fallback" implementation for atomics, which guarantees atomicity using some locking mechanism.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @03:25PM (#11809380)
CAS or LL/SC is straightforward enough (although you have to be aware in your use of them of the differences between processors in terms of whether they lock cache lines, or have exclusive reservation granules, or per logical-core locks, etc, and there is one other minor complication to consider, the presence or absence of contigious double-word CAS or LL/SC), but memory ordering behaviour and support varies significantly across processors.

Intel in that regard are a pain, because they have a mandatory, built-in full memory barrier in their atomic operations. ARM does not, and I see the freelist on ARM running about 25% faster (relatively speaking) than Intel, because of it.

If you look at the first two bars (first is the new GCC atomic instrincs, second the old GCC sync intrinsics) in the one-core chart from these two gunplots, the first gnuplot being ARM32 and the second a Core i5,

http://liblfds.org/pages/images/liblfds710_freelist_push1_th...

http://liblfds.org/pages/images/liblfds710_freelist_push1_th...

You will see on Intel they're level, and on ARM, the atomic bar (the first bar) is about 25% higher.

The new GCC atomic instrincs only issue memory barrier when told to, whereas the old sync instrincs normally (e.g. on most platforms - the docs are a little nebulous) issue memory barriers.

The freelist doesn't need a memory barrier on pop, but on Intel, you get one anyway, and on ARM, with the sync instrincs, you get one anyway. The atomic instrinics also issue on Intel, because Intel forces it to happen, but they do not issue on ARM. I think this gives the 25% performance improvement.

Re:Liblfds, a portable, license-free, lock-free data structu... by Joky on Tuesday May 31, 2016 @01:58PM (#11808539)
> This is also a strong argument for not releasing code and advertising it on HN if it's not mature.

I'm not totally convinced about that, cf: https://en.wikipedia.org/wiki/Release_early,_release_often

Re:Liblfds, a portable, license-free, lock-free data structu... by erichdongubler on Tuesday May 31, 2016 @10:53AM (#11806841)
Uh...what about typedef?

typedef lfds710_freelist_element freelist_element;

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:47PM (#11808422)
I think typedefs are almost always harmful. The explanation is longish and not directly related to the library, so I'll leave it at that.

What I will say though is that the struct already has a type, so as far as I can tell, the benefit consists of not having to type the struct keyword?

Also, the typedef in particular you've given would make it impossible to concurrently include and link multiple versions of the library (which is the purpose of having the version in the public entity names).

Re:Liblfds, a portable, license-free, lock-free data structu... by cyphar on Tuesday May 31, 2016 @06:44PM (#11810863)
> Also, the typedef in particular you've given would make it impossible to concurrently include and link multiple versions of the library (which is the purpose of having the version in the public entity names).

Honest question: why do you think that's a useful usecase? I've never thought of using two versions of the same library, mainly due to fear of nasal demons.

Also, you could do symbol versioning like glibc does and then just keep the old code in the library for backwards compatibility.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Thursday June 02, 2016 @07:49AM (#11821749)
> Honest question: why do you think that's a useful usecase?

I worked for three years on software used by telcos. Carrier grade - they were rigourous about change control and validation, because bugs were totally unacceptable. For them, it would have been exactly what they needed.

Before that, I worked once for a while on a huge, unmaintainable code base. Awful code, basically one huge function, with a million lines of code =-) with that code, you should not risk ANY change. For them, it would have been essential.

In general, across all software I think software quality is not high. Developers do not test enough, and are too casual about change. I am taking an approach which I think is necessary, and it certainly deviates from the usual practise.

> Also, you could do symbol versioning like glibc

I'm not sure I properly understand - I need to read up properly on what this offers. However, it's not clear to me how it changes anything from the C code POV - in the C code, the user still needs to use the old versions of prototypes, to call the correct code in the library, so what do they get for symbol versioning? why not just link to the old binary? and it's important, because the old binary is completely unchanged and it is only by that, that revalidation is unnecessary and so does not have to be performed.

On a more practical level though, the library targets arbitrary compilers on bare metal platforms, and symbol versioning from what I read is rarely offered.

Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @12:37PM (#11807585)
Sure. Did he include the typedefs in his code?

Not that I can see (on a quick scan).

So the only way to use his library is to create your own wrapper functions. And update them every time he updates his library.

Thanks, but no thanks.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @01:25PM (#11808155)
Could you explain why this is the only way to use the library? why are typedefs essential for use?
Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Tuesday May 31, 2016 @07:19PM (#11811044)
Let's say that my application uses your library. Great! I code it, it works, and I release it for public consumption.

It get popular, so that Ubuntu packages the application and your library. Millions of people use it.

Now what happens when you release a new version of the library? All of the APIs with 710_foo become 720_foo. Which means that I have to rebuild my application to work with the library. I can't just link to the new version and get the bug fixes.

Even worse, Ubuntu has to rebuild all applications which depend on your library. Every time you release a new version.

This is why no one else puts version numbers into function / struct names. We rely on the C compiler to do type checks at compile time, and we rely on the linker to do symbol checks at run time.

If no one else puts version numbers into function names, it should be a strong hint that you shouldn't do that, either.

Similarly, 80-character symbols / macro names are just too complicated to use / remember. Pretty much no one else does this, either.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Tuesday May 31, 2016 @07:50PM (#11811175)
> I can't just link to the new version and get the bug fixes.

I think this isn't quite right, by omitting the down side - that you will be getting the not just the bug fixes, but new bugs. It's not all roses!

What has occurred between 710 and 720 is change. Ideally, hopefully, intended to be, positive change only. Bug fixes only. Improvements only. We all as software developers know there will in fact be new bugs introduced. Regression testings exists for that reason, and it is an imperfect method.

So I guess what I'm saying is this : nothing, NOTHING, should change for a given application, without revalidation. Swapping a library version under the hood is by that view not good practise. By and large of course this is type of change is absolutely normal practise, because most of the time it seems to work, and it less costly and time consuming.

(Really, it happens I think because humans are optimists and writing code is hard work and time consuming, so we involuntarily hope it's all fine and don't look hard for the bugs we've not found).

Re:Liblfds, a portable, license-free, lock-free data structu... by adekok on Wednesday June 01, 2016 @10:10AM (#11814457)
> What has occurred between 710 and 720 is change.

As you note, the changes should be minimal. i.e. the versions should be compatible. By changing the names, you are creating massive change, in order to bludgeon users of your library with the knowledge that there might be minor changes in it.

This is counter-productive.

> Swapping a library version under the hood is by that view not good practise.

And re-naming everything is?

Please, get over yourself. Your practice runs counter to 40 years of computer engineering. There are hundreds of thousands of Open Source projects which keep consistent names across minor releases.

Either they're all wrong, every one of the millions of developers, or you are wrong.

I think my review ends here. You're clearly in the camp of "I know better than everyone else".

Re:Liblfds, a portable, license-free, lock-free data structu... by cyphar on Tuesday May 31, 2016 @06:45PM (#11810870)
Having version numbers in struct and function names is what he's saying is a bad idea. Typedefs would be a way to achieve it, but you have to write a wrapper library to do that.

Why not just use symbol versioning like glibc does.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Wednesday June 01, 2016 @12:56AM (#11812131)
You have to remember what I'm looking to achive here is that a new version can be released, and used, while the existing codebase using the old versions is utterly unchanged. The APIs are unchanged, the library they link to is unchanged - totally, utterly, unchanged, not one single byte of difference.

I've not thought about (or really come across - I think I have seen it on Windows) symbol versioning, but from what I've understood (from a pretty terrible explanation online) it would mean the library ends up with a single library file, which gains new members as new releases of the library occur.

This still has the problem of imposing unvalidated change on the user - the library changes under him. What if I introduced new bugs?

Re:Liblfds, a portable, license-free, lock-free data structu... by cyphar on Wednesday June 01, 2016 @02:10AM (#11812356)
Well, the solution to that is to maintain branches of your code for each major version change and to only introduce breakages in major versions.

Because your current method means that your library will never delete old code. Not to mention that I don't know how deep your obsession with versioning goes -- if you slightly change a basic function shared by different library versions what will you do then? Or do you have n copies of the same code everywhere? What do you do if there's a bug in it? And how the hell do you expect a distribution to maintain the code, because you are copying large chunks of code in every version with no net benefit before you even start working on new versions.

If you did major versioning right, then only people who link against version X of your library would use the version X symbols. Glibc uses symbol versioning to extend that further and allow you to change glibc versions under users and they will still be using the old functions because you have symbol versions. Unless you're talking about "changing the library under them at compile time" in which case I think that it's a bad idea to do it that way (people just won't update their code).

Alternatively, you could allow users to set a macro before including your headers. This macro sets the version of the library they want to use. Then you don't require people to specify the version in every single symbol.

Re:Liblfds, a portable, license-free, lock-free data structu... by liblfds on Wednesday June 01, 2016 @07:31AM (#11813538)
> Well, the solution to that is to maintain branches of your code for each major version change and to only introduce breakages in major versions.

That is what is being done. Versioning is GCC style, "[major].[minor].[bugfix]". When APi breaking changes occur, a new major release is published, and is begins a new line of releases. When non-API breaking changes are made (or backported), a minor release occurs on all previous lines. Bugfix release can occur on previous lines.

So there's 6.0.0, then 6.1.0, and then a few months later 6.0.1 and 6.1.1 came out, with the same bug fix for both releases.

> Because your current method means that your library will never delete old code

Right. That is intentional. The idea is that when a new release is made, there is no change whatsoever in previous versions of the library which are in already in use.

> if you slightly change a basic function shared by different library versions what will you do then?

There are no shared functions, the library is stand-alone.

> If you did major versioning right

It would still require change in the binary being used by application, right? it would mean change, and that means revalidation - the only way it would not mean revalidation is if the application owner decided "what the hell, I'm sure he's got it right and there are no new bugs and it'll all be okay".

Anyway, you must alao remember the library targets bare metal platforms on arbitrary compilers. As it is for example the library is for example wholly independent of the standard library - it doens't even require a freestanding implementation. Symbol versioning is a luxury, high-end, rarely provided functionality. If the library relied on it, it would greatly limit the range of supported platforms.

> Alternatively, you could allow users to set a macro before including your headers. This macro sets the version of the library they want to use. Then you don't require people to specify the version in every single symbol.

That would defeat the very goal being aimed for. The idea is that existing code does not change when a new version of the library si released. The idea that when a new version is release, that all existing code should automatically use that new version, is to be avoided. You are trying to find ways in which it can happen, when that's the very thing which I'm trying to have not happen. That change should be controlled, should be consciously and deliberately chosen at a particular time, and to whatever extent is decided, by the maintainer of the application using the library.

Consider. Say an application is using the queue from 7.0.0 in say six different places. The code works. Why change it? but then there's a performance problem. One of those queues would really benefit from going faster. In this situation, why change all of the queues? those queues could be in completely different sub-components of the overall ssytem. When you update one of those queues, you have to revalidate that part of the system. You don't want to do it - you have limited developer resources, a to-do list the length of your arm and customers screaming for new features and other bugfixes.