This is a comprehensive example of how to use the various definition, testing, and logging facilities offered by MoonUnit. These tests can be run by executing make check in the moonunit build tree.
#include <moonunit/interface.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
static int constructed = 0;
{
constructed = 42;
}
static int x = 0;
static int y = 0;
{
x = 2;
y = 3;
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
*(int volatile*)0 = 42;
}
{
*(int volatile*)0 = 42;
}
{
}
{
int fd[2];
if (pipe(fd))
close(fd[0]);
if (write(fd[1], fd, sizeof(int)*2) < 0)
}
{
abort();
}
{
while (1)
pause();
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
typedef struct
{
int needed, waiting;
pthread_mutex_t lock;
pthread_cond_t cond;
} barrier_t;
static void
barrier_init(barrier_t* barrier, int needed)
{
barrier->needed = needed;
barrier->waiting = 0;
pthread_mutex_init(&barrier->lock, NULL);
pthread_cond_init(&barrier->cond, NULL);
}
static int
barrier_wait(barrier_t* barrier)
{
pthread_mutex_lock(&barrier->lock);
barrier->waiting++;
if (barrier->waiting == barrier->needed)
{
barrier->waiting = 0;
pthread_cond_broadcast(&barrier->cond);
pthread_mutex_unlock(&barrier->lock);
return 1;
}
else
{
pthread_cond_wait(&barrier->cond, &barrier->lock);
pthread_mutex_unlock(&barrier->lock);
return 0;
}
}
static barrier_t barrier;
static void*
racer(void* number)
{
barrier_wait(&barrier);
MU_INFO(
"Racer #%lu at the finish line", (
unsigned long) number);
return NULL;
}
{
pthread_t racer1, racer2;
barrier_init(&barrier, 3);
if (pthread_create(&racer1, NULL, racer, (void*) 0x1))
MU_FAILURE(
"Failed to create thread: %s\n", strerror(errno));
if (pthread_create(&racer2, NULL, racer, (void*) 0x2))
MU_FAILURE(
"Failed to create thread: %s\n", strerror(errno));
barrier_wait(&barrier);
pthread_join(racer1, NULL);
pthread_join(racer2, NULL);
}