0003-B.patch
application/octet-stream
Filename: 0003-B.patch
Type: application/octet-stream
Part: 2
Patch
Format: format-patch
Series: patch 0003
Subject: B
| File | + | − |
|---|---|---|
| src/bin/pgbench/pgbench.c | 30 | 5 |
From 79efa2073b4345ae95b9336412ee328ab2695df1 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 2 Jan 2021 14:13:28 +1300
Subject: [PATCH 3/3] B
---
src/bin/pgbench/pgbench.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index b8a3e28690..d0970d15ba 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -120,15 +120,18 @@ typedef int pthread_attr_t;
static int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
static int pthread_join(pthread_t th, void **thread_return);
+#include "port/pg_pthread.h"
#elif defined(ENABLE_THREAD_SAFETY)
-/* Use platform-dependent pthread capability */
-#include <pthread.h>
+#include "port/pg_pthread.h"
#else
/* No threads implementation, use none (-j 1) */
#define pthread_t void *
+#define pthread_barrier_t void *
+#define pthread_barrier_init(a, b, c) /* ignore */
+#define pthread_barrier_wait(a) /* ignore */
+#define pthread_barrier_destroy(a) /* ignore */
#endif
-
/********************************************************************
* some configurable parameters */
@@ -311,6 +314,9 @@ typedef struct RandomState
/* Various random sequences are initialized from this one. */
static RandomState base_random_sequence;
+/* Synchronization barrier for start and connection */
+static pthread_barrier_t barrier;
+
/*
* Connection state machine states.
*/
@@ -454,8 +460,8 @@ typedef struct
/* per thread collected stats in microseconds */
pg_time_usec_t create_time; /* thread creation time */
- pg_time_usec_t started_time; /* thread is running */
- pg_time_usec_t bench_start; /* thread is benchmarking */
+ pg_time_usec_t started_time; /* thread is running after start barrier */
+ pg_time_usec_t bench_start; /* thread is benchmarking after connection barrier */
pg_time_usec_t conn_duration; /* cumulated connection and deconnection delays */
StatsData stats;
@@ -6111,6 +6117,8 @@ main(int argc, char **argv)
if (duration > 0)
setalarm(duration);
+ pthread_barrier_init(&barrier, NULL, nthreads);
+
#ifdef ENABLE_THREAD_SAFETY
/* start all threads but thread 0 which is executed directly later */
for (i = 1; i < nthreads; i++)
@@ -6182,6 +6190,8 @@ main(int argc, char **argv)
printResults(&stats, pg_time_now() - bench_start, conn_total_duration,
bench_start - start_time, latency_late);
+ pthread_barrier_destroy(&barrier);
+
if (exit_code != 0)
pg_log_fatal("Run was aborted; the above results are incomplete.");
@@ -6228,6 +6238,8 @@ threadRun(void *arg)
state[i].state = CSTATE_CHOOSE_SCRIPT;
/* READY */
+ pthread_barrier_wait(&barrier);
+
thread_start = pg_time_now();
thread->started_time = thread_start;
last_report = thread_start;
@@ -6240,7 +6252,18 @@ threadRun(void *arg)
for (int i = 0; i < nstate; i++)
{
if ((state[i].con = doConnect()) == NULL)
+ {
+ /*
+ * On connection failure, we meet the barrier here in place of
+ * GO before proceeding to the "done" path which will cleanup,
+ * so as to avoid locking the process.
+ *
+ * It is unclear whether it is worth doing anything rather than
+ * coldly exiting with an error message.
+ */
+ pthread_barrier_wait(&barrier);
goto done;
+ }
}
/* compute connection delay */
@@ -6252,6 +6275,8 @@ threadRun(void *arg)
thread->conn_duration = 0;
}
+ /* GO */
+ pthread_barrier_wait(&barrier);
start = pg_time_now();
thread->bench_start = start;
--
2.24.3 (Apple Git-128)