Archive for March, 2010
Removed some distribution-specific patches
By chys on March 24th, 2010With all due respect to Gentoo developers, I really hate the patches they made for coreutils, especially the one to have uname parse /proc/cpuinfo.
The result is that uname -a displays more info, specifically the mode of the CPU, on Gentoo than other Linux distributions. Generally this is not a bad thing. But I do have concerns:
(1) In my view the utility uname should remain a simple wrapper of the homonym system call. If CPU/vendor info really needs to be returned by uname, it is better to add it to kernel. This is also part of the reason why upstream rejected this patch.
(2) If I am used to finding CPU info from uname, I will likely forget the more orthodox method (cat /proc/cpuinfo). A job interviewer may not be that patient to listen to my explanation about the patch.
&errno as thread identifier
By chys on March 13th, 2010
Thread identifiers may have different types in different systems – pthread_t under POSIX; uintptr_t or HANDLE under Windows. They are usually integers or pointers, but POSIX actually allows structures though not usually found. This leads to a little difficulty in portability.
A trick, used by OpenSSL (if not overridden by calling CRYPTO_set_id_callback), is to use &errno as the thread identifier.
Per C standard, errno must be a modifiable lvalue, and thus we can safely take its address – &errno. And under any practically usable thread implementation, errno must be thread-local, which means &errno is different in different threads.
Note: It seems OpenSSL defaults to &errno only since 0.9.8m. Earlier versions always require the user to call CRYPTO_set_id_callback.
Tags: multithread, portability
Acquire and Release Semantics
By chys on March 2nd, 2010The concept of acquire and release semantics is important for multi-threaded programs that run on more than one physical core or processor. MSDN has a clear and concise explanation of then.
Consider the following code example:
a++;
b++;
c++;From another processor’s point of view, the preceding operations can appear to occur in any order. For example, the other processor might see the increment of
bbefore the increment ofa.…
[T]he
InterlockedIncrementAcquireroutine uses acquire semantics to increment a variable. If you rewrote the preceding code example as follows:
InterlockedIncrementAcquire(&a);
b++;
c++;other processors would always see the increment of
abefore the increments ofbandc.Likewise, the
InterlockedIncrementReleaseroutine uses release semantics to increment a variable. If you rewrote the code example once again, as follows:
a++;
b++;
InterlockedIncrementRelease(&c);other processors would always see the increments of
aandbbefore the increment ofc.
The operation of acquiring a lock must have acquire semantics; and the operation of releasing a lock must have release semantics. This is probably where they get their names.
Tags: dev, multithread
