diff --git a/src/bin/pgbench/.gitignore b/src/bin/pgbench/.gitignore index aae819e..983a3cd 100644 --- a/src/bin/pgbench/.gitignore +++ b/src/bin/pgbench/.gitignore @@ -1,3 +1,4 @@ /exprparse.c /exprscan.c /pgbench +/tmp_check/ diff --git a/src/bin/pgbench/Makefile b/src/bin/pgbench/Makefile index 18fdf58..e9b1b74 100644 --- a/src/bin/pgbench/Makefile +++ b/src/bin/pgbench/Makefile @@ -40,3 +40,9 @@ clean distclean: maintainer-clean: distclean rm -f exprparse.c exprscan.c + +check: + $(prove_check) + +installcheck: + $(prove_installcheck) diff --git a/src/bin/pgbench/t/001_pgbench.pl b/src/bin/pgbench/t/001_pgbench.pl new file mode 100644 index 0000000..88e83ab --- /dev/null +++ b/src/bin/pgbench/t/001_pgbench.pl @@ -0,0 +1,25 @@ +use strict; +use warnings; + +use PostgresNode; +use TestLib; +use Test::More tests => 3; + +# Test concurrent insertion into table with UNIQUE oid column. DDL expects +# GetNewOidWithIndex() to successfully avoid violating uniqueness for indexes +# like pg_class_oid_index and pg_proc_oid_index. This indirectly exercises +# LWLock and spinlock concurrency. This test makes a 5-MiB table. +my $node = get_new_node('main'); +$node->init; +$node->start; +$node->psql('postgres', + 'CREATE UNLOGGED TABLE oid_tbl () WITH OIDS; ' + . 'ALTER TABLE oid_tbl ADD UNIQUE (oid);'); +my $script = $node->basedir . '/pgbench_script'; +append_to_file($script, + 'INSERT INTO oid_tbl SELECT FROM generate_series(1,1000);'); +$node->command_like( + [ qw(pgbench --no-vacuum --client=5 --protocol=prepared + --transactions=25 --file), $script ], + qr{processed: 125/125}, + 'concurrent OID generation'); diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h index 1e8a11e..f24e3af 100644 --- a/src/include/port/atomics/generic-xlc.h +++ b/src/include/port/atomics/generic-xlc.h @@ -41,18 +41,22 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval) { /* + * XXX: __compare_and_swap is defined to take signed parameters, but that + * shouldn't matter since we don't perform any arithmetic operations. + */ + bool ret = __compare_and_swap((volatile int*)&ptr->value, + (int *)expected, (int)newval); + + /* * xlc's documentation tells us: * "If __compare_and_swap is used as a locking primitive, insert a call to * the __isync built-in function at the start of any critical sections." + * + * The critical section begins immediately after __compare_and_swap(). */ __isync(); - /* - * XXX: __compare_and_swap is defined to take signed parameters, but that - * shouldn't matter since we don't perform any arithmetic operations. - */ - return __compare_and_swap((volatile int*)&ptr->value, - (int *)expected, (int)newval); + return ret; } #define PG_HAVE_ATOMIC_FETCH_ADD_U32 @@ -69,10 +73,12 @@ static inline bool pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval) { + bool ret = __compare_and_swaplp((volatile long*)&ptr->value, + (long *)expected, (long)newval); + __isync(); - return __compare_and_swaplp((volatile long*)&ptr->value, - (long *)expected, (long)newval);; + return ret; } #define PG_HAVE_ATOMIC_FETCH_ADD_U64 diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat index feb0fe5..d21692f 100755 --- a/src/tools/msvc/clean.bat +++ b/src/tools/msvc/clean.bat @@ -94,6 +94,7 @@ if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_chec if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check +if exist src\bin\pgbench\tmp_check rd /s /q src\bin\pgbench\tmp_check if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check REM Clean up datafiles built with contrib