Initial commit
Change-Id: I6a4444e3c193dae437cd7929f4c39aba7b749efa
diff --git a/contrib/OpenWRT/test_required/Makefile b/contrib/OpenWRT/test_required/Makefile
new file mode 100644
index 0000000..d13cc91
--- /dev/null
+++ b/contrib/OpenWRT/test_required/Makefile
@@ -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
diff --git a/contrib/OpenWRT/test_required/testcase.c b/contrib/OpenWRT/test_required/testcase.c
new file mode 100644
index 0000000..11d7882
--- /dev/null
+++ b/contrib/OpenWRT/test_required/testcase.c
@@ -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;
+
+}