]> granicus.if.org Git - postgresql/commitdiff
Add a trivial testbed for pg_sema and pg_shmem code.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 5 May 2002 16:02:37 +0000 (16:02 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 5 May 2002 16:02:37 +0000 (16:02 +0000)
src/backend/port/Makefile
src/backend/port/ipc_test.c [new file with mode: 0644]

index 1370cdbb78ba941431fbdfc8dca9bae241e3d451..6979cf197392246043cf7c35a335dfce447df917 100644 (file)
@@ -13,7 +13,7 @@
 # be converted to Method 2.  
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.12 2002/05/05 00:03:28 tgl Exp $
+#    $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.13 2002/05/05 16:02:37 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -25,7 +25,7 @@ OBJS = dynloader.o pg_sema.o pg_shmem.o
 
 OBJS += $(GETHOSTNAME) $(GETRUSAGE) $(INET_ATON) $(ISINF) $(MEMCMP) \
         $(MISSING_RANDOM) $(SNPRINTF) $(SRANDOM) $(STRCASECMP) $(STRERROR) \
-        $(STRTOL) $(STRTOUL) $(SNPRINTF)
+        $(STRTOL) $(STRTOUL)
 
 OBJS += $(TAS)
 
@@ -68,8 +68,12 @@ darwin.dir:
 tas.o: tas.s
        $(CC) $(CFLAGS) -c $<
 
+# IPC test program
+ipc_test: ipc_test.o pg_sema.o pg_shmem.o $(MEMCMP) $(SNPRINTF) $(STRERROR)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(export_dynamic) $^ $(LIBS) -o $@
+
 distclean clean:
-       rm -f SUBSYS.o $(OBJS)
+       rm -f SUBSYS.o $(OBJS) ipc_test ipc_test.o
        $(MAKE) -C beos clean
        $(MAKE) -C darwin clean
        $(MAKE) -C qnx4 clean
diff --git a/src/backend/port/ipc_test.c b/src/backend/port/ipc_test.c
new file mode 100644 (file)
index 0000000..1c137ed
--- /dev/null
@@ -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 */
+}