summaryrefslogtreecommitdiffstats
path: root/testsuites/psxtests
diff options
context:
space:
mode:
authorJennifer Averett <Jennifer.Averett@OARcorp.com>2008-01-18 17:09:51 +0000
committerJennifer Averett <Jennifer.Averett@OARcorp.com>2008-01-18 17:09:51 +0000
commitf7ad5b3e12623b865c4557d8d19e3b013a4ef6c0 (patch)
tree758705c788afb948e0eeb2177522239adcf23aec /testsuites/psxtests
parent2008-01-18 Jennifer Averett <jennifer.averett@OARcorp.com> (diff)
downloadrtems-f7ad5b3e12623b865c4557d8d19e3b013a4ef6c0.tar.bz2
2008-01-18 Jennifer Averett <jennifer.averett@OARcorp.com>
* Makefile.am, configure.ac: * psxcleanup/Makefile.am, psxcleanup/psxcleanup.c, psxcleanup/psxcleanup.scn: New files.
Diffstat (limited to 'testsuites/psxtests')
-rw-r--r--testsuites/psxtests/ChangeLog6
-rw-r--r--testsuites/psxtests/Makefile.am2
-rw-r--r--testsuites/psxtests/configure.ac1
-rw-r--r--testsuites/psxtests/psxcleanup/Makefile.am28
-rw-r--r--testsuites/psxtests/psxcleanup/psxcleanup.c253
-rw-r--r--testsuites/psxtests/psxcleanup/psxcleanup.scn6
6 files changed, 295 insertions, 1 deletions
diff --git a/testsuites/psxtests/ChangeLog b/testsuites/psxtests/ChangeLog
index 4ede460e1f..df982154e7 100644
--- a/testsuites/psxtests/ChangeLog
+++ b/testsuites/psxtests/ChangeLog
@@ -1,5 +1,11 @@
2008-01-18 Jennifer Averett <jennifer.averett@OARcorp.com>
+ * Makefile.am, configure.ac:
+ * psxcleanup/Makefile.am, psxcleanup/psxcleanup.c,
+ psxcleanup/psxcleanup.scn: New files.
+
+2008-01-18 Jennifer Averett <jennifer.averett@OARcorp.com>
+
* psx01/init.c, psxmsgq01/init.c, psxtimer01/psxtimer.c,
psxtimer01/psxtimer01.scn, psxtimer02/psxtimer.c:
diff --git a/testsuites/psxtests/Makefile.am b/testsuites/psxtests/Makefile.am
index ed3ae074eb..1981c6cb45 100644
--- a/testsuites/psxtests/Makefile.am
+++ b/testsuites/psxtests/Makefile.am
@@ -5,7 +5,7 @@
ACLOCAL_AMFLAGS = -I ../aclocal
SUBDIRS = psxhdrs psx01 psx02 psx03 psx04 psx05 psx06 psx07 psx08 psx09 \
- psx10 psx11 psx12 psxtime psxtimer01 psxtimer02 psxcancel psxbarrier01 \
+ psx10 psx11 psx12 psxcleanup psxtime psxtimer01 psxtimer02 psxcancel psxbarrier01 \
psxmsgq01 psxrwlock01 psxsem01 psxspin01 psxenosys psxsignal01 psxsysconf \
psxualarm
diff --git a/testsuites/psxtests/configure.ac b/testsuites/psxtests/configure.ac
index ad2fa02760..d1ec04758d 100644
--- a/testsuites/psxtests/configure.ac
+++ b/testsuites/psxtests/configure.ac
@@ -43,6 +43,7 @@ psx13/Makefile
psxbarrier01/Makefile
psxcancel/Makefile
psxchroot01/Makefile
+psxcleanup/Makefile
psxenosys/Makefile
psxfile01/Makefile
psxhdrs/Makefile
diff --git a/testsuites/psxtests/psxcleanup/Makefile.am b/testsuites/psxtests/psxcleanup/Makefile.am
new file mode 100644
index 0000000000..915e9dc659
--- /dev/null
+++ b/testsuites/psxtests/psxcleanup/Makefile.am
@@ -0,0 +1,28 @@
+##
+## $Id$
+##
+
+MANAGERS = all
+
+rtems_tests_PROGRAMS = psxcleanup.exe
+psxcleanup_exe_SOURCES = psxcleanup.c system.h ../include/pmacros.h
+
+dist_rtems_tests_DATA = psxcleanup.scn
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+psxcleanup_exe_LDADD = $(MANAGERS_NOT_WANTED:%=$(PROJECT_LIB)/no-%.rel)
+
+AM_CPPFLAGS += -I$(top_srcdir)/include
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(psxcleanup_exe_OBJECTS) $(psxcleanup_exe_LDADD)
+LINK_LIBS = $(psxcleanup_exe_LDLIBS)
+
+psxcleanup.exe$(EXEEXT): $(psxcleanup_exe_OBJECTS) $(psxcleanup_exe_DEPENDENCIES)
+ @rm -f psxcleanup.exe$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/psxtests/psxcleanup/psxcleanup.c b/testsuites/psxtests/psxcleanup/psxcleanup.c
new file mode 100644
index 0000000000..f8092648ab
--- /dev/null
+++ b/testsuites/psxtests/psxcleanup/psxcleanup.c
@@ -0,0 +1,253 @@
+/*
+ *
+ * This is a simple real-time applications XXX.
+ *
+ * Other POSIX facilities such as XXX, condition, .. is also used
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#define CONFIGURE_INIT
+#include "system.h"
+#include <pthread.h> /* thread facilities */
+#include <signal.h> /* signal facilities */
+#include <unistd.h> /* sleep facilities */
+#include <sched.h> /* schedule facilities */
+#include <time.h> /* time facilities */
+#include <stdio.h> /* console facilities */
+#include "tmacros.h"
+
+#define NUMBER_THREADS 2
+pthread_t ThreadIds[NUMBER_THREADS];
+
+typedef struct {
+ pthread_mutex_t lock;
+ pthread_cond_t rcond;
+ pthread_cond_t wcond;
+ int lock_count; /* < 0 .. Held by writer. */
+ /* > 0 .. Held by lock_count readers. */
+ /* = 0 .. Held by nobody. */
+ int waiting_writers; /* Count of waiting writers. */
+} lock_t;
+
+volatile boolean reader_cleanup_ran;
+volatile boolean release_read_lock_ran;
+volatile boolean writer_cleanup_ran;
+
+void waiting_reader_cleanup(void *arg)
+{
+ lock_t *l;
+
+ reader_cleanup_ran = TRUE;
+
+ l = (lock_t *) arg;
+ pthread_mutex_unlock(&l->lock);
+}
+
+void lock_for_read(void *arg)
+{
+ lock_t *l = arg;
+
+ pthread_mutex_lock(&l->lock);
+ pthread_cleanup_push(waiting_reader_cleanup, l);
+ while ((l->lock_count < 0) && (l->waiting_writers != 0))
+ pthread_cond_wait(&l->rcond, &l->lock);
+ l->lock_count++;
+ reader_cleanup_ran = FALSE;
+
+ /*
+ * Note the pthread_cleanup_pop executes
+ * waiting_reader_cleanup.
+ */
+ pthread_cleanup_pop(1);
+
+ if ( reader_cleanup_ran == FALSE ) {
+ puts( "reader cleanup did not run" );
+ rtems_test_exit(0);
+ }
+}
+
+void release_read_lock(void *arg)
+{
+ lock_t *l = arg;
+
+ release_read_lock_ran = TRUE;
+ pthread_mutex_lock(&l->lock);
+ if (--l->lock_count == 0)
+ pthread_cond_signal(&l->wcond);
+ pthread_mutex_unlock(&l->lock);
+}
+
+void waiting_writer_cleanup(void *arg)
+{
+ lock_t *l = arg;
+
+ writer_cleanup_ran = TRUE;
+
+ if ((--l->waiting_writers == 0) && (l->lock_count >= 0)) {
+ /*
+ * This only happens if we have been canceled.
+ */
+ pthread_cond_broadcast(&l->wcond);
+ }
+ pthread_mutex_unlock(&l->lock);
+}
+
+void lock_for_write(lock_t *l)
+{
+ pthread_mutex_lock(&l->lock);
+ l->waiting_writers++;
+ l->lock_count = -1;
+
+ pthread_cleanup_push(waiting_writer_cleanup, l);
+
+ while (l->lock_count != 0)
+ pthread_cond_wait(&l->wcond, &l->lock);
+ l->lock_count = -1;
+
+ /*
+ * Note the pthread_cleanup_pop executes
+ * waiting_writer_cleanup.
+ */
+ writer_cleanup_ran = FALSE;
+ pthread_cleanup_pop(1);
+
+ if ( writer_cleanup_ran == FALSE ) {
+ puts( "writer cleanup did not run" );
+ rtems_test_exit(0);
+ }
+}
+
+void release_write_lock(void *arg)
+{
+ lock_t *l = arg;
+
+ writer_cleanup_ran = TRUE;
+
+ /* pthread_mutex_lock(&l->lock); */
+ l->lock_count = 0;
+ if (l->waiting_writers == 0)
+ pthread_cond_broadcast(&l->rcond);
+ else
+ pthread_cond_signal(&l->wcond);
+ /* pthread_mutex_unlock(&l->lock); */
+}
+
+
+/*
+ * This function is called to initialize the read/write lock.
+ */
+void initialize_lock_t(lock_t *l)
+{
+ pthread_mutexattr_t mutexattr; /* mutex attributes */
+ pthread_condattr_t condattr; /* condition attributes */
+
+ if (pthread_mutexattr_init (&mutexattr) != 0) {
+ perror ("Error in mutex attribute init\n");
+ }
+ if (pthread_mutex_init (&l->lock,&mutexattr) != 0) {
+ perror ("Error in mutex init");
+ }
+
+ if (pthread_condattr_init (&condattr) != 0) {
+ perror ("Error in condition attribute init\n");
+ }
+ if (pthread_cond_init (&l->wcond,&condattr) != 0) {
+ perror ("Error in write condition init");
+ }
+ if (pthread_cond_init (&l->rcond,&condattr) != 0) {
+ perror ("Error in read condition init");
+ }
+
+ l->lock_count = 0;
+ l->waiting_writers = 0;
+}
+
+void *ReaderThread(void *arg)
+{
+ lock_t *l = arg;
+
+ puts("Lock for read");
+ lock_for_read(l);
+ puts("cleanup push for read");
+ pthread_cleanup_push(release_read_lock, &l->lock);
+
+ /* Thread has read lock. */
+ release_read_lock_ran = FALSE;
+ puts("cleanup pop for read");
+ pthread_cleanup_pop(1);
+
+ if ( release_read_lock_ran == FALSE ) {
+ puts( "release read lock did not run" );
+ rtems_test_exit(0);
+ }
+ return NULL;
+}
+
+void *WriterThread(void *arg)
+{
+ lock_t *l = arg;
+
+ puts("Lock for write");
+ lock_for_write(l);
+ puts("cleanup push for write");
+ pthread_cleanup_push(release_write_lock, &l->lock);
+
+ /* do nothing */
+ puts("do nothing cleanup pop for write");
+ pthread_cleanup_pop(0);
+
+ /* Thread has write lock. */
+ puts("cleanup pop for write");
+ pthread_cleanup_pop(1);
+ return NULL;
+}
+
+/*
+ * main entry point to the test
+ */
+
+void *POSIX_Init (
+ void *argument
+)
+{
+ pthread_attr_t attr; /* task attributes */
+ int status;
+ lock_t l;
+
+ puts( "\n\n*** POSIX CLEANUP TEST ***" );
+
+ /*************** INITIALIZE ***************/
+ initialize_lock_t(&l);
+ if (pthread_attr_init(&attr) != 0) {
+ perror ("Error in attribute init\n");
+ }
+
+ /*************** CREATE THREADS ***************/
+
+ status = pthread_create(&ThreadIds[0], NULL, ReaderThread, &l);
+ posix_service_failed( status, "pthread_create Reader" );
+
+ sleep(1);
+
+ status = pthread_create(&ThreadIds[1], NULL, WriterThread, &l);
+ posix_service_failed( status, "pthread_create Writer" );
+
+ sleep(1);
+
+ /*************** ERROR CASES ***************/
+ puts("Call pthread_cleanup_push with NULL handler");
+ pthread_cleanup_push(NULL, NULL);
+
+ puts("Call pthread_cleanup_pop with no push");
+ pthread_cleanup_pop(1);
+
+ /*************** END OF TEST *****************/
+ puts( "*** END OF POSIX CLEANUP TEST ***\n" );
+ rtems_test_exit(0);
+}
+
diff --git a/testsuites/psxtests/psxcleanup/psxcleanup.scn b/testsuites/psxtests/psxcleanup/psxcleanup.scn
new file mode 100644
index 0000000000..23c6a718f6
--- /dev/null
+++ b/testsuites/psxtests/psxcleanup/psxcleanup.scn
@@ -0,0 +1,6 @@
+*** POSIX CLEANUP TEST ***
+Lock for read
+cleanup push for read
+cleanup pop for read
+Lock for write
+*** END OF POSIX CLEANUP TEST ***