Permalink
Browse files

added test case sequence2 for proving fix for monolithic bundling of …

…test cases:

the monolithic test case bundle fails when running sequence1 and reuse1 when other tests have been executed in the same process before either of these; the test bundle does not fail in these test cases when these are executed at start of run (you can only do this for one of them) - turns out to be due to the thread reuse logic kicking in and the test code not anticipating that
	  -->
introduction of test sequence2.c to showcase the fix for this, including augmentation of pthread_win32_process_attach_np() to prevent crashes.
  • Loading branch information...
1 parent 8039228 commit 321adcd88b11b2fe6aaeaee03805e0a4a6d55df4 @GerHobbelt committed Jul 20, 2011
Showing with 281 additions and 8 deletions.
  1. +9 −0 ptw32_processTerminate.c
  2. +4 −0 tests/Debug.2008.vcproj
  3. +228 −0 tests/sequence2.c
  4. +40 −8 tests/wrapper4tests_1.c
View
@@ -97,8 +97,17 @@ ptw32_processTerminate (void)
tp = tpNext;
}
+ ptw32_threadReuseTop = PTW32_THREAD_REUSE_EMPTY;
+ ptw32_threadReuseBottom = PTW32_THREAD_REUSE_EMPTY;
+
ptw32_mcs_lock_release(&node);
+ /* ptw32_cond_list_head = NULL; */
+ /* ptw32_cond_list_tail = NULL; */
+
+ /* reset the thread sequence number. */
+ ptw32_threadSeqNumber = 0;
+
ptw32_processInitialized = PTW32_FALSE;
}
View
@@ -1180,6 +1180,10 @@
>
</File>
<File
+ RelativePath=".\sequence2.c"
+ >
+ </File>
+ <File
RelativePath=".\sizes.c"
>
</File>
View
@@ -0,0 +1,228 @@
+/*
+ * File: sequence1.c
+ *
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
+ *
+ * Contact Email: rpj@callisto.canberra.edu.au
+ *
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Test Synopsis:
+ * - that unique thread sequence numbers are generated.
+ * - Analyse thread struct reuse.
+ *
+ * Test Method (Validation or Falsification):
+ * -
+ *
+ * Requirements Tested:
+ * -
+ *
+ * Features Tested:
+ * -
+ *
+ * Cases Tested:
+ * -
+ *
+ * Description:
+ * -
+ *
+ * Environment:
+ * - This test is implementation specific
+ * because it uses knowledge of internals that should be
+ * opaque to an application.
+ *
+ * Input:
+ * - None.
+ *
+ * Output:
+ * - File name, Line number, and failed expression on failure.
+ * - analysis output on success.
+ *
+ * Assumptions:
+ * -
+ *
+ * Pass Criteria:
+ * - unique sequence numbers are generated for every new thread.
+ *
+ * Fail Criteria:
+ * -
+ */
+
+#include "test.h"
+#include "implement.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ */
+
+#define PTW_ASSERT(expr) \
+ if (ptw_assert((expr), #expr, __FILE__, __LINE__)) \
+ { \
+ return 1; \
+ }
+
+enum {
+ NUMTHREADS = 20000
+};
+
+
+static long done = 0;
+/*
+ * seqmap should have 1 in every element except [0]
+ * Thread sequence numbers start at 1 and we will also
+ * include this main thread so we need NUMTHREADS+2
+ * elements.
+ */
+static UINT64 seqmap[NUMTHREADS+2];
+
+static ptw_assert(int boolean_expr, const char *expr_str, const char *fname, int lineno)
+{
+ if (!boolean_expr)
+ {
+ const char *p;
+
+ p = strrchr(fname, '/');
+ if (!p)
+ {
+ p = strrchr(fname, '\\');
+ }
+ if (!p)
+ {
+ p = fname;
+ }
+ else
+ {
+ p++;
+ }
+ fprintf(stderr, "[%s @ line %d] ASSERT failed: %s\n", p, lineno, expr_str);
+ }
+ return !boolean_expr;
+}
+
+static int seqmap_set_value = 1;
+
+static void * func(void * arg)
+{
+ sched_yield();
+ if (seqmap_set_value)
+ {
+ /*
+ * [i_a] here we use the reuse link list internals, so worst case
+ * we'll have more then NUMTHREADS+2 threads used before
+ * we went in here (when this test is part of a 'monolithic'
+ * test app), so we apply a modulo to the sequence number
+ * to prevent out-of-bounds array addressing of seqmap[].
+ */
+ seqmap[(int)pthread_getunique_np(pthread_self()) % (NUMTHREADS+2)]++;
+ }
+ InterlockedIncrement(&done);
+
+ return (void *) 0;
+}
+
+static int run_a_sequence(int numthreads)
+{
+ pthread_t t[NUMTHREADS];
+ pthread_attr_t attr;
+ int i;
+
+ assert(pthread_attr_init(&attr) == 0);
+ assert(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0);
+
+ for (i = 0; i < NUMTHREADS+2; i++)
+ {
+ seqmap[i] = 0;
+ }
+
+ for (i = 0; i < numthreads; i++)
+ {
+ if (numthreads/2 == i)
+ {
+ /* Include this main thread, which will be an implicit pthread_t */
+ if (seqmap_set_value)
+ {
+ seqmap[(int)pthread_getunique_np(pthread_self()) % (NUMTHREADS+2)]++;
+ }
+ }
+ PTW_ASSERT(pthread_create(&t[i], &attr, func, NULL) == 0);
+ }
+
+ while (numthreads > InterlockedExchangeAdd((LPLONG)&done, 0L))
+ Sleep(100);
+
+ Sleep(100);
+
+ PTW_ASSERT(seqmap[0] == 0);
+ for (i = 1; i < numthreads+2; i++)
+ {
+ PTW_ASSERT(seqmap[i] == seqmap_set_value);
+ }
+ for ( ; i < NUMTHREADS+2; i++)
+ {
+ PTW_ASSERT(seqmap[i] == 0);
+ }
+
+ return 0;
+}
+
+#ifndef MONOLITHIC_PTHREAD_TESTS
+int
+main()
+#else
+int
+test_sequence2(void)
+#endif
+{
+ printf("phase 1: pollute reuse linked list, i.e. fill it!\n");
+ fflush(stdout);
+
+ seqmap_set_value = 0;
+ assert(0 == run_a_sequence(NUMTHREADS));
+
+ printf("phase 2: notice the reuse linked list trigger a fault\n");
+ printf(" NOTE: the next ASSERT is EXPECTED!\n");
+ fflush(stdout);
+
+ seqmap_set_value = 1;
+ assert(1 == run_a_sequence(NUMTHREADS / 2));
+
+ printf("phase 3: clean the reuse linked list and verify the cleaning\n");
+ fflush(stdout);
+
+ pthread_win32_process_detach_np(); // ptw32_processTerminate();
+ pthread_win32_process_attach_np(); // ptw32_processInitialize();
+
+ seqmap_set_value = 1;
+ assert(0 == run_a_sequence(NUMTHREADS / 2));
+
+ return 0;
+}
View
@@ -2,6 +2,9 @@
Ger Hobbelt ([i_a]) : wrapper code for multiple pthreads library tests; for use with MSVC2003/5 project.
*/
+#include "pthread.h"
+
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -146,6 +149,7 @@ int test_semaphore4(void);
int test_semaphore4t(void);
int test_semaphore5(void);
int test_sequence1(void);
+int test_sequence2(void);
int test_sizes(void);
int test_spin1(void);
int test_spin2(void);
@@ -224,6 +228,34 @@ int main(int argc, char **argv)
atexit(&exit_handler);
+ TEST_WRAPPER(test_sequence2);
+
+ pthread_win32_process_detach_np(); // ptw32_processTerminate();
+ pthread_win32_process_attach_np(); // ptw32_processInitialize();
+ /*
+ fails when run down below; does not fail when run at start of run - turns out to be
+ due to the thread reuse logic kicking in and the test code not anticipating that
+ -->
+ introduction of test sequence2.c above to showcase the fix for this, including
+ augmentation of pthread_win32_process_attach_np() to prevent crashes.
+ */
+ TEST_WRAPPER(test_reuse1);
+
+ pthread_win32_process_detach_np(); // ptw32_processTerminate();
+ pthread_win32_process_attach_np(); // ptw32_processInitialize();
+ TEST_WRAPPER(test_sequence1); /* fails when run down below; does not fail when run at start of run - same issue as test reuse1 */
+
+ pthread_win32_process_detach_np(); // ptw32_processTerminate();
+ pthread_win32_process_attach_np(); // ptw32_processInitialize();
+ TEST_WRAPPER(test_cancel7);
+// TEST_WRAPPER(test_cancel8);
+ TEST_WRAPPER(test_cleanup1);
+ TEST_WRAPPER(test_condvar7);
+ TEST_WRAPPER(test_condvar9);
+ TEST_WRAPPER(test_exception1);
+// TEST_WRAPPER(test_loadfree);
+// TEST_WRAPPER(test_sequence1);
+
TEST_WRAPPER(test_barrier1);
TEST_WRAPPER(test_barrier2);
TEST_WRAPPER(test_barrier3);
@@ -242,11 +274,11 @@ int main(int argc, char **argv)
TEST_WRAPPER(test_cancel5);
TEST_WRAPPER(test_cancel6a);
TEST_WRAPPER(test_cancel6d);
- TEST_WRAPPER(test_cancel7);
- TEST_WRAPPER(test_cancel8);
+// TEST_WRAPPER(test_cancel7);
+// TEST_WRAPPER(test_cancel8);
TEST_WRAPPER(test_cancel9);
TEST_WRAPPER(test_cleanup0);
- TEST_WRAPPER(test_cleanup1);
+// TEST_WRAPPER(test_cleanup1);
TEST_WRAPPER(test_cleanup2);
TEST_WRAPPER(test_cleanup3);
TEST_WRAPPER(test_condvar1);
@@ -261,9 +293,9 @@ int main(int argc, char **argv)
TEST_WRAPPER(test_condvar4);
TEST_WRAPPER(test_condvar5);
TEST_WRAPPER(test_condvar6);
- TEST_WRAPPER(test_condvar7);
+// TEST_WRAPPER(test_condvar7);
TEST_WRAPPER(test_condvar8);
- TEST_WRAPPER(test_condvar9);
+// TEST_WRAPPER(test_condvar9);
TEST_WRAPPER(test_context1);
TEST_WRAPPER(test_count1);
TEST_WRAPPER(test_create1);
@@ -273,7 +305,7 @@ int main(int argc, char **argv)
TEST_WRAPPER(test_detach1);
TEST_WRAPPER(test_equal1);
TEST_WRAPPER(test_errno1);
- TEST_WRAPPER(test_exception1);
+// TEST_WRAPPER(test_exception1);
TEST_WRAPPER(test_exception3);
TEST_WRAPPER(test_exit2);
TEST_WRAPPER(test_exit3);
@@ -286,7 +318,7 @@ int main(int argc, char **argv)
TEST_WRAPPER(test_join2);
TEST_WRAPPER(test_join3);
TEST_WRAPPER(test_kill1);
- TEST_WRAPPER(test_loadfree);
+// TEST_WRAPPER(test_loadfree);
TEST_WRAPPER(test_mutex1);
TEST_WRAPPER(test_mutex1e);
TEST_WRAPPER(test_mutex1n);
@@ -350,7 +382,7 @@ int main(int argc, char **argv)
TEST_WRAPPER(test_semaphore4);
TEST_WRAPPER(test_semaphore4t);
TEST_WRAPPER(test_semaphore5);
- TEST_WRAPPER(test_sequence1);
+// TEST_WRAPPER(test_sequence1);
TEST_WRAPPER(test_sizes);
TEST_WRAPPER(test_spin1);
TEST_WRAPPER(test_spin2);

0 comments on commit 321adcd

Please sign in to comment.