|
From: <sv...@va...> - 2006-12-06 06:32:43
|
Author: njn
Date: 2006-12-06 06:32:37 +0000 (Wed, 06 Dec 2006)
New Revision: 6379
Log:
Add a regression test, courtesy of Bart Van Assche.
Added:
trunk/none/tests/pth_detached.c
trunk/none/tests/pth_detached.stderr.exp
trunk/none/tests/pth_detached.stdout.exp
trunk/none/tests/pth_detached.vgtest
Modified:
trunk/none/tests/Makefile.am
Modified: trunk/none/tests/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/Makefile.am 2006-12-06 03:36:24 UTC (rev 6378)
+++ trunk/none/tests/Makefile.am 2006-12-06 06:32:37 UTC (rev 6379)
@@ -95,6 +95,8 @@
pth_rwlock.stderr.exp pth_rwlock.vgtest \
pth_stackalign.stderr.exp \
pth_stackalign.stdout.exp pth_stackalign.vgtest \
+ pth_detached.stderr.exp \
+ pth_detached.stdout.exp pth_detached.vgtest \
rcrl.stderr.exp rcrl.stdout.exp rcrl.vgtest \
readline1.stderr.exp readline1.stdout.exp \
readline1.vgtest \
@@ -146,6 +148,7 @@
pth_atfork1 pth_blockedsig pth_cancel1 pth_cancel2 pth_cvsimple \
pth_empty pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \
pth_stackalign \
+ pth_detached \
rcrl readline1 res_search resolv \
rlimit_nofile selfrun sem semlimit sha1_test \
shortpush shorts stackgrowth sigstackgrowth susphello \
@@ -175,6 +178,7 @@
pth_once_LDADD =3D -lpthread
pth_rwlock_LDADD =3D -lpthread
pth_stackalign_LDADD =3D -lpthread
+pth_detached_LDADD =3D -lpthread
if VGP_PPC32_AIX5
res_search_LDADD =3D -lpthread
else
Added: trunk/none/tests/pth_detached.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/pth_detached.c (rev 0)
+++ trunk/none/tests/pth_detached.c 2006-12-06 06:32:37 UTC (rev 6379)
@@ -0,0 +1,68 @@
+/* Test whether detached threads are handled properly.
+ Contributed by Bart Van Assche (bar...@gm...).
+*/
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int s_finished_count;
+
+static void* thread_func1(void* arg)
+{
+ write(STDOUT_FILENO, ".", 1);
+ s_finished_count++;
+ return 0;
+}
+
+static void* thread_func2(void* arg)
+{
+ pthread_detach(pthread_self());
+ write(STDOUT_FILENO, "*", 1);
+ s_finished_count++;
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ const int count1 =3D argc > 1 ? atoi(argv[1]) : 100;
+ const int count2 =3D argc > 2 ? atoi(argv[2]) : 100;
+ int i;
+ int detachstate;
+ pthread_attr_t attr;
+ =20
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ assert(pthread_attr_getdetachstate(&attr, &detachstate) =3D=3D 0);
+ assert(detachstate =3D=3D PTHREAD_CREATE_DETACHED);
+ pthread_attr_setstacksize(&attr, 16384);
+ // Create count1 detached threads by setting the "detached" property v=
ia=20
+ // thread attributes.
+ for (i =3D 0; i < count1; i++)
+ {
+ pthread_t thread;
+ pthread_create(&thread, &attr, thread_func1, 0);
+ }
+ // Create count2 detached threads by letting the threads detach themse=
lves.
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ assert(pthread_attr_getdetachstate(&attr, &detachstate) =3D=3D 0);
+ assert(detachstate =3D=3D PTHREAD_CREATE_JOINABLE);
+ for (i =3D 0; i < count2; i++)
+ {
+ pthread_t thread;
+ pthread_create(&thread, &attr, thread_func2, 0);
+ }
+ pthread_attr_destroy(&attr);
+
+ // Wait until all detached threads have written their output to stdout=
.
+ while (s_finished_count < count1 + count2)
+ {
+ struct timespec delay =3D { 0, 1 * 1000 * 1000 };
+ nanosleep(&delay, 0);
+ }
+
+ printf("\n");
+ return 0;
+}
Added: trunk/none/tests/pth_detached.stderr.exp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/pth_detached.stderr.exp (rev=
0)
+++ trunk/none/tests/pth_detached.stderr.exp 2006-12-06 06:32:37 UTC (rev=
6379)
@@ -0,0 +1,2 @@
+
+
Added: trunk/none/tests/pth_detached.stdout.exp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/pth_detached.stdout.exp (rev=
0)
+++ trunk/none/tests/pth_detached.stdout.exp 2006-12-06 06:32:37 UTC (rev=
6379)
@@ -0,0 +1 @@
+........................................................................=
............................*********************************************=
*******************************************************
Added: trunk/none/tests/pth_detached.vgtest
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/none/tests/pth_detached.vgtest (rev 0)
+++ trunk/none/tests/pth_detached.vgtest 2006-12-06 06:32:37 UTC (rev 637=
9)
@@ -0,0 +1 @@
+prog: pth_detached
|
|
From: Julian S. <js...@ac...> - 2006-12-11 23:18:35
|
> New Revision: 6379 > > Log: > Add a regression test, courtesy of Bart Van Assche. > > Added: > trunk/none/tests/pth_detached.c Am trying to figure out why this doesn't always work reliably on a 16-way SMP. Bart, isn't there a race on 's_finished_count' here? Also, the expected stdout is a sequence of '.' followed by a sequence of '*'. But I couldn't see from the test anything that guarantees the first group of threads will print their character before any of the second group of threads do. Did I miss something? J |
|
From: Bart V. A. <bar...@gm...> - 2006-12-12 08:57:25
|
On 12/12/06, Julian Seward <js...@ac...> wrote: > > > Added: > > trunk/none/tests/pth_detached.c > > Am trying to figure out why this doesn't always work reliably on a > 16-way SMP. > > Bart, isn't there a race on 's_finished_count' here? > > Also, the expected stdout is a sequence of '.' followed by a sequence > of '*'. But I couldn't see from the test anything that guarantees the > first group of threads will print their character before any of the > second group of threads do. Did I miss something? Your observations are right -- I wasn't aware that regression tests were also run on SMP-systems. The first issue can be solved by letting thread_func2() also print a dot instead of a star (and updating stdout.exp). Regarding the second issue: there is indeed a race on s_finished_count. IMHO chances are small that the race on s_finished_count will cause trouble on SMP systems -- should I solve this one ? |
|
From: Bart V. A. <bar...@gm...> - 2006-12-12 09:22:48
|
The following patch should solve the SMP-issues in none/tests/pth_detached.c:
Index: none/tests/pth_detached.stdout.exp
===================================================================
--- none/tests/pth_detached.stdout.exp (revision 6394)
+++ none/tests/pth_detached.stdout.exp (working copy)
@@ -1 +1 @@
-..........................................................................................
..........*********************************************************************************
*******************
+..........................................................................................
...........................................................................................
...................
Index: none/tests/pth_detached.c
===================================================================
--- none/tests/pth_detached.c (revision 6394)
+++ none/tests/pth_detached.c (working copy)
@@ -9,19 +9,36 @@
#include <unistd.h>
static int s_finished_count;
+static pthread_spinlock_t s_spinlock;
+void increment_finished_count()
+{
+ pthread_spin_lock(&s_spinlock);
+ s_finished_count++;
+ pthread_spin_unlock(&s_spinlock);
+}
+
+int get_finished_count()
+{
+ int result;
+ pthread_spin_lock(&s_spinlock);
+ result = s_finished_count;
+ pthread_spin_unlock(&s_spinlock);
+ return result;
+}
+
static void* thread_func1(void* arg)
{
write(STDOUT_FILENO, ".", 1);
- s_finished_count++;
+ increment_finished_count();
return 0;
}
static void* thread_func2(void* arg)
{
pthread_detach(pthread_self());
- write(STDOUT_FILENO, "*", 1);
- s_finished_count++;
+ write(STDOUT_FILENO, ".", 1);
+ increment_finished_count();
return 0;
}
@@ -32,6 +49,8 @@
int i;
int detachstate;
pthread_attr_t attr;
+
+ pthread_spin_init(&s_spinlock, 0);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
@@ -57,12 +76,15 @@
pthread_attr_destroy(&attr);
// Wait until all detached threads have written their output to stdout.
- while (s_finished_count < count1 + count2)
+ while (get_finished_count() < count1 + count2)
{
struct timespec delay = { 0, 1 * 1000 * 1000 };
nanosleep(&delay, 0);
}
printf("\n");
+
+ pthread_spin_destroy(&s_spinlock);
+
return 0;
}
|