Monday, 2 April 2012

sb-posix tests and OS X Lion

I tried to build SBCL on my new Mac last week, and it seems that there are issues with sb-posix contrib tests on Mac OS 10.7.3 x86-64. I am not sure if anybody else is facing this problem, but there were similar issues with 10.6, described here. The workaround from that thread seems to work fine.

Saturday, 13 August 2011

[Caps & Mugs] Some of my CL aliens designs

Sorry for polluting Planet SBCL with these images (also, it is a good idea to remove my blog from the planet, see the previous post on this), but I designed several simple 'Lisp + aliens' images which I want to put into the public domain. They are not complex or artful, and maybe even agressive (not funny, as the traditional Lisp aliens), but I like them:

The first:



The second:



The third:




These are in the public domain, so anyone can use them.

Thursday, 11 August 2011

[Note] Crowdfunding and SBCL

I think that you already know about it, but if not, please see here.

BTW, our 'SBCL Users & Developers' Linkedin group has more than 100 members (105 at the time when I'm writing this post). Thanks to all people who participate.

And the last update is my personal one: there were some changes in my career, and I cannot say that I am a CL developer at this time. But that's okay - people should try other things, even if they started with the best one :) This blog will be silent during my absence in CL community, I think.

Monday, 2 May 2011

[Feature] MAKE-THREAD with the thread arguments

Today seems to be a features day :)

This feature has the extremely simple implementation (unless I'm missing something here), but it makes the life easier when it comes to the thread function's arguments. So, with this patch you can write the next code:

(defun f (x y) (* x y))

(sb-thread:make-thread #'f :args '(6 7))


without messing with the wrapper lambda.

Maybe this simple thing does not deserve a post, but I am really happy to see it working. The patch is here.

[Feature] Running tests in parallel

This feature may be interesting for the people who often run SBCL tests. It uses several CPU cores to do that quickly. While it is still not finished, there is some early implementation which can be used to measure the performance boost. In case you want to try it yourself, here are the explanations and instructions:

The idea of the multi-core test launcher is based on the fact that SBCL test files are independent, so they can be loaded and executed in parallel. The classic model with the threads pool and the test files queue fits fine - there is a main, "supervisor" thread, whose job is to spawn additional threads. Every additional thread takes care of one impure test file at a time, and executes it using child SBCL process. The supervisor thread runs all pure tests (most of them are short) and waits for the additional threads to finish.

On my PC with Phenom X4 920, I use three additional threads and all tests run 3 minutes. Without the parallel launcher, they take 8 minutes to finish. Failures seem to be reported correctly, I have tweaked several tests to check that. However, the failures collection needs synchronization, and I hope to finish with it in the future.

The performance may be improved even more by splitting all-threads.impure.lisp on several files, but this is a low-priority task. Just make sure that you rename the original threads.impure.lisp before trying this stuff (the file is so long that a separate thread runs it almost 3 minutes, so it should be the first file in the queue, alphabetically). Also, adjust the number of threads as described in Launchpad. The default value are for quad-core systems.

The issue page and the initial code changes are here:

https://bugs.launchpad.net/sbcl/+bug/742777

In case you find any errors/mistakes in the code, please let me know. I am interested to make this feature stable and ready for the upstream.

Tuesday, 11 January 2011

[mini-HOWTO] Writing Regression Tests For SBCL

Most of the complex software systems have some kind of regression tests, and SBCL is not an exception. In this short post, I want to answer the next two questions:

1. Why it is preferable to provide a regression test with the bug report?
2. How to write such a test?

Frankly speaking, regression tests are not necessary for bug reports. One may just say “this code is compiled wrongly”, and then attach the code snippet. However, such reports can be hard to understand, especially when we are trying to figure out the desired behavior. In contrary, regression tests always show the desired behavior, so they make the report more informative.

Moreover, your report with a regression test always saves the time for SBCL developer who will fix the corresponding bug. A regression test is mandatory for the most of patches, so someone should write it anyway. I do not know about the others, but I prefer the next steps while fixing a bug in SBCL:

- write a regression test. Make sure that it fails before the fix;
- fix the bug;
- make sure that all regression tests pass.

The issue originator knows the problem very well, so he or she can provide the best regression test.

So, how to write them? It is surprisingly easy in most cases. First of all, you need to find out the right test file to put your test into. These files are located in /sbcl/tests directory. They have the extension “lisp”, and the two important parts before it: the suffix “pure” or “impure”, and the main part which classifies the subject of the tests – in other words, the functionality which is tested. The main part is something like “compiler”, “loop”, “print” etc. The suffix “pure” means that the file contains no tests with global side effects; “impure” files contain tests which define variables, conditions, classes, functions and so on. For example, “loop.pure.lisp” file contains LOOP macro tests without side effects.

After you have selected a file, it's a time to write the test itself. The only constant element of all tests is a WITH-TEST wrapper, which binds a human-readable name to your test (it can do other things as well, but I use only :name keyword. See the macro definition in test-util.lisp to find out more). The rest of the test body may vary (you can use different assertion clauses, bind handlers for compilation errors or warnings etc.).

Here is a very simple (and pure) test from arith.pure.lisp:




The test passes when ASSERT receives non-NIL value. Obviously, you may use any CL code inside ASSERT. For example:




RAISES-ERROR? is an utility macro (defined in assertoid.lisp). It is useful when you want to test that a form evaluation signals an error. The optional second argument can be used to specify the condition type, as in the above example.

Here is another example – the impure test from mop.impure.lisp:




The test is impure, because it creates a class definition. Some old tests (like this) miss WITH-TEST, but it is strongly recommended for new ones.

It is often required to test that SBCL signals (or does not signals) errors and/or warnings during the particular form compilation. This pure LOOP test can be a good example:




The test idea is to check the return values of COMPILE. Another way to do something similar is to use HANDLER-CASE (the example from compiler.pure.lisp):




This test ensures that a compiler note is printed for the non-optimal operation.

In general, SBCL regression tests are very expressive and powerful - we can test quite complex functionality in the several lines of code.

To run the added tests, execute a command (on Linux):

sh run-tests.sh filename

from sbcl/tests directory. Without a file argument, it runs all tests in the regression suite.

I hope that this short post is helpful for those who have never written any SBCL regression tests. Just try to do it when submitting a new bug report – and you will help SBCL developers a lot.

Saturday, 18 September 2010

SBCL platforms

There was a poll in Linkedin about the SBCL platforms, and you can see the final chart below. I cannot say that it shows the real picture, because the number of responses is very small. But anyway, Linux seems to be the reasonable winner here, which is not a big surprise :)