Hi there! My name is Adrian Kummerländer and I am a software developer currently studying mathematics in Karlsruhe. On these pages you will find blog articles covering amongst other topics some of my experiences in software development, open source and related tinkerings as well as repositories and information on some of my personal projects. If you have any comments or questions feel free to reach out. I hope you will find something here worth your time.

» Fun with compute shaders and fluid dynamics

December 22, 2018 | Adrian Kummerländer

As I previously alluded to, computational fluid dynamics is a current subject of interest of mine both academically1 and recreationally2. Where on the academic side the focus obviously lies on theoretical strictness and simulations are only useful as far as their error can be judged and bounded, I very much like to take a more hand wavy approach during my freetime and just fool around. This works together nicely with my interest in GPU based computation which is to be the topic of this article.

» On NixOS, GPU programming and other assorted topics

June 23, 2018 | Adrian Kummerländer

So I recently acquired a reasonably priced second-hand CAD workstation computer featuring a Xeon CPU, plenty of RAM as well as a nice Nvidia K2200 GPU with 4 GiB of memory and 640 cores as the heart of the matter. The plan was that this would enable me to realize my long hedged plans of diving into GPU programming - specifically using compute shaders to implement mathematical simulation type stuff. True to my previously described inclination to procrastinate interesting projects by delving into other interesting topics my first step to realizing this plan was of course acquainting myself with a new Linux distribution: NixOS.

» Notes on BlackBerry OS 10 development in 2017

October 3, 2017 | Adrian Kummerländer

I recently broke my seven-year streak of only using smartphones in the tradition of Nokia’s fabled N900. The reason for this change was the growing age of my Jolla phone combined with my continued desire for a working physical keyboard1. In today’s market overflowing with faceless, exchangeable, uninspired and uniform touch-only devices this left me no choice but to opt for the last true BlackBerry: The Passport.

» Describe custom gitolite and cgit setup

October 1, 2018 at 08:26 | nixos_system | 55daf8 | Adrian Kummerlaender

Replaces short-term Gitea instance on code.kummerlaender.eu.

The main reason for implementing this more complex setup is that Gitea both lacks in features in areas that I care about and provides distracting features in other areas that I do not use.

e.g. Gitea provides multi-user, discussion and organization support but doesn’t provide Atom feeds which are required for Overview.

This is why exposing gitolite-managed repositories via cgit is a better fit for my usecases.

Note that gitolite is further configured outside of Nix through its own admin repository.

As a side benefit pkgs.kummerlaender.eu now provides further archive formats of its Nix expressions which simplifies Nix channel usage.

» Nixify build process

June 4, 2018 at 19:12 | blog.kummerlaender.eu | c08fbb | Adrian Kummerlaender

Building the website in the presence of the Nix package manager is now as simple as:

All dependencies such as the internal InputXSLT, StaticXSLT and BuildXSLT modules as well as external ones such as KaTeX and pandoc are built declaratively by Nix.

» Implement deferred word, conditional resolution

April 13, 2017 at 19:51 | slang | d2126f | Adrian Kummerlaender

Due to the non-trivial way tokens were previously processed the compiler could not safely perform tail-call elimination. Thus the slang evaluation depth was restricted by the maximum call stack size.

This issue is mitigated by introducing deferred word resolution - i.e. pushing expanded tokens onto a buffer stack and processing them in an explicit loop.

This change ties into the implementation of the language’s conditional primitive. The previous implementation did implicitly not support direct nesting of conditional expressions such as:

truthA if
    truthB if
    then else

This issue is now made explicit by disallowing direct nesting of conditionals as depicted above. Appropriate exceptions are generated when required and the conditional primitive is reimplemented in a more robust fashion under the assumption that this rule holds. Note that nesting is still fully supported iff. the nested conditional is contained in a deferredly evaluated word. As a positive side effect this will make it slightly harder to generate unreadable code by forcing developers to write simpler words.

The main change of the conditional primitive lies in deferring branch token processing until the conditional expression is concluded by else. This is achieved by capturing non-dropped tokens in an internal buffer akin to how the word definition operator § is implemented. The branch buffer is discharged after else is evaluated. Discharging is triggered via the newly introduced result method of the primitive evaluation module. This avenue for injecting tokens into the processing stream may be used by further primitives in the future.

» Expand conditional primitive to choose between `then` and `else` branch

April 12, 2017 at 16:15 | slang | 061db1 | Adrian Kummerlaender

i.e. 1 if true then false else evaluates to true, 0 if true then false else evaluates to false.

» Use `pandoc` as markdown processor

January 17, 2017 at 19:38 | blog.kummerlaender.eu | 23f629 | Adrian Kummerlaender

The trigger but not the actual reason for this replacement of kramdown with pandoc was a strange generation issue with kramdown’s latest release.

All recent articles failed to generate anything more than an empty page. A quick check of the resulting HTML for those articles offered nothing out of the ordinary. After taking a close look at the articles in question I narrowed the set of failing articles down to those containing footnotes - tangentially I only started using footnotes a couple of articles ago i.e. this explained this part of the issue.

Some debugging of InputXSLT offered the following problem: Xerces-C generated an error message and stopped processing XML inputs containing nbsp non-blocking space characters in the implementation of the external-command function. This change in kramdown’s output can be traced back to enhancement issue 399. Obviously this is not a problem in kramdown but an issue in the way this static site generator is wrapping HTML inputs.

This problem should be solvable by adding appropriate namespace and doctype declarations to the markdown-generated HTML output. Instead I opted to perform the change to pandoc I had already planned for quite some time.

The choice fell on pandoc as it offers some additional markdown features as well as allowing for conversion to a rich set of document formats. i.e. features like printing articles as PDF using LaTeX are trivial to implement if pandoc is the markdown processor of choice. Furthermore page compilation is noticeably faster using pandoc.

One might note that this switch only solved the original issue by coincidence: Should pandoc start to generate non-blocking space characters the same problem will occur. But I have hopes that such a change would be configurable via pandoc’s plethora of configuration options. As this static site generator assumes everything to be XHTML I see no reason why I should not continue to treat HTML inputs as XML.

» Interpose `open` library function

February 20, 2016 at 21:30 | change | b3ef0f | Adrian Kummerlaender

open is not as side effect free as I had imagined - i.e. if the flag O_TRUNC is passed it truncates the file contents alongside opening the file descriptor. In practice this is done by emacs prior to writing the new file content and as such needs to be intercepted so we can start tracking the file before it is changed.

Interposing open required some changes to make the library work without including fcntl.h. This header not only defines some of the flags we require to check if a library call actually is able to change files but also defines the open library function.

While implementing this change I noticed that the function interpositions implemented in C++ actually need to be declared as external "C" so their names do not get wrangled during compilation. I suspect that this was previously implicitly done for e.g. mmap and write by the included C standard library headers. However this did not work for open which is why all function interpositions are now explicitly declared external.

End result: emacs file changes are now tracked correctly.

» Implement static allocator for initialization

February 17, 2016 at 14:02 | change | af756d | Adrian Kummerlaender

The previous interposition logic based on plain usage of dlsym analogously to various online examples led to a deadlock during neovim startup. This deadlock was caused by neovim’s custom memory allocation library jemalloc because it calls mmap during its initialization phase. The problem with calling mmap during initialization is that this already leads to executing libChangeLog’s mmap version whoes static actual_mmap function pointer is not initialized at this point in time. This is detected and leads to a call to dlsym to remedy this situation. Sadly dlsym in turn requires memory allocation using calloc which leads us back to initializing jemalloc and as such to a deadlock.

I first saw this as a bug in jemalloc which seemed to be confirmed by a short search in my search engine of choice. This prompted me to create an appropriate bug report which was dismissed as a problem in the way mmap was interposed and not as a bug in the library. Thus it seems to be accepted practice that it is not the responsibility of a custom memory allocator to cater to the initialization needs of other libraries relying on function interposition. This is of course a valid position as the whole issue is a kind of chicken and egg problem where both sides can be argued.

To cut to the chase I was left with the only option of working around this deadlock by adapting libChangeLog to call dlsym without relying on the wrapped application’s memory allocator of choice. The most straight forward way to do this is to provide another custom memory allocator alongside the payload function interpositions of mmap and friends.

init/alloc.cc implements such a selectively transparent memory allocator that offers a small static buffer for usage in the context of executing dlsym.The choice between forwarding memory allocation requests to the wrapped application’s allocator and using the static buffer is governed by init::dlsymContext. This tiny helper class maintains an dlsym_level counter by posing as a scope guard.

The end result of this extension to libChangeLog is that it now also works with applications using jemalloc such as neovim and should overall be much more robust during its initialization phase.

» Implement support for excluding arbitrary paths from tracking

February 14, 2016 at 19:52 | change | 1ffaf3 | Adrian Kummerlaender

The library may be provided with a new-line separated list of regular expressions via the newly introduced CHANGE_LOG_IGNORE_PATTERN_PATH.

Any proposed tracking path that is matched by any of the provided patterns is excluded from change reporting. This functionality uses the Standard’s regular expression parsing functionality and as such doesn’t introduce any new dependencies. If no file path is provided or the provided file path is unreadable all paths will be tracked.

change was adapted to set CHANGE_LOG_IGNORE_PATTERN_PATH to .change_log_ignore which means that it will by default exclude any patterns provided via this file in the current working directory.

An example for such a file customized for hiding vim’s internal write logic may look as follows:


Note that this is implemented in a fashion where it is not guaranteed that the full canonical path is checked against the patterns. It remains to be decided if this is enough for all common use cases of this new functionality.

tracking::PathMatcher lacks any explicit thread synchronization - according to my current knowledge this should not be necessary as we are only ever reading the private std::vector<std::regex> instance. If invalid regular expressions are provided they are silently ignored.

» Delay tracking activation

February 11, 2016 at 17:43 | change | 7582ab | Adrian Kummerlaender

Introduce global static enabled variable used to signal the interposed functions to either start tracking or perform plain forwarding without any additional logic. This is required as e.g. nvim crashed when wrapped in libChangeLog because it called interposed functions during library initialization.

» Implement file change tracking using `diff`

December 23, 2015 at 20:43 | change | cce63a | Adrian Kummerlaender

The newly introduced ChangeTracker class is now keeping track of all tracked file in addition to spawning and managing a corresponding diff instance that enables printing pretty patch-style change summaries to the logging target.

This commit introduces boost-process and diff as dependencies of this library.

» Extract actual function acquisition

November 30, 2015 at 11:07 | change | 30d28c | Adrian Kummerlaender

The pointers to the actual function implementations are now fetched inside the actual namespace declared in the actual_function.h header.

Fixed source of noreturn related warning during compilation by adding the appropriate flag. Sadly this means that we can not use std::function in this context as it doesn’t seem to carry these c-like flags.