Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Libabc: Best practices for library writers from Lennart Poettering (0pointer.de)
42 points by cpeterso on Nov 3, 2011 | hide | past | favorite | 15 comments


anyone knows what motivated this: 'Don't write your own LISP interpreter and do not include it in your library.' ? thanks !


I suspect that it's a jab at ALSA which, for reasons unknown, ships with a full LISP interpreter[1] that it doesn't actually use...

Lennart Poetering is the author of PulseAudio. He probably has a bone or two to pick with ALSA.

[1] http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/precise/...


Whoa. That file contained the absolutely most naive string hash function I've ever seen:

    static int get_string_hash(const char *s)
    {
	int val = 0;

	if (s == NULL)
	    return val;

        while (*s)
	    val += *s++;

        return val & ALISP_OBJ_PAIR_HASH_MASK;
    }
It seems to cleverly avoid everything that's supposed to go into a string hash function, and makes me quite wary of the rest of the file's code quality. I stopped reading after checking that this function is indeed used (it is).

Also, the file itself was last modified on 2011-10-18, which seems to be pretty recent for something that's not used. Perhaps they're gearing up to start using it, and if that's going to involve any kind of even remotely performance-sensitive, I hope they replace the hash function first. :)


I'm curios, what is (under normal circumstances) supposed to go into a string hash function?

The biggest problem I see with this hash function is that it will produce very many collisions (because most common strings will probably produce only small numbers).

I have seen other very simple string hash functions which just take the 4 first bytes (or 4 last or some sort of other pattern) of the string and use them (interpreted as 32bit integer) as the hash.


I'm no expert in hash function design, but one thing that seems bad is that it will generate colliding hashes for all permutations of the same characters. Also, it will not "spread" the bits very well, due to just using addition. Most "real" hash functions tend to multiply the hash by each new character, thus causing it to "churn" more.


That's probably still better than the string hash in really early versions of Java, which only looked at a relatively small number of characters at the start of the string.


Greenspun's Tenth Rule of Programming

https://en.wikipedia.org/wiki/Greenspun%27s_Tenth_Rule


This is generally pretty awesome, thanks to Lennart and co. for putting this together.

> avoid locking and mutexes, they are very unlikely to work correctly, and incredibly hard to get right.

For serious? Everything in this README is golden advice except for this. Locking can be reasoned about, it's not "incredibly hard", and it's often necessary.


In the context of a shared library, this might not be so bad advice. You don't know how you are going to be used (either by the program tat loads you or by another library loaded by the program).

In such an environment, it's much easier to accidentally create deadlocks that you know nothing about, because you can't predict the invocation pattern of all the libraries and applications potentially linking to you.


I see what you're saying, but that still doesn't mean it's so difficult to get right, it just means you have to think about lock ordering (or just avoid taking > 1 lock at the same time).


I believe that follows from what he said above:

> zero global state -- Make your library threads-aware, but not thread-safe!

His point is that even if you have global state and try to protect that using locks, there may be code unknown to your application that works on the same global variables and you may not be able to predict the order of locking.

He specifically mentions the example of NSS (name service switch), which allows you to optionally create and plug in shared libraries that will be invoked without the application or the core C library being modified. So for example, an admin could change /etc/nsswitch.conf to set up LDAP user logins but your application could still use getpwnam(3) without caring about whether the pw retrieved is local, NIS, or LDAP.


You shouldn't be using _ names for the header guards. ANSI C reserves _ names for implementation library (libc and friend) use and __ names for internal compiler use.


We use cmake to build our software and libraries and I agree with he author, it's much more viable than autotools, would it be only for visual studio support.


No, you do not agree with the OP. (You probably mistook one of the comments for the OP.)

From the README file endorsed by the OP:

--start quote--

use autotools

- every custom config/makefile build system is worse for everybody than autotools is

- we are all used to autotools, it works, nobody cares

- it's only two simple files to edit and include in git, which are well understood by many many people, not just you. . . .

- And really, anything but autotools is not an option. Just get over it. Everything else is crack, and it will come back to you if you choose anything else, sooner or later. Why? think cross compilation, installation/uninstallation, build root integration, separate object trees, standard adherence, tarball handling, make distcheck, portability between distros, ...


You are correct, then my comment is "the OP is wrong, CMake is not only an alternative to autotools, it's also better in every aspect as a commenter explained".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: