Posts Tagged serious

Java concepts in C: classes

While to some it might seem absurd, some concepts in Java development can be used more or less straight-forward in C. Lets start with basic things such as object-oriented programming. OOP is a way of programming that does not rely on the language in use.

You have several choices in C:

  1. (most common): use a .h file with the struct and all functions related to the struct. if the struct is called foo_bar, the functions are called foo_bar_init(), foo_bar_set_baz(), etc.
  2. (the gnome way): gobject is a class concept that uses preprocessor directives. It is as effective as ugly.

I prefer the first. A funky thing you can do in C is to put the functions as function pointers in the struct:


typedef struct {
int a;
(void)*set_a(int);
} myclass;
void myclass_set_a(myclass * c, int new_a) {
c->a = new_a;
}
myclass * myclass_init() {
myclass * c = (myclass*) malloc(sizeof(myclass));
c->set_a = myclass_set_a;
return c;
}

This allows you to write

c->set_a(c, 42);

in your code, which already has a very object-oriented-language touch. It is basically the same thing python does: The first argument of a method is the object, only if you are already in the object and call self.mymethod(), python fills in the self for you.

If you want something ugly, you add a type-unsafe subclassing concept:

typedef struct {
int a;
void * additional_data;
} classA;
classA * classA_init();
typedef struct {
int b;
void * additional_data;
} classB;
classA * classB_init() {
classB * b = (classB*)malloc(sizeof(classB));
classA * a = classA_init();
a->additional_data = (void*)b;
return a;
}
classB_set_b(classA * c, int newb)  {
(classB*)(c->additional_data)->b = newb;
}

2 Comments

C: IDE of choice

I used to use gedit as C IDE, I still use vim, but today I’d like you to try eclipsecdt.
It has the benefit of highlighting the line of errors and being able to jump there, rebuilding with a keystroke (Ctrl-B) without leaving the window and providing a tree view. So far, lots of C IDEs do that. anjuta for example. The thing that made the difference for me is that eclipsecdt provides completion for structs (functions too) when you haven’t written any letter yet. For example “mystructp->”(Ctrl-Space). I had a look at anjuta and BLOCKS.
Further, the outline (functions, structs, directives in the file) is nice as well as a very good preprocessor expansion/preview. Eclipsecdt also has a sufficient method of autoformatting your C code and also respects your preprocessor code.
So if you have

#define IFDEBUG if(1)
IFDEBUG
printf("blah");

depending on your settings, printf will be intended.

Last word: Intend with tabs and indent “case:”. If you don’t, you are wrong :-).
Edit: typo.

2 Comments

Java concepts in C: logging

One will always run into the problem that one needs more detailed output from a section at some time, and less verbose output at another time. Or the whole output should be more verbose, or you want to investigate a segfault.

There are some logging libraries (log4c for example). I however use the following approach:



debug.h:

#ifdef DEBUG

#define IFDEBUG if(1)

#else

#define IFDEBUG if(0)

#endif

#ifdef SEGV

#define IFSEGV if(1)

#else

#define IFSEGV if(0)

#endif

#define debug(str)        IFDEBUG { printf("\tDEBUG[%s]: %s\n", AT, str); fflush(NULL); }

#define dump_i(str, var)  IFDEBUG { printf("\tDEBUG[%s]: %s: %i\n", AT, str, var); fflush(NULL); }

#define dump_p(str, var)  IFDEBUG { printf("\tDEBUG[%s]: %s: %p\n", AT, str, var); fflush(NULL); }

in your code:

		debug("we are now doing foo ");

		IFSEGV

			dump_p("m\n", (void*)m);

		IFDEBUG

			printf("\t\tn_par=%d; status=%d\n", get_n_par(m), status);

Example output:

	DEBUG[tests/tests.c:196]: add starting points, ...

This allows you to recompile your code with -DDEBUG -DSEGV and enable/disable verbosity levels without constant code changes.

2 Comments

Java concepts in C: test-first development and unit-testing

Unit testing is no rocket science. Do it as often as you can. Writing your own unit-testing library is simple: You need something that calls your test methods, and some form of assert-function that can die with style.

I chose the convention of simply returning 0 if the test is ok, and 1 if it fails:

/* example test function. return value is 0 iff succeeded.*/

int test_tests(void) {

        return (count_tests() > 0 ? 0 : 1);

}

A assertEquals directive you can use.

#define ASSERTEQUALD(result, expected, text) { \

                if(expected == result || expected - result < (expected+result)*0.001 ) { \

                        printf("  subtest ok: %s\n", text); \

                } else { \

                        printf("  ASSERT EQUAL FAILED: expected: %e; got: %e; %s\n", expected, result, text); \

                        return 1; \

                } \

        }

Collect the tests you want to run



/* register of all tests */

int (*tests_registration[])(void)  = {

        /* this is test 1 */ /*test_tests, */

        test_hist,

        test_create,

        test_alloc,

        test_load,

        test_resize,

        test_append,

        test_random,

        test_mod,

        test_write,

        test_write_prob,

        /* register more tests before here */

        NULL,

};

And link with the following test runner. (run-tests.c)

/* we do testing of the inner works */

#include <ctype.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

extern int (*tests_registration[])(void);

int count_tests() {

	int n = -1;

	while (tests_registration[++n] != NULL)

		;

	return n;

}

/*

 * when testnr in 1..n, execute the specific test.

 * output is conforming to TAP

 */

int test(int testnr) {

	int n = count_tests();

	int r;

	if (testnr <= 0 || testnr > n) {

		fprintf(stderr, "Test number out of range (1..%d)\n", n);

		return -1;

	}

	r = tests_registration[testnr - 1]( ) ;if(r == 0)

	printf("ok %d\n", testnr);

	else

	printf("not ok %d - returned %d\n", testnr, r);

	return r;

}

int test_all() {

	int i = 0;

	int n = count_tests();

	int count = 0;

	printf("1..%d\n", n);

	while (i++ < n) {

		count += test(i);

	}

	if (count != 0) {

		printf("  %d of %d tests unsuccessful\n", count, n);

	} else {

		printf("  all %d tests successful\n", n);

	}

	return count;

}

void usage(char * progname) {

	printf("SYNOPSIS: \n\n"

		"%s               \trun all tests\n"

		"%s [<testnumber>]\trun a specific test by number\n"

		"\n"

		"Tests available: 1..%d\n\n"

		"", progname, progname, count_tests());

}

int main(int argc, char ** argv) {

	int t;

	if (argc == 1) {

		return test_all();

	} else if (argc == 2 && isdigit(argv[1][0])) {

		errno = 0;

		t = strtol(argv[1], (char **) NULL, 10);

		if (errno != 0) {

			usage(argv[0]);

		} else {

			test(t);

		}

	} else {

		usage(argv[0]);

	}

	return 0;

}

You can then run your tests selectively or the whole suite



$ ./tests.exe

...

ok 8

  subtest ok: mod ints

  subtest ok: mod doubles

  subtest ok: mod doubles

ok 9

ok 10

  all 10 tests successful

$ ./tests.exe 4

  subtest ok: x 0

  subtest ok: x 1

  subtest ok: x last

	DEBUG[tests/tests.c:196]: add starting points, ...

  subtest ok: y 0

  subtest ok: y 1

  subtest ok: y last

ok 4

The beauty of this test suite (yes, there is some beauty in it), is that it is pluggable, extendable, debuggable and TAP (Test Anything Protocol) conform.

As with all test suites you will have to separate your code into testable chunks so that they are accessible by your test functions.

2 Comments

C: Documenting is Duty

Document your functions, your structs, your preprocessor directives, and most importantly, your general concept.

Doxygen provides a good tool for keeping the documentation inline. If your documentation is not next to your code, it will never be updated.
It produces nice html output. Make a make target. Write a general introduction with \mainpage.

No Comments

C: Simple multi-processor optimization

Programming threads explicitly is extremely verbose. But how else can you utilize all processors on your machine? You could use a compiler that is so good it can optimize your code and do everything.

However, with OpenMP it is as easy as adding 3 lines:

Look for a expensive loop in your code

+ #include <omp.h>

...

+#pragma omp parallel for

                for (i = 0; i < n; i++) {

                        for (j = 0; j < n2; j++) {

                                do_something(m, i, j);

                        }

                }

...

add -fopenmp to your compile-flags.

3 lines. By default, the number of processors used is the number available, and the work is split up between the threads automatically, but you can set it at runtime (!) using the environment variable OMP_NUM_THREADS.

OpenMP is of course much more powerful, but this little change might already improve your optimization. It scales very well if you have enough work for each thread.

Last word: The concepts and way of programming when sharing load between computers (clusters, grids) is totally different from multi-processor programming. You will have to choose at some point. OpenMP is not meant for clusters. Have a look at programming with BOINC.

No Comments

C: Makefiles and compile flags

I bet whole books have been written about the compile flags of gcc.

In my opinion it is good style to apply all the following flags to all your programs and try to enforce them onto others:

-Wall -Werror -Wextra -ansi -pedantic

This might seem a little harsh at first, but it has several benefits: 1) Errors in your code are detected before execution. 2) Your code is more portable.
The only case where the compile flags above are annoying, is when you have unused parameters. Trick:

void my_no_sort(int * a){

   (void)a;

}

The line performs a no-op onto the parameter, saying “I voluntarily do not use this parameter”.

Optimization

I will try to keep this short, as there are good resources around.
1. Do not optimize. Premature optimization is the root of all evil. First make sure your program is correct and complete (A unimplemented routine is faster than a implemented one).
2. Measure, never assume. Optimize only where your bottlenecks are, and when you can measure the performance increase. Optimization generally leads to poorer code style. Concluding after 3 hours that a certain change does not improve your performance is a good reason to throw the change away. Use version control systems, even (especially?) if you program alone.
3. gcc drastically improved optimization when moving to 4.0/4.1. Try to use a new compiler. -O3 is not better than -O2 or -Os in all cases, especially if your program size is big in memory. O3 increases the program and swapping in/out between the various caches can become a problem.
4. Run tests. On various scenarios. Several times. Watch the deviation closely before concluding significance.
BenchmarkOn the right side is what the evaluation results of various compile-flag configurations should look like.
5. Take it seriously or let it be. Many types of programs don’t need to be extremely fast: User interaction programs and logins can take up to 200ms for returning a result. A program in a higher-level scripting language might be easier to maintain. Compilers don’t need to be fast, correctness is so much more important.

At some point, be satisfied with the level of performance and try to keep it over the following versions :-)

No Comments

C: Mitigating Memory Management Mistakes

So your C code has invalid allocations, double frees, pointer arithmetic errors and generally crashes. That’s ok.

First of all, check the return value of every malloc/calloc/realloc.


#include <assert.h>
void myfunction(int n) {
int * arr = (int*) malloc(n, sizeof(int));
/* assert(arr != NULL); -- for development */
if(arr == NULL) {
perror("memory could not be allocated");
// error handling
}
...

Your code will crash sooner or later, but if you handle it now, you will know why.

Valgrind:

You will not be able to get everything right, except with excessive effort. Try valgrind, it prints out what memory you illegally accessed, left unfreed (leaks), etc.. Best of all: It tells you where exactly in your code.

Example output.

==19182== Invalid write of size 4
==19182==    at 0x804838F: f (example.c:6)
==19182==    by 0x80483AB: main (example.c:11)
==19182==  Address 0x1BA45050 is 0 bytes after a block of size 40 alloc'd
==19182==    at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)
==19182==    by 0x8048385: f (example.c:5)
==19182==    by 0x80483AB: main (example.c:11)

call it like this:

$ valgrind --leak-check=full ./myprog.exe

DUMA:

Beside having a silly acronym (Detect Unintended Memory Access), this library protects you from illegal memory access. The previous name is more accurate: “ElectricFence”. Usually the OS is very lenient about memory access (no checks make stuff fast), except when you run into other programs space. To make the usual output (“Segmentation fault.”) more colorful, and to terminate early (so that your debug output matches the access), run your (or any) program with

$ LD_PRELOAD=libduma.so.0.0.0 ./myprog.exe

The LD_PRELOAD is a bash feature (read about it elsewhere), it saves you from linking your program with the library.
Last word I wanted to say: With DUMA or valgrind, your program will run slower (all allocated memory is registered). Be a good programmer and make your programs pointer perfect (what’s up with the alliterations by the way), so that the OS doesn’t have to do it.

No Comments

Java concepts in C: garbage collection

While purists will say using a garbage collector in C is blasphemy, it has been shown that very often code runs faster when a garbage collector is in use.
Also, sometimes it occurs that you have to leave a function due to a error case and don’t want to copy all the cleanup to every exit point. You should if you can.

When you have memory leaks, and don’t use a garbage collector, your program will also become slower and slower.

However, luckily good garbage collectors exist and are easy to use. E.g. the good old boehm gc. Linux distributors usually provide a package.

You can include my memory.h and just call mem_malloc, mem_calloc, mem_realloc, mem_free instead of without the mem. for people that don’t have boehmgc installed, you still remain compatible. Of course there are other ways too.


#ifndef MEMORY_H_
#define MEMORY_H_
#include "debug.h"
#define FREEMSG(x) IFSEGV dump_p("about to free", (void*)x);
#ifdef WITHOUT_GARBAGE_COLLECTOR
#define mem_malloc(x) malloc(x)
#define mem_calloc(n,x) calloc(n, x)
#define mem_realloc(p,x) realloc(p,x)
#define mem_free(x) { FREEMSG(x); free(x); (x) = NULL; }
#else
#include <gc.h>
#define mem_malloc(x) GC_malloc(x)
#define mem_calloc(n,x) GC_malloc((n)*(x))
#define mem_realloc(p,x) GC_realloc((p),(x))
#define mem_free(x) { FREEMSG(x); (x) = NULL; }
#endif
#endif /* MEMORY_H_ */

No Comments

Patterns for Unit testing multithreaded applications

What I do here is more module/component testing of threaded parts of an application. Testing a module without threads is way easier than one with threads. I use JUnit and standard concurrency mechanisms for testing. Logging (log4j) can be a big help during test development.

Pattern Alpha:

Basic asynchronous event checking using semaphores explicitly.
The general idea is the following: first add a Mocked Listener inline:

	final Semaphore s = new Semaphore(0);
fw.addListener(new IModificationListener() {
public void fileModified(File f, ModifyActions action) {
log.debug("got event: " + f.getAbsolutePath() + ":" + action);
Assert.assertEquals("just_edited", f.getName());
Assert.assertEquals(ModifyActions.MODIFIED, action);
s.release();
}
});

It is important to note that the AssertionFailedError from JUnit will not cause the test to fail, because it happens in a different thread! It is wise to do some logging.
After that:

	Assert.assertTrue("Real content change",
s.tryAcquire(interval * 3,TimeUnit.MILLISECONDS));

We test if we got the right call in time. You have to choose a useful timing. Note that this should still be fast, so my advice would be: Determine what timing is the lower limit that still works for you – choose 10x of that. Also document for other development what the expected run time is.

A similar example:

	@Test
public void testReceiveSend_XML() throws Exception {
final String testmsgcontent = "<msg>hello</msg>";
final Semaphore s = new Semaphore(0);
msgService.registerReceiveMessageListener(
new IMessageReceiveListener() {
@Override
public void receivedMessage(UserId from_userid,
String content) {
// do some more checks here
s.release();
}
});
msgService.sendMessage(testUser2, testmsgcontent);
Assert.assertTrue(s.tryAcquire(2, 5, TimeUnit.SECONDS));
}

Pattern Beta:

more advanced checking of one or more handlers with a state chain.

I use this Counter (java, 1 KB) class with the functions inc() and await(statenumber).

Consider the following example:
State 0. User 1 sends a message to User 2. The message is received by User 2 (State 1), User 2 replies. User1 replies again, the message is received by User 2 again (State 2).
The test constraint is that the test is successful iff State 2 was reached within a certain time.

	@Test
@Prerequisite(checker = TestEnvironment.class)
public void testReceiveSend_MultipleInteractions() throws Exception {
final String testmsgcontent1 = "Testmessagecontent1";
final String testmsgcontent2 = testmsgcontent1 + " >> really?";
final String testmsgcontent3 = testmsgcontent2 + " >> yeah, srsly!";
final Counter c = new Counter();
msgService2.registerReceiveMessageListener(
new IMessageReceiveListener() {
@Override
public void receivedMessage(UserId from_userid,
String content) {
c.inc(); // We reached our next control check
if (c.getValue() == 1) {
Assert.assertEquals(testUser1, from_userid);
Assert.assertEquals(testmsgcontent1, content);
try {
msgService2.sendMessage(from_userid,
content + " >> really?");
} catch (Exception e) {
log.error("", e);
Assert.fail("Unexpected exception");
}
} else if (c.getValue() == 2) {
Assert.assertEquals(testUser1, from_userid);
Assert.assertEquals(testmsgcontent3, content);
} else {
Assert.fail("Unexpected call");
}
}
});
msgService1.registerReceiveMessageListener(
new IMessageReceiveListener() {
// practically a echo service
@Override
public void receivedMessage(UserId from_userid,
String content) {
try {
msgService1.sendMessage(from_userid,
content + " >> yeah, srsly!");
Assert.assertEquals(testmsgcontent2, content);
} catch (Exception e) {
Assert.fail("Unexpected exception");
}
}
});
msgService1.sendMessage(testUser2, testmsgcontent1);
Assert.assertTrue(c.await(2, 5, TimeUnit.SECONDS));
}

Pattern Gamma

So this was very simple so far, but we most likely don’t know the order of events that might come in. Also, I’d like the events to have names rather than numbers.

So what I really want is

  • to enter a event in the queue: step(“myevent”);
  • to wait until a step is reached no matter if it is exactly the next: awaitStep(“something”); This removes the step from the list.
  • to assure that was all that was received (the list of events is empty): isDone()

This Tracer.java (java, 3 KB) class helps me with that.
It also allows you to check only specific events and ignore others you enter (don’t use isDone).

An example:

	@Test
public void testSocketMethod_accepting() throws Exception {
// ...
tfm.request(this.outrequest, new INegotiationSuccessListener() {
@Override
public void failed(Throwable reason) {
t.step("clientside negotiation failed");
Assert.fail();
}
@Override
public void succeeded(IFileTransfer ft) {
t.step("clientside negotiation succeeded");
Assert.assertEquals(filename, ft.getFileName());
// make the variable available
TestSocketFileTransfer.this.fileTransfer = ft;
}
});
Assert.assertTrue(this.t.awaitStep("clientside negotiation succeeded", 1,
TimeUnit.SECONDS));
// it is assured that fileTransfer is available now
while (!this.fileTransfer.isDone()) { // This is a form of waiting in the main thread because this might take longer
try {
log.debug(this.t.toString());
Thread.sleep(40);
} catch (InterruptedException e) {
// best effort, doesn't matter
}
}
Assert.assertTrue(this.t.await("getting content from fs,started on server", 40,
TimeUnit.MILLISECONDS));
log.debug(this.t.toString()); // print what else is in the Tracer
Assert.assertTrue("timeout", this.t.isDone(40, TimeUnit.MILLISECONDS));
}

As far as I know, there are no simple libraries for handling threaded testing, I don’t know if that is possible in a very simple yet flexible way.
Threaded testing is quite verbose (as you see), but once you saw these constructs, it is easier to read.

I welcome your postings or links to other approaches in threaded testing.

PS: My experience in threaded testing comes from working at Porsche Informatik and two semesters of a Software Engineering project for the university that handles project folders (modifying listeners for deleting/changing files) and transferring content over the network (XMPP, sockets, thus message and other state notifications). If you are interested, the project, called Jake will be release within a month.

2 Comments