diff --git a/src/test/modules/foo/Makefile b/src/test/modules/foo/Makefile
new file mode 100644
index 0000000..da13e65
--- /dev/null
+++ b/src/test/modules/foo/Makefile
@@ -0,0 +1,18 @@
+# src/test/modules/foo/Makefile
+
+MODULES = foo
+
+EXTENSION = foo
+DATA = foo--1.0.sql
+PGFILEDESC = "foo -- a random testing/hacking extension"
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/foo
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/foo/foo--1.0.sql b/src/test/modules/foo/foo--1.0.sql
new file mode 100644
index 0000000..6914e8a
--- /dev/null
+++ b/src/test/modules/foo/foo--1.0.sql
@@ -0,0 +1,8 @@
+\echo Use "CREATE EXTENSION foo" to load this file. \quit
+
+CREATE FUNCTION barrier_test(workers int, loops int, impl int)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+
diff --git a/src/test/modules/foo/foo.c b/src/test/modules/foo/foo.c
new file mode 100644
index 0000000..bd267a2
--- /dev/null
+++ b/src/test/modules/foo/foo.c
@@ -0,0 +1,118 @@
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "funcapi.h"
+#include "miscadmin.h"
+#include "postmaster/bgworker.h"
+#include "storage/barrier.h"
+#include "storage/dsm.h"
+#include "storage/proc.h"
+#include "utils/builtins.h"
+#include "utils/resowner.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(barrier_test);
+
+extern Datum barrier_test_main(Datum);
+
+typedef struct barrier_test_state
+{
+	int loops;
+	int impl;
+	Barrier barrier;
+} barrier_test_state;
+
+Datum
+barrier_test_main(Datum arg)
+{
+	dsm_segment *segment;
+	barrier_test_state *state;
+	int i;
+
+	BackgroundWorkerUnblockSignals();
+
+	CurrentResourceOwner = ResourceOwnerCreate(NULL, "barrier_test_main toplevel");
+
+	segment = dsm_attach(DatumGetInt32(arg));
+	state = (barrier_test_state *) dsm_segment_address(segment);
+
+	switch (state->impl)
+	{
+	case 0:
+		/* Use barrier.c. */
+		for (i = 0; i < state->loops; ++i)
+			BarrierWait(&state->barrier);
+		break;
+
+	case 1:
+		/* Insert semaphore-based barrier loop here! */
+		break;
+	}
+
+	dsm_detach(segment);
+
+	return (Datum) 0;
+}
+
+Datum
+barrier_test(PG_FUNCTION_ARGS)
+{
+	int workers = PG_GETARG_INT32(0);
+	int loops = PG_GETARG_INT32(1);
+	int impl = PG_GETARG_INT32(2);
+	BackgroundWorkerHandle **handles;
+	barrier_test_state *state;
+	dsm_segment *segment;
+	int i;
+
+	handles = palloc(sizeof(BackgroundWorkerHandle *) * workers);
+
+	/* Set up basic state. */
+	segment = dsm_create(sizeof(barrier_test_state), 0);
+	state = (barrier_test_state *) dsm_segment_address(segment);
+	state->loops = loops;
+	state->impl = impl;
+
+	/* Set up per-implementation state. */
+	switch (impl)
+	{
+	case 0:
+		BarrierInit(&state->barrier, workers);
+		break;
+	case 1:
+		/* Initialize semaphore-based version here. */
+		break;
+	default:
+		elog(ERROR, "unknown impl");
+	}
+
+	/* Start workers. */
+	for (i = 0; i < workers; ++i)
+	{
+		BackgroundWorker bgw;
+
+		snprintf(bgw.bgw_name, sizeof(bgw.bgw_name), "worker%d", i);
+		bgw.bgw_flags = BGWORKER_SHMEM_ACCESS;
+		bgw.bgw_start_time = BgWorkerStart_PostmasterStart;
+		bgw.bgw_restart_time = BGW_NEVER_RESTART;
+		bgw.bgw_main = NULL;
+		snprintf(bgw.bgw_library_name, sizeof(bgw.bgw_library_name),
+				 "foo");
+		snprintf(bgw.bgw_function_name, sizeof(bgw.bgw_function_name),
+				 "barrier_test_main");
+		bgw.bgw_main_arg = Int32GetDatum(dsm_segment_handle(segment));
+		bgw.bgw_notify_pid = MyProcPid;
+
+		if (!RegisterDynamicBackgroundWorker(&bgw, &handles[i]))
+			elog(ERROR, "Can't start worker");
+	}
+
+	/* Wait for workers to complete. */
+	for (i = 0; i < workers; ++i)
+		WaitForBackgroundWorkerShutdown(handles[i]);
+
+	dsm_detach(segment);
+
+	return (Datum) 0;
+}
diff --git a/src/test/modules/foo/foo.control b/src/test/modules/foo/foo.control
new file mode 100644
index 0000000..af1b50a
--- /dev/null
+++ b/src/test/modules/foo/foo.control
@@ -0,0 +1,4 @@
+comment = 'foo'
+default_version = '1.0'
+module_pathname = '$libdir/foo'
+relocatable = true
