Christian's Projects Mon, 26 Jun 2017 20:29:06 +0000 en-US hourly 1 Archived Mon, 26 Jun 2017 20:28:50 +0000 Christian This is an archived copy of a site I used between 2007 and 2013 to talk about a few of my projects.

]]> 0
Better diffs in gerrit code review Thu, 03 Oct 2013 06:25:54 +0000 Christian Code review is critical for quality code. There are many ways to do it and many tools to help with the process, such as gerrit, phabricator, reviewboard and github code review.

We use gerrit, which is nice. But there’s one annoying problem: when a change author rebases a change and pushes the rebased patch for review the patch set diff is nearly useless. That either makes the reviewer’s job much harder or leads to people avoiding rebases. Unfortunately the existing ticket about the issue is four years old.

I spent some time on fixing it: Our gerrit shows a hunk in the diff from A to B only if it isn’t in the diff between their parent commits, or if there is a conflict. This reliably hides unrelated changes, like those from rebases, while erring on the side of showing too much in case of conflicting edits or large hunks.

Unfortunately the patch isn’t ready for upstream: It doesn’t work with unified diff view or with gerrit’s new change screen (the new side-by-side view can’t have the left and right side be different without highlighting the change). Also it’s not configurable.

Feel free to contact me if you’re interested in the details or want to pick this up!

]]> 0
Improving REQ sockets in ZMQ 4 Wed, 25 Sep 2013 10:12:30 +0000 Christian I contributed two new socket options to libzmq 4.0: ZMQ_REQ_CORRELATE and ZMQ_REQ_RELAXED. They simplify usage of REQ sockets in situations where you would have had to reset the whole socket or switch to a DEALER socket with earlier versions. More specifically, you can now send a new request on a REQ socket when you’ve given up on getting a response for the preceding request.

ZMQ defines several socket types that can be used to implement different messaging patterns. REQ sockets provide the basic “send a request, wait for the response, send the next request, …” pattern and are used frequently. In practice things break though and you’re not guaranteed to actually get a response to a request. The old REQ sockets strictly enforce the send/recv/send/recv/… cycle and have to be completely reset when a timeout is detected.

This is unintuitive and people have commented on it in several times.

With ZMQ_REQ_RELAXED enabled, calling send() while waiting for a reply becomes valid. It will give up on the old request and send a new one.

When enabling ZMQ_REQ_RELAXED, always enable ZMQ_REQ_CORRELATE as well. It ensures the receive call only reports the reply to the latest request. Otherwise, if the old reply comes in after all, you might receive that and think it’s the reply for the later request.

The new option only changes the behavior for send() in a state where it would previously have returned an EFSM error. It is safe to enable it in nearly all cases. libzmq wants to make it as easy as possible for users to migrate to new versions, however, so it is not enabled by default.

Contributing to libzmq has been simple and rewarding. They use a interesting “merge first, review later” process which sounds problematic – but which seems to work for them and definitely made me feel welcome as a contributor.

]]> 0
Getting more out of the range-based for statement in C++11 Wed, 06 Mar 2013 15:14:10 +0000 Christian Among the most useful features added to C++11 is the range-based for statement. It is defined to be equivalent to the usual iterator-based loop from begin() to end() and makes standard iteration look way more appealing.

Keeping the noise out of a large fraction of iterator-based loops is great, but other common for loops are missing out! They have not received a convenient shorthand. Luckily, you can make some yourself by feeding the right containers to the range-based for statement.

For example, the regular counting loops

for (auto i = begin, e = end; i < e; ++i)
for (size_t i = 0, e = container.size(); i < e; ++i)

can be written as

for (const auto i : range(begin, end))
for (const auto i : indices(container))

if you define indices() and range() the right way.

Using the range-based version has no drawbacks: it is easier to read, quicker to write and compiles to equivalent assembly (calls to operator!= and operator++ get optimized away even at g++ -O1).

You can do a lot with the range-based for statement. What I have found useful so far is:

  • range(begin, end): for (auto i = begin, e = end; i != e; ++i)
  • range(end): same as range(0, end)
  • indices(container): same as range(container.size())
  • keys(container_of_pairs): shorthand for getting only value.first
  • values(container_of_pairs): shorthand for getting only value.second

The code is available on github under the Boost Software License. It has no external dependencies and using it should be as simple as putting the header file into your include path. It is also fairly minimal, implementing only what is needed to make it work. A lot could be added, like rbegin(), rend(), generic reverse(), correct iterators, …

The approach has its limits, and one of them is exposed when you implement something like enumerate():

for (auto e : enumerate(c)) {
    // e.index is the current index
    // e.value is the current value

For standard containers (as well as the keys() and values() ranges above) the type in the for statement controls whether you get a copy or a reference of what you are iterating over as well as whether it should be const or not:

for (const auto e : c) // e is a const copy
for (auto & e : c) // e is a mutable reference

That can only work as long as what you want to put into e is an lvalue (i.e. c.begin() is an output iterator). It breaks down for enumerate() which cannot return a reference without extra overhead.

That is why I decided to split enumerate() into two functions. enumerate_byref() always grabs ‘value’ by reference and enumerate_byval() makes a copy. Usage then becomes:

for (const auto e : enumerate_byref(container))
    e.value = true; // ok, modifies container!
for (auto e : enumerate_byval(container))
    e.value = true; // ok, changes copy

Which is far from the ideal syntax, but at least it is explicit about what is going on.

Thanks to my employer, CeleraOne GmbH, for permitting me to publish this.

]]> 3
Recent activity Thu, 03 Nov 2011 19:52:03 +0000 Christian Over the last year I’ve been focusing on Qt Creator and have done several posts on the Qt Labs blog:

]]> 0
Star Guard level editor Thu, 06 May 2010 17:22:28 +0000 Christian I spent the last few evenings working on a fun side project which is now complete: a level editor for Loren Schmidt’s Star Guard.

first level of Star Guard

the first level of Star Guard

the same scene in the editor

the same scene in the editor

A few things came together that caused me to make this level editor:

  • I was looking for an excuse to do something interesting with QML.
  • Star Guard is a great game and stores its levels in friendly, easily accessible XML files.
  • When I emailed Loren about the project, he allowed me to use some of the game’s artwork.

The whole thing was surprisingly easy to do, took a couple of days and amounted to less than 1200 lines of code – one half of it QML and the other C++.

If you don’t know about QML: It’s a fairly new part of the Qt framework, essentially an extension of JavaScript to build user interfaces declaratively – and great fun to work with. All the details can be found on its documentation page and if you want to get started, the Qt 4.7 beta1 packages have just been released.

The editor uses QML to describe every aspect of the user interface. It’s turned out to be very useful in the beginning of the project when the editor was still QML-only and the interface layout and behavior changed a lot. It also means that it’d be very easy to redo the user interface now – even for someone without any C++ knowledge. Also, not having to recompile after every step simply makes fiddling with the UI a lot more pleasant.

Of course there’s the disadvantage of not following the native look and feel. But no one ever complains that most games don’t use it – and I don’t think it’s necessary for a level editor to look just like your spreadsheet application either.

The C++ part deals with the backend work, like providing a model that holds the map, a QML item that paints it, and loading from and saving to files. I used the QML plugin mechanism to expose these to the UI code.

The editor is fully functional; I consider it done and will not continue working on it. If someone wants to improve it or base his own tile based level editor on it, feel free! I release the code under the Boost Software License 1.0.

Linux binary (64 bit) and source code (12 MB)
Windows binary and source code (10 MB)
source code only (.tar.bz2, 20 kB)
source code only (.zip, 30 kB)

]]> 0
LDC 0.9.2 released Fri, 19 Mar 2010 08:29:49 +0000 Christian A new version of LDC, the LLVM based compiler for the D programming language has been released. It is built with DMDFE version 1.057 and LLVM 2.6. The runtime library has been upgraded to Tango 0.99.9.

In addition to up-to-date dependencies, this release incorporates a wealth of fixes and improvements by Benjamin Kramer, Frits van Bommel, Kelly Wilson, Leandro Lucarella, Matti Niemenmaa, Moritz Warning, Robert Clipsham, Tomas Lindquist Olsen and me.

Linux x86-64 download

]]> 3
LDC 0.9.1 released Wed, 27 May 2009 18:25:54 +0000 Christian The release 0.9.1 of LDC, the LLVM based compiler for the D programming language, contains the following major improvements:

  • lots of bug fixes
  • x86-64 support is mature
  • inline asm improved (we now define D_Inline_Asm)
  • cross-compilation support
  • uses boehm-gc during compilation (x86-32 only)
  • D specific optimizations:
    • turn GC allocations to allocas if possible
    • simplify or remove certain calls to D runtime functions

The command line interface of LDC now has added options in line with other LLVM based tools. Please use the ldmd wrapper if you want a drop-in replacement for DMD.

Linux x86-32 download
Linux x86-64 download

Tomas Lindquist Olsen
Christian Kamm
Frits van Bommel
Kelly Wilson

]]> 3
LDC presentation video, Tango Conference 2008 Sat, 28 Feb 2009 15:27:07 +0000 Christian Peter Modzelewski, member of the illustrious team0xf and an organizer of the Tango Conference 2008, has posted the video and slides of the talk on LDC Tomas Lindquist Olsen and I gave in September.

The original summary was:

The new D1 compiler based on the strong fundament of LLVM, the DMD frontend and the Tango runtime is maturing rapidly. We’ll take a brief look at LLVM, report on LLVMDC’s status and discuss the future of the project.

Have fun watching the video and thanks again to the organizers for an excellent conference.

Here’s a short list of major changes since then:

  • Almost immediately after the lecture we renamed the compiler to LDC, which has worked out very well and should simplify the next presentation by avoiding tounge twisting sentences that contain LLVM, LLVMDC, DMD and GDC in close proximity.
  • We released LDC 0.9 for x86-32 Linux in early January.
  • Support for x86-64 Linux has improved significantly due to contributions by Kelly Wilson and Frits van Bommel. Our platform support entry for it now reads: “no big open issues,
    dstress results pretty much the same as x86-32 Linux” – The next release will very likely include x86-64 Linux binaries!
  • LDC switched to LLVM 2.5.
  • ABI conformance work continued: The D calling convention is fully implemented and naked functions are supported.
  • A lot of tickets have been closed; this includes a large amount of bugfixes, but also higher level issues like allowing template functions to be inlined and basic cross compilation.
]]> 0
LDC 0.9 released Thu, 08 Jan 2009 23:21:47 +0000 Christian The first version of LDC, the LLVM based compiler for version one of the D programming language has been released for x86-32 Linux. Get it here!

We had already announced this release during the Tango conference in September (we hope the video of our presentation will be out soon), but – as was to be expected – it took a bit longer than planned.

LDC ships with a precompiled Tango rev 4237 and passes all except two of Tango’s unittests (io.digest.Md2 and text.locale.Posix fail). DStress results also look favorable and the GtkD demos work. The chances are good that your code will work with it too!

There are several known issues, the most severe being:

If you encounter a bug, please check our bug tracker and create a new ticket if the issue isn’t listed yet. Maybe you are feeling adventurous and want to try fixing it yourself; in that case take a look at our getting started guide.

LDC could support other platforms. Furthest along so far are

  • x86-64 Linux: needs people to start fixing smaller bugs, exception bug (LLVM issue)
  • x86-32 Mac: small runtime issues, needs tests
  • x86-32 Windows: exceptions not supported (LLVM issue)

but support for these platforms won’t improve on its own! Several friendly people have offered their help – we need more of those!

For those with big CTFE memory needs, we have an experimental version of LDC available which has the compile-time garbage collector enabled. In the future, we’re going to experiment with a forward reference hack, but right now it still introduces too many regressions.

Feedback and questions are appreciated and should go to the mailing list. Alternatively, we’re often seen in #ldc on FreeNode.

Tomas Lindquist Olsen, Christian Kamm

]]> 11