aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/ipc_test.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-05-05 16:02:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-05-05 16:02:37 +0000
commit17ea23dd174c9626f4c8ab8e59c5a535cb1fed9c (patch)
tree6d4f8b1223f5f33720ec5b0803de153a51fa4e63 /src/backend/port/ipc_test.c
parent2010a43fcb06ca762a3349e2be666a17a5863740 (diff)
downloadpostgresql-17ea23dd174c9626f4c8ab8e59c5a535cb1fed9c.tar.gz
postgresql-17ea23dd174c9626f4c8ab8e59c5a535cb1fed9c.zip
Add a trivial testbed for pg_sema and pg_shmem code.
Diffstat (limited to 'src/backend/port/ipc_test.c')
-rw-r--r--src/backend/port/ipc_test.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/backend/port/ipc_test.c b/src/backend/port/ipc_test.c
new file mode 100644
index 00000000000..1c137ed3c42
--- /dev/null
+++ b/src/backend/port/ipc_test.c
@@ -0,0 +1,278 @@
+/*-------------------------------------------------------------------------
+ *
+ * ipc_test.c
+ * Simplistic testbed for shared memory and semaphore code.
+ *
+ * This file allows for quick "smoke testing" of a PG semaphore or shared
+ * memory implementation, with less overhead than compiling up a whole
+ * installation. To use:
+ * 1. Run configure, then edit src/include/pg_config.h to select the
+ * USE_xxx_SEMAPHORES and USE_xxx_SHARED_MEMORY settings you want.
+ * Also, adjust the pg_sema.c and pg_shmem.c symlinks in
+ * src/backend/port/ if needed.
+ * 2. In src/backend/port/, do "gmake ipc_test".
+ * 3. Run ipc_test and see if it works.
+ * 4. If it seems to work, try building the whole system and running
+ * the parallel regression tests for a more complete test.
+ *
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/port/ipc_test.c,v 1.1 2002/05/05 16:02:37 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <unistd.h>
+
+#include "miscadmin.h"
+#include "storage/ipc.h"
+#include "storage/pg_sema.h"
+#include "storage/pg_shmem.h"
+#include "utils/exc.h"
+
+
+/********* stuff needed to satisfy references in shmem/sema code *********/
+
+
+volatile bool InterruptPending = false;
+volatile bool QueryCancelPending = false;
+volatile bool ProcDiePending = false;
+volatile bool ImmediateInterruptOK = false;
+volatile uint32 InterruptHoldoffCount = 0;
+volatile uint32 CritSectionCount = 0;
+
+bool IsUnderPostmaster = false;
+
+int MaxBackends = DEF_MAXBACKENDS;
+int NBuffers = DEF_NBUFFERS;
+
+#ifndef assert_enabled
+bool assert_enabled = true;
+#endif
+
+Exception FailedAssertion = {"Failed Assertion"};
+
+
+#define MAX_ON_EXITS 20
+
+static struct ONEXIT
+{
+ void (*function) ();
+ Datum arg;
+} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
+
+static int on_proc_exit_index,
+ on_shmem_exit_index;
+
+void
+proc_exit(int code)
+{
+ shmem_exit(code);
+ while (--on_proc_exit_index >= 0)
+ (*on_proc_exit_list[on_proc_exit_index].function) (code,
+ on_proc_exit_list[on_proc_exit_index].arg);
+ exit(code);
+}
+
+void
+shmem_exit(int code)
+{
+ while (--on_shmem_exit_index >= 0)
+ (*on_shmem_exit_list[on_shmem_exit_index].function) (code,
+ on_shmem_exit_list[on_shmem_exit_index].arg);
+ on_shmem_exit_index = 0;
+}
+
+void
+on_shmem_exit(void (*function) (), Datum arg)
+{
+ if (on_shmem_exit_index >= MAX_ON_EXITS)
+ elog(FATAL, "Out of on_shmem_exit slots");
+
+ on_shmem_exit_list[on_shmem_exit_index].function = function;
+ on_shmem_exit_list[on_shmem_exit_index].arg = arg;
+
+ ++on_shmem_exit_index;
+}
+
+void
+on_exit_reset(void)
+{
+ on_shmem_exit_index = 0;
+ on_proc_exit_index = 0;
+}
+
+void
+RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
+{
+}
+
+void
+ProcessInterrupts(void)
+{
+}
+
+int
+ExceptionalCondition(char *conditionName,
+ Exception *exceptionP,
+ char *detail,
+ char *fileName,
+ int lineNumber)
+{
+ fprintf(stderr, "TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
+ exceptionP->message, conditionName,
+ (detail == NULL ? "" : detail),
+ fileName, lineNumber);
+ abort();
+ return 0;
+}
+
+void
+elog(int lev, const char *fmt,...)
+{
+ if (lev >= ERROR)
+ {
+ fprintf(stderr, "elog(%s)\n", fmt);
+ abort();
+ }
+}
+
+
+/********* here's the actual test *********/
+
+
+typedef struct MyStorage
+{
+ PGShmemHeader header;
+ int flag;
+ PGSemaphoreData sem;
+} MyStorage;
+
+
+int
+main(int argc, char **argv)
+{
+ MyStorage *storage;
+ int cpid;
+
+ printf("Creating shared memory ... ");
+ fflush(stdout);
+
+ storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433);
+
+ storage->flag = 1234;
+
+ printf("OK\n");
+
+ printf("Creating semaphores ... ");
+ fflush(stdout);
+
+ PGReserveSemaphores(2, 5433);
+
+ PGSemaphoreCreate(&storage->sem);
+
+ printf("OK\n");
+
+ /* sema initial value is 1, so lock should work */
+
+ printf("Testing Lock ... ");
+ fflush(stdout);
+
+ PGSemaphoreLock(&storage->sem, false);
+
+ printf("OK\n");
+
+ /* now sema value is 0, so trylock should fail */
+
+ printf("Testing TryLock ... ");
+ fflush(stdout);
+
+ if (PGSemaphoreTryLock(&storage->sem))
+ printf("unexpected result!\n");
+ else
+ printf("OK\n");
+
+ /* unlocking twice and then locking twice should work... */
+
+ printf("Testing Multiple Lock ... ");
+ fflush(stdout);
+
+ PGSemaphoreUnlock(&storage->sem);
+ PGSemaphoreUnlock(&storage->sem);
+
+ PGSemaphoreLock(&storage->sem, false);
+ PGSemaphoreLock(&storage->sem, false);
+
+ printf("OK\n");
+
+ /* check Reset too */
+
+ printf("Testing Reset ... ");
+ fflush(stdout);
+
+ PGSemaphoreUnlock(&storage->sem);
+
+ PGSemaphoreReset(&storage->sem);
+
+ if (PGSemaphoreTryLock(&storage->sem))
+ printf("unexpected result!\n");
+ else
+ printf("OK\n");
+
+ /* Fork a child process and see if it can communicate */
+
+ printf("Forking child process ... ");
+ fflush(stdout);
+
+ cpid = fork();
+ if (cpid == 0)
+ {
+ /* In child */
+ on_exit_reset();
+ sleep(3);
+ storage->flag++;
+ PGSemaphoreUnlock(&storage->sem);
+ proc_exit(0);
+ }
+ if (cpid < 0)
+ {
+ /* Fork failed */
+ printf("failed: %s\n", strerror(errno));
+ proc_exit(1);
+ }
+
+ printf("forked child pid %d OK\n", cpid);
+
+ if (storage->flag != 1234)
+ printf("Wrong value found in shared memory!\n");
+
+ printf("Waiting for child (should wait 3 sec here) ... ");
+ fflush(stdout);
+
+ PGSemaphoreLock(&storage->sem, false);
+
+ printf("OK\n");
+
+ if (storage->flag != 1235)
+ printf("Wrong value found in shared memory!\n");
+
+ /* Test shutdown */
+
+ printf("Running shmem_exit processing ... ");
+ fflush(stdout);
+
+ shmem_exit(0);
+
+ printf("OK\n");
+
+ printf("Tests complete.\n");
+
+ proc_exit(0);
+
+ return 0; /* not reached */
+}