Page MenuHomeFreeBSD

D26473.diff
No OneTemporary

D26473.diff

Index: head/contrib/netbsd-tests/lib/libpthread/t_mutex.c
===================================================================
--- head/contrib/netbsd-tests/lib/libpthread/t_mutex.c
+++ head/contrib/netbsd-tests/lib/libpthread/t_mutex.c
@@ -35,6 +35,9 @@
#include <inttypes.h> /* For UINT16_MAX */
#include <pthread.h>
#include <stdio.h>
+#ifdef __FreeBSD__
+#include <stdlib.h>
+#endif
#include <string.h>
#include <errno.h>
#include <time.h>
@@ -128,16 +131,41 @@
PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
}
+#ifdef __FreeBSD__
+/*
+ * Increment the value using a noinline function that includes a small delay
+ * to increase the window for the RMW data race.
+ */
+__noinline static int
+increment(int value)
+{
+ for (volatile int i = 0; i < 100; i++) {
+ /* Small delay between read+write to increase chance of race */
+ __compiler_membar();
+ }
+ return value + 1;
+}
+
+static volatile bool thread2_started = false;
+#endif
+
static void *
mutex2_threadfunc(void *arg)
{
long count = *(int *)arg;
+#ifdef __FreeBSD__
+ thread2_started = true;
+#endif
printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
while (count--) {
PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
+#ifdef __FreeBSD__
+ global_x = increment(global_x);
+#else
global_x++;
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
}
@@ -153,16 +181,13 @@
atf_tc_set_md_var(tc, "timeout", "40");
#endif
#endif
-
-#ifdef __FreeBSD__
-#if defined(__riscv)
- atf_tc_set_md_var(tc, "timeout", "600");
-#endif
-#endif
}
ATF_TC_BODY(mutex2, tc)
{
int count, count2;
+#ifdef __FreeBSD__
+ int num_increments;
+#endif
pthread_t new;
void *joinval;
@@ -177,18 +202,39 @@
PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
global_x = 0;
+#ifdef __FreeBSD__
+ num_increments = count = count2 = 1000;
+ if (getenv("NUM_ITERATIONS") != NULL) {
+ num_increments = count = count2 =
+ MIN(INT_MAX, strtoul(getenv("NUM_ITERATIONS"), NULL, 10));
+ }
+ printf("Will use %d iterations\n", num_increments);
+#else
count = count2 = 10000000;
+#endif
PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
+#ifdef __FreeBSD__
+ thread2_started = false;
+#endif
PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2));
printf("1: Thread %p\n", pthread_self());
-
+#ifdef __FreeBSD__
+ while (!thread2_started) {
+ /* Wait for thread 2 to start to increase chance of race */
+ }
+ printf("1: Unlocking to start increment loop %p\n", pthread_self());
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
while (count--) {
PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
+#ifdef __FreeBSD__
+ global_x = increment(global_x);
+#else
global_x++;
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
}
@@ -197,7 +243,14 @@
PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy));
printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
global_x, (long)joinval);
+#ifdef __FreeBSD__
+ ATF_REQUIRE_EQ_MSG(count, -1, "%d", count);
+ ATF_REQUIRE_EQ_MSG((long)joinval, -1, "%ld", (long)joinval);
+ ATF_REQUIRE_EQ_MSG(global_x, num_increments * 2, "%d vs %d", global_x,
+ num_increments * 2);
+#else
ATF_REQUIRE_EQ(global_x, 20000000);
+#endif
#ifdef __NetBSD__
#if defined(__powerpc__)
@@ -210,16 +263,27 @@
#endif
}
+#ifdef __FreeBSD__
+static volatile bool thread3_started = false;
+#endif
+
static void *
mutex3_threadfunc(void *arg)
{
long count = *(int *)arg;
+#ifdef __FreeBSD__
+ thread3_started = true;
+#endif
printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
while (count--) {
PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
+#ifdef __FreeBSD__
+ global_x = increment(global_x);
+#else
global_x++;
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
}
@@ -236,16 +300,13 @@
atf_tc_set_md_var(tc, "timeout", "40");
#endif
#endif
-
-#ifdef __FreeBSD__
-#if defined(__riscv)
- atf_tc_set_md_var(tc, "timeout", "600");
-#endif
-#endif
}
ATF_TC_BODY(mutex3, tc)
{
int count, count2;
+#ifdef __FreeBSD__
+ int num_increments;
+#endif
pthread_t new;
void *joinval;
@@ -258,18 +319,36 @@
#endif
global_x = 0;
+#ifdef __FreeBSD__
+ num_increments = count = count2 = 1000;
+ if (getenv("NUM_ITERATIONS") != NULL) {
+ num_increments = count = count2 =
+ MIN(INT_MAX, strtoul(getenv("NUM_ITERATIONS"), NULL, 10));
+ }
+ printf("Will use %d iterations\n", num_increments);
+#else
count = count2 = 10000000;
+#endif
PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2));
printf("1: Thread %p\n", pthread_self());
-
+#ifdef __FreeBSD__
+ while (!thread3_started) {
+ /* Wait for thread 3 to start to increase chance of race */
+ }
+ printf("1: Unlocking to start increment loop %p\n", pthread_self());
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
while (count--) {
PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
+#ifdef __FreeBSD__
+ global_x = increment(global_x);
+#else
global_x++;
+#endif
PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
}
@@ -278,8 +357,14 @@
PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy));
printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
global_x, (long)joinval);
+#ifdef __FreeBSD__
+ ATF_REQUIRE_EQ_MSG(count, -1, "%d", count);
+ ATF_REQUIRE_EQ_MSG((long)joinval, -1, "%ld", (long)joinval);
+ ATF_REQUIRE_EQ_MSG(global_x, num_increments * 2, "%d vs %d", global_x,
+ num_increments * 2);
+#else
ATF_REQUIRE_EQ(global_x, 20000000);
-
+#endif
#ifdef __NetBSD__
#if defined(__powerpc__)
/* XXX force a timeout in ppc case since an un-triggered race

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 7, 4:54 AM (17 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17024674
Default Alt Text
D26473.diff (5 KB)

Event Timeline