WTC Memorial

You’ve probably already seen this picture before. Apparently there’s a controversy brewing about a memorial sculpture based on it. You see, the three guys in the picture are all white (I know, it’s hard to tell) but the sculpture is multi-racial. Some people think this is political correctness gone overboard, and a slight to the three individuals involved. Regular readers here know what I think of political correctness, but I think the change is appropriate in this case and I’ll try to explain why.

You see, the memorial isn’t about those three guys. What they did was moving, inspirational, generally cool…but not heroic. The real heroes were trapped a hundred feet lower down, and it’s them the memorial is intended to honor. The memorial is about “everyfireman” and that abstract person has many faces. I don’t think the memorial should specifically resemble any particular people, not even these three. Those three men gave us a powerful symbol by which to remember and honor their fallen fellows, and for that they deserve our gratitude, but symbols don’t represent the people who draw them. This symbol represents other men and women and it should represent those other men and women in all of their diversity.

Maybe the real quibble is that the memorial doesn’t include any women. I don’t know for sure whether there were any female police or firefighters trapped in WTC, but it does seem very likely and at any rate there were plenty of female civilians. They deserve a share of the memorial too.

Canned Platypus

I actually bought one of the “Canned Platypus” stuffed animals from which I stole the picture at left. The little guy inside is actually very cute; maybe I’ll post a picture of him (and the rest of my platypus collection) some time.

BTW, in case anybody’s wondering about the name “Canned Platypus”, a few words of explanation. Basically I’m the platypus, and the stuff on this site is a sort of “canned” (preserved) version of the continual stream of odd thoughts you’d be exposed to if you actually knew me in real life, so the site is a canned version of me. Maybe you’d already figured that out. Oh well.

OOM Killer Killer

This was part of a Slashdot discussion that started with an interview of Rik van Riel, who designed one of Linux’s two virtual-memory systems and is an all-around great guy. I have a lot of respect for Rik’s work, but I couldn’t resist the opportunity to talk about one of his few missteps. The original context for this article is here.

Rik is an extremely bright (and likeable) guy, but his adherence to the OOM killer concept is disappointing. I’ve seen a lot of dumb ideas gain currency in the computing community or some part of it; OOM killer is the dumbest. If your process was allowed to exist in the first place, it should not be killed by the VM system. The worst that should happen is that it gets suspended with all of its pages taken away. If that doesn’t free up any memory then neither would killing it (modulo some metadata – read on). If there are other processes waiting for the one that’s suspended, then eventually they’ll go to sleep, their pages will be released, and the suspended process will wake up – which won’t happen if you killed it. There are only two differences between the two approaches:

  • Suspension does not take irrevocable action; the suspended process can still be restarted.
  • Suspension bears the cost of retaining the metadata for the suspended process so it can be restarted.

The usual whine from OOM-killer advocates is that you can still get into a situation where all of that retained metadata clogs up the system and essential system functions can’t allocate pages. However, that’s preventable too. All you need to do is preallocate a special pool of memory that’s only available for use by those essential system processes – either individually or collectively. The size of that pool and the exact details of how it gets allocated (e.g. which processes are considered essential) could be treated as site-specific tuning parameters. The same idea can then be further generalized to allow definition of multiple private pools, creating a semi-hard barrier between different sets of tasks running on the system (if you want one; the default pool is still there otherwise). This actually fits in very nicely with other things like processor affinity and NUMA-friendly VM, which I know because I once worked on a kernel that had all of these features.

In short, there’s no need for the OOM killer. Plenty of systems, many of which handle extreme VM load much better than Linux, have been implemented without such a crock. Rik contends that a lot of people make suggestions without actually understanding the problem, and he’s right, but I also submit that sometimes he also rejects suggestions from people who do know what they’re talking about. This row has been hoed before, and Rik’s smart enough that he should know to avoid the NIH syndrome that afflicts so many of the other Linux kernel heavyweights.

Special People

I was thinking the other day about how so many otherwise intelligent-seeming young people seem enamored of certain “individualist” philosophies such as those of Nietzsche or Rand. My conclusion, which I’m sure is not original but which I’ll share anyway, is that they never grew out of what I call the “Arthur/Anastasia Complex”. This the common childhood daydream about finding out that you’re really “someone special” and you’re only among boring old normal kids because the time is not yet right to reveal your true identity. The daydream about discovering some sort of latent superpowers (like Clark Kent or the Tomorrow People) is very similar. These special people in the daydreams correspond, of course, to the special people in the relevant philosophies – people so different from the rest of us that they deserve to live by special rules. 99% of the Rand freaks infesting every college campus in the US, for example, believe that they’re in that very special creative 1% that includes Roark, Taggart and Galt. Not bloody likely, if you ask me, but it’s easy to see how someone who was a high-school valedictorian last year might not have figured out yet how they truly measure up in the real world. It’s equally easy to see how such philosophies would have much greater appeal for people who believe they’re in that special 1% than for people who realize they’re in the other 99.

Here’s the all-important clue for the “special people” still reading this: you’re not fundamentally different from the rest of humanity. Sure, everyone’s different in some ways from the people around them, but not in any essential sort of way that justifies treating them as demi-gods (or like nobles used to be treated). Even movie stars, professional athletes, and world-class scientists are, at a certain level, just like you and me. I’ve met a few. Humanity is not divided into inferior and superior subspecies; we are all humans first and most, everything else second and less. If you really, truly feel that you have good reason to deny your essential similarity to regular humanity of humanity, and that you are therefore exempt from the social contract that binds everyone else, then you might be pleased to know that there’s a concise scientific term describing you. You’re a sociopath.

Right to Anonymity

This all started with a thread on Slashdot, but this particular article is an attempt to encapsulate in a shorter, more coherent form why I’m skeptical about the notion of a right to anonymity.

When people talk about rights, they usually mean inalienable, permanent, absolute kinds of rights…rights that the government must respect and try to preserve even when it’s inconvenient or distasteful to do so. Free speech, freedom of assembly, freedom from unreasonable search and seizure, are all in this category. Note that the government does in fact limit the exercise of these rights in certain cases. For example, there’s the classic public-endangerment example of shouting “Fire!” in a crowded theater, and I think it’s right for the government to limit that kind of free speech. In other cases, such as hate-speech laws or requiring permits for public gatherings, I think the government is wrong. Nonetheless, in principle the government is required to respect these rights even in the relatively rare cases when they cannot be fully preserved.

Is anonymity such a right? The classic affirmative argument among Americans (apologies to those who live elsewhere) is based on the Ninth Amendment to the Constitution, which I quote:

The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.

My contention is that this still does not allow people to claim arbitrary rights, and I like to use the example of a right to urinate in public places. Does the government have the power to limit that right? Of course they do, in the interests of public health. The Ninth Amendment is really pretty weak. It says that other rights (than those enumerated) might exist, and that broadly accepted rights can be given legal consideration without needing to be written into the Constitution, but it doesn’t mean that Joe Schmoe can just make up a right and expect such consideration. The right to privacy is an example of something that does meet this “broadly accepted” standard, but the right to remain anonymous does not. There’s no community consensus or legal precedent to support a right to anonymity like there is for the right to privacy.

The other argument I’ve seen for a right to anonymity is that it’s a form of free speech. Proponents of this view often refer to the 1995 case McIntyre vs. Ohio, which I quote:

Anonymous pamphlets, leaflets, brochures and even books have played an important role in the progress of mankind. Great works of literature have frequently been produced by authors writing under assumed names. Despite readers’ curiosity and the public’s interest in identifying the creator of a work of art, an author generally is free to decide whether or not to disclose her true identity. The decision in favor of anonymity may be motivated by fear of economic or official retaliation, by concern about social ostracism, or merely by a desire to preserve as much of one’s privacy as possible. Whatever the motivation may be, at least in the field of literary endeavor, the interest in having anonymous works enter the marketplace of ideas unquestionably outweighs any public interest in requiring disclosure as a condition of entry. Accordingly, an author’s decision to remain anonymous, like other decisions concerning omissions or additions to the content of a publication, is an aspect of the freedom of speech protected by the First Amendment.

I think the last sentence of the above is often misunderstood. If you read the whole paragraph, the author(s) clearly intended to say that anonymity is supportive of free speech, and thus worthy of protection, not that it’s important and subject to protection in and of itself. It’s a tool, like equal-time provisions or Miranda rules, to support and preserve another right, but it’s not a right itself.

I agree that when anonymity which is used to allow or promote protected free speech anonymity should be preserved. Political dissenters or whistle-blowers need and deserve to have access to anonymity as a means to preserve their freedom of speech. However, anonymity is often used to allow non-protected forms of speech such as libel or breaches of confidentiality. No social, legal or moral purpose is served by treating anonymity as a “first order” right in such cases. By treating anonymity as an enabler of rights rather than a right in itself, we can easily say that if the speech itself is not protected then neither is the anonymity of the speaker. This allows us to deal with anonymous slanderers or confidentiality-contract violators, without abandoning our principles or the aforementioned dissenters and whistle-blowers.

There are, of course, some “secondary issues” to work out. For example, it can be hard to distinguish between whistle-blowing and libel, which creates problematic situations such as someone being identified and brought to court only to find that they were in the right after all. Requiring that the existence of a crime must be proven before the identity of an anonymous author can be demanded (the current law) doesn’t quite work because legally necessary questions of diligence and provenance of information often cannot be answered until after identity is known. There’s also the problem that at least the people in the courtroom – including the plaintiff – will become privy to the no-longer-anonymous author’s identity. Indeed, plaintiffs might file suit just for this reason even if they know they’ll lose, and this does erode the protection afforded by anonymity. All I can say is: tough. There are already laws protecting whistle-blowers and others, and if we need more we can write them. Treating anonymity as an absolute inalienable right is unacceptable and unsupportable; by treating it as a “rights enabler” instead we allow ourselves to approach issues involving it with flexibility and common sense.

Space, the Final Frontier

Looks like I ran out of disk space. In addition to problems here on the website, this might have caused email to bounce, etc. If this affected you, my apologies.

Random Questions

Two random questions today:

  • Do turtles make sounds? What kind?
  • How do you measure an animal’s visual acuity? I see a lot of claims about how this animal has sharp eyesight, and this other animal sees poorly, but how do they know? I don’t think they make the animals read eyecharts. ;-)

Server Framework

I’ve been thinking about the same old event-based vs. multithreading issues that have been discussed here before (articles 1, 2, and 3) and come up with a proposal for a new structure that I hope will represent the “best of both worlds”. It’s on a separate page because it has big-ass section headers and generally looks ugly on the front page.

Server Framework

Introduction

Here are the requirements I’m trying to reconcile:

  1. I have requests coming from multiple sources, some of which are network sockets so I can take advantage of poll/select and some of which involve blocking calls with no asynchronous/non-blocking equivalents. Because of the latter, I can not use a pure “monothreaded” model.
  2. The program must be able to get more than one processor’s worth of work done on a multiprocessor machine, so – again – a purely single-threaded approach would be unacceptable.
  3. Context switches (the biggest performance-killer in a multithreaded program) must be kept to a minimum. One big part of that is keeping the number of threads to a minimum by taking advantage of poll/select where possible, but there are other parts too.

My basic approach, based on these requirements, is as follows.

Registering Request Sources

For request sources that involve reading requests from sockets (or other file descriptors), a RequestSource object is used, which has the following attributes and methods:

  • The file descriptor.
  • A ReadRequest method, which is invoked whenever the file descriptor becomes ready. This method must be non-blocking, and return a boolean value to indicate whether a complete request has been received yet. If not, the partial request should be stored somewhere on the RequestSource for later (obviously, extra work is necessary when implementing this in C as I must, but idiom translations are left as an exercise for the reader).
  • A HandleRequest method to be invoked when the ReadRequest method indicates that a complete request is present.

The RequestSource object is then registered to be handled by the framework’s main poll/request loop. This registration also involves a priority, so that requests received on higher-priority sockets can be handled preferentially and requests received on equal-priority sockets can be handled fairly to avoid starvation.

For request sources that involve blocking operations just to read the request, a different approach is needed. In this case, all that gets registered with the framework is a function to read and handle a single request, plus a context pointer passed to that function. The framework is then responsible for calling that function as needed, whenever concurrency limits (described below) allow and there is not already a thread waiting to receive that type of request.

Handling Requests

Once a request has been received, it can be handled pretty much as it would be in any other multi-threaded application, without any special tricks involved. As long as processing the request doesn’t involve any operations that block (such as by issuing an I/O operation, but not counting contention for locks on data structures), the handler function can just do its business and return. At that point the current thread will either continue the main poll/select loop or invoke the handler function for the just-completed request typed; either way, we’re ready to start on the next request without any context switches occurring.

If a request handler decides that it does need to block, e.g. for I/O, it must call an AboutToBlock function. This tells the framework to invoke either the main poll/select loop or the current blocking request handler in a new thread; when the current thread returns from handling its request, it will be “recycled” or placed on a spare-thread list as appropriate.

Concurrency Control

One key to maximizing performance on a multiprocessor system is keeping exactly as many CPU-oriented activities scheduled as there are processors. If you schedule fewer, you’re wasting processors; if you schedule more, you’re likely to cause wasteful context switches. To deal with this, the framework constantly keeps track at all times of how many of its threads are actually running, and refrains from dispatching new threads when that number already equals or exceeds the number of available processors. This is mostly done using a simple counting semaphore as a resource counter. When the poll/select loop is about to call a HandleRequest function, it first acquires the semaphore and hence reserves a CPU; when HandleRequest finishes, the semaphore and CPU are released again. Similarly, AboutToBlock releases and reacquires the semaphore to keep the count of truly active threads current. Blocking request-reader functions must explicitly call the GetBusy framework function between reading and handling a request, to convey the same thread-activity information.

It might seem that the concurrency control can be done separately from the request read/dispatch framework. However, the framework needs to be capable of actively spawning new threads to service the poll/select loop or invoke blocking request-reader functions as previously dispatched handlers call AboutToBlock or BecomeBusy. If done naively, this could lead to significant waste. For example, consider the following sequence that could occur when concurrency control is done separately:

  1. N-1 out of N CPU resources are already assigned to request-handler threads.
  2. The poll/select code, running in thread X, finishes reading a request and prepares to call a HandleRequest method. Part of this preparation involves assigning another thread Y (perhaps out of a spare-thread pool) to handle poll/select requests, because one such thread must exist at all times to achieve any level of parallelism.
  3. X enters the HandleRequest method and acquires the last CPU resource via the semaphore. We now have N+1 threads including Y.
  4. Y finds a socket ready for reading, and competes with the N existing request-handler threads as it reads the new request.
  5. Y finishes reading the request, spawns yet another new thread Z to handle poll/select, enters HandleRequest, and blocks on the CPU-resource semaphore. The sequence could repeat for as many new poll/request threads as there are outstanding requests.
  6. One of the request-handler threads finishes and returns to the framework, only to find there’s nothing to do, so it either puts itself on a spare-thread list or exits.

Obviously, this scenario potentially involves many unnecessary thread creations and context switches. To avoid these problems, the framework actively makes use of concurrency information to decide whether it should spawn or dispatch new request-reader threads. In the most common case, the framework will forego spawning a new thread to read requests (which couldn’t be handled anyway) when the concurrency limit is reached, and returning request-handler threads will enter the poll/select loop or invoke a blocking request reader as appropriate.

Myth of Male Power

In lieu of original content, here’s something I wrote for kuro5hin about Warren Farrell’s The Myth of Male Power.

original article

I don’t remember the exact wording, because I read the book quite a while ago, but it’s basically something like this:

Nowhere else in history has the group that had longer lifespans, spent most of the money, and cast most of the votes been able to portray themselves as oppressed.

Farrell does a pretty good job of explaining the facts and statistics behind the above. Wmen do live longer than men; everybody knows that. It seems that some people would like to believe it’s because of female genetic superiority, but Farrell gives some statistics that cast serious doubt on such a theory. For example, he shows that heart disease (a, if not the, leading killer) afflict men disproportionately in the general population, but not if you carefully select groups of men and women for equivalency (family medical histories, occupations, income levels, and so on). Hmmm. In other words, more men die of heart disease because more men are exposed to conditions – i.e. stress – that lead to heart disease. By the time Farrell is done, it’s hard not to see this as a form of discrimination – women complain constantly about the stress in their lives, but the people who are killed by stress are usually men, and the fact that it’s politically incorrect for them to complain only adds more stress.

To pick another example, Farrell asks the very reasonable question of whether economic power is best represented by who earns money, or who spends it. Then he points to studies showing that women are responsible for the majority of domestic spending and economic decision-making. Oh, how oppressed women must be, Farrell says, when they earn less but spend more. He also poses a similar question about political power being vested in who serves vs. who votes.

There’s lots more. I’m trying to give a feel for what Farrell’s getting at and how he goes about making his points, but I have neither the literary skill nor the statistical arsenal that Farrell demonstrates in the book itself. Even if you disagree with his basic premise – perhaps especially then – it’s a book worth reading and understanding.