Otherwise, nice writeup -- I'm trying to fuzz Lwan right now using preeny.
432 karma · joined March 20, 2012
Otherwise, nice writeup -- I'm trying to fuzz Lwan right now using preeny.
I'm genuinely curious, because it's the first time I hear someone saying it's poorly written to the point that it's used as an example of how not to write in C. In fact, I often hear the opposite from people that are way more skilled in C than I am.
I care a lot about code quality, both performance- and readability-wise; so much so that I regularly check the code with static analyzers, ubsan, build the project using two different compilers with a bunch of warnings turned on, and, of course, I'm always refactoring stuff so it's more readable.
If you could help me understand better what you mean specifically about "it violates C standards", I can keep improving the project.
In time, "gratuitously using unportable APIs" isn't really a fact. There are some uses here and there of unportable APIs (such as epoll, maybe a call or two to some pthread_*_np() function), but I believe it's better to support something I know inside out than a platform I have no familiarity with. Maybe "gratuitously" could be removed from that affirmation. Also, I follow the OpenSSH idea of portability, which seems to work pretty well for them: http://www.openbsd.org/papers/portability.ps
In my defense, the first paragraph states that I never get things right the first time. :)
From 1984 (during which time we were under a military dictatorship) to 1991, we were under a market reserve. Because of this, the computers we had were either cloned from smuggled devices, or, funnily enough, devices imported legally with the intention of being reverse engineered.
Reverse engineering was not only legal, it was encouraged by the reserve. Due to government incentives, even companies that had nothing to do with computers ended up building them.
Cloned computers ranged from ZX81 and Apple II+, to ones with more elaborate circuitry, such as the Mac 512 (this one has a lot of interesting stories -- albeit somewhat sad, in a sense --, some even involves orange juice embargo from the US government).
The idea behind the reserve was to create a computer hardware industry in Brazil, but this ended up never happening the way it was supposed to happen.
Although locally-developed peripherals were made, there were very few computers that were actually designed in Brazil that ended up having a significant portion of the market. Clones thrived, mostly. Local semiconductor companies failed to produce quality components, but those were used anyway. Some companies managed to import (with special permission from the government) processors and other components we were never able to properly manufacture.
In a move that's both obvious and surprising, the focus moved to software when the reserve was finally lifted.
Obvious because, although we had many skilled people that managed to reverse engineer circuits (including ASICs, as was the case with the Unitron Mac), and build new ones, often improving them (either making them faster, more reliable, or just cheaper), we still depended on foreign technology to build our computers. The whole idea of the reserve was to reduce that dependency.
Surprising because, during the reserve, software was most often hacked versions of foreign stuff. Although some important bits and pieces (such as compilers, operating systems, CAD programs, word processing and a bunch of other stuff) ended up being made locally, unless you're a collector, you're not going to find the remnants of these bits.
Regarding rawmemchr(): both are pretty well optimized. Both are implemented in glibc using the same technique (reading a byte at a time until it is aligned, then moving to multibyte reads). strlen() might be faster, yes, considering that the implementation can hardcode some magic numbers. In other words: some micro benchmarks might help decide here.
Regarding __linux__ vs. __GLIBC__: Lwan works with some alternative libcs (such as uClibc), so relying on __GLIBC__ being defined for things like this doesn't seem like a good idea. In any case, since Lwan isn't portable anyway, one can just assume it is always running on Linux and get rid of these #ifdefs.
OTOH, the beefiest machine I have access to test it is a 4 year old laptop, not a 24-core Xeon.
And, yes, that's pretty much it, although "rebimboca da parafuseta" is less obscure than "reticulation of the splines" (if you're Brazilian, anyway).
It is used to denote a fictitious part, which name or function are unknown, of a car engine or any other machine. It was coined in the 70s TV show, and later used in some ads aired during the same period; since then, it's an expression used for humorous effect. It's not very common these days but is unlikely you'll meet someone down here that never heard it.
In addition to them, I also use Coverity (they offer free licenses for open source projects) and Coccinelle (although it's a tool to refactor/create semantic patches, can be also used to find defects if you know what you're looking for -- useful if you fix one bug and you're wondering if there are more like it lurking).
Having different opinions about your codebase is often good as the approach in finding defects is usually different between them. For instance, stuff by the PVS people seem pretty good to find copy/paste mistakes, which I've rarely found with other tools.
I was able to spot 13 of these errors -- although the page only counted that as 10 as it's very picky of which token constitutes the error.
PVS Studio (and CppCat) are great tools. I can't unfortunately use them as I don't write stuff for Windows.
The Reddit thread for Nope.c is generating a lot of constructive criticism. It ranges from stylistic issues to security issues to architectures issues. Nope's author might learn a lot of stuff and have a lot of fun -- I sure did when writing my own.
(In time, my project's web page is at http://lwan.ws)
It is still online at http://labs.hardinfo.org/pb/.
To play, turn it on (green button), then press "Memória Tons" (third button from the right in the last row).
Being able to continue inspecting the model in the same position it was before loading another version would be nice as well.
Granted this is also being tested on localhost with static content (no disk I/O) -- but shows that event-driven servers are not that novel or difficult to write: my code weighs around 1700 LOC of (might I say) readable C.
Static file serving is also fast (using sendfile(), etc), but needs an overhaul to achieve usable concurrency. Currently there's a ~4x performance drop while serving files, but I'm working on this.
(The sources are at http://github.com/lpereira/lwan by the way.)