Mercurial > hg > freeDiameter
changeset 700:0ae67f14ac17
Added testcase and explanation about problematic OpenWRT support (#26)
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 24 Jan 2011 14:32:45 +0900 |
parents | d31c536d452a |
children | 8af6b79cf7d7 |
files | contrib/OpenWRT/HOWTO contrib/OpenWRT/test_required/Makefile contrib/OpenWRT/test_required/testcase.c |
diffstat | 3 files changed, 125 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/OpenWRT/HOWTO Fri Jan 21 16:59:46 2011 +0900 +++ b/contrib/OpenWRT/HOWTO Mon Jan 24 14:32:45 2011 +0900 @@ -1,3 +1,23 @@ +##################### +# !! IMPORTANT !! # +##################### + +The uClibc library that is shipped with OpenWRT lacks support for several POSIX thread +features, such as pthread_cleanup_{push,pop}, that are required by the freeDiameter +framework. + +Until these features are included in the base OpenWRT system, the framework will not +behave correctly on this platform. + +Therefore, the OpenWRT port is NOT usable at this moment. + +A test software is included in test_required for checking if new uClibc distributions +support the required features. You'll have to adapt the Makefile according to your environment. + +##################### + + + This HOWTO describes how to generate a set of ipkg modules for providing support of freeDiameter in an OpenWRT system.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/OpenWRT/test_required/Makefile Mon Jan 24 14:32:45 2011 +0900 @@ -0,0 +1,15 @@ +OWRT_ENV_ROOT=/root/openwrt-env/openwrt +STAGING_UCLIBC_ROOT=$(OWRT_ENV_ROOT)/staging_dir/target-mipsel_uClibc-0.9.31 +STAGING_GCC_ROOT=$(OWRT_ENV_ROOT)/staging_dir/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.31 + +CFLAGS=-Os -pipe -mips32 -mtune=mips32 -funit-at-a-time -fhonour-copts -msoft-float -I$(STAGING_UCLIBC_ROOT)/usr/include -I$(STAGING_UCLIBC_ROOT)/include -I$(STAGING_GCC_ROOT)/usr/include -I$(STAGING_GCC_ROOT)/include +LDFLAGS=-L$(STAGING_UCLIBC_ROOT)/usr/lib -L$(STAGING_UCLIBC_ROOT)/lib -L$(STAGING_GCC_ROOT)/usr/lib -L$(STAGING_GCC_ROOT)/lib + +GCC=mipsel-openwrt-linux-uclibc-gcc +PATH:=$(STAGING_GCC_ROOT)/bin/:$(PATH) + +testcase: testcase.o + $(GCC) $(LDFLAGS) -lpthread testcase.o -o testcase + +testcase.o: testcase.c + $(GCC) $(CFLAGS) -o testcase.o -c testcase.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/OpenWRT/test_required/testcase.c Mon Jan 24 14:32:45 2011 +0900 @@ -0,0 +1,90 @@ +#include <pthread.h> +#include <stdio.h> +#include <strings.h> +#include <assert.h> + +static pthread_barrier_t bar; +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cnd = PTHREAD_COND_INITIALIZER; +static int called = 0; + +#ifndef ASSERT +#define ASSERT(x) assert(x) +#endif /* ASSERT */ + +static void cleanupmutex(void * arg) +{ + printf("cancelation cleanup handler called\n"); + if (arg) { + ASSERT( pthread_mutex_unlock((pthread_mutex_t *)arg) == 0 ); + called++; + } + +} + +static void * mythread(void * a) +{ + int ret; + + /* lock mutex */ + ASSERT( pthread_mutex_lock(&mtx) == 0 ); + + /* Push cleanup */ + pthread_cleanup_push(cleanupmutex, &mtx); + + printf("thread synchronization (mutex acquired)\n"); + + /* Wake the other thread */ + ret = pthread_barrier_wait(&bar); + ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) ); + + /* Now wait for the condition, this unlocks the mutex */ + do { + printf("thread waiting cond\n"); + ASSERT( pthread_cond_wait(&cnd, &mtx) == 0); + printf("thread woken\n"); + } while (1); + + /* Cleanup, never reached */ + pthread_cleanup_pop(1); + return NULL; +} + +int main(int argc, char * argv[]) +{ + int ret; + pthread_t thr; + void * dummy; + + /* initialize the barrier */ + ASSERT( pthread_barrier_init(&bar, NULL, 2) == 0 ); + + printf("Creating thread\n"); + + /* Create the thread */ + ASSERT( pthread_create(&thr, NULL, mythread, NULL) == 0 ); + + printf("main synchronization\n"); + ret = pthread_barrier_wait(&bar); + ASSERT( (ret == 0) || (ret == PTHREAD_BARRIER_SERIAL_THREAD) ); + + ASSERT( pthread_mutex_lock(&mtx) == 0 ); + printf("main: thread is now waiting for condvar\n"); + + /* Cancel the thread */ + ASSERT( pthread_cancel(thr) == 0 ); + + /* Now, unlock, so that the thread can actually really exit */ + ASSERT( pthread_mutex_unlock(&mtx) == 0 ); + + /* Release thread resources */ + ASSERT( pthread_join(thr, &dummy) == 0 ); + + if (called == 1) + printf("Test successful!\n"); + else + printf("Test failed! Cleanup was not called (& lock not released)\n"); + + return 0; + +}