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;
+	
+}
"Welcome to our mercurial repository"