1 /*-------------------------------------------------------------------------
4 * Simplistic testbed for shared memory and semaphore code.
6 * This file allows for quick "smoke testing" of a PG semaphore or shared
7 * memory implementation, with less overhead than compiling up a whole
8 * installation. To use:
9 * 1. Run configure, then edit src/include/pg_config.h to select the
10 * USE_xxx_SEMAPHORES and USE_xxx_SHARED_MEMORY settings you want.
11 * Also, adjust the pg_sema.c and pg_shmem.c symlinks in
12 * src/backend/port/ if needed.
13 * 2. In src/backend/port/, do "gmake ipc_test".
14 * 3. Run ipc_test and see if it works.
15 * 4. If it seems to work, try building the whole system and running
16 * the parallel regression tests for a more complete test.
19 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
20 * Portions Copyright (c) 1994, Regents of the University of California
24 * $Header: /cvsroot/pgsql/src/backend/port/ipc_test.c,v 1.4 2002/08/10 20:29:18 momjian Exp $
26 *-------------------------------------------------------------------------
33 #include "miscadmin.h"
34 #include "storage/ipc.h"
35 #include "storage/pg_sema.h"
36 #include "storage/pg_shmem.h"
39 /********* stuff needed to satisfy references in shmem/sema code *********/
42 volatile bool InterruptPending = false;
43 volatile bool QueryCancelPending = false;
44 volatile bool ProcDiePending = false;
45 volatile bool ImmediateInterruptOK = false;
46 volatile uint32 InterruptHoldoffCount = 0;
47 volatile uint32 CritSectionCount = 0;
49 bool IsUnderPostmaster = false;
51 int MaxBackends = DEF_MAXBACKENDS;
52 int NBuffers = DEF_NBUFFERS;
54 #ifndef assert_enabled
55 bool assert_enabled = true;
59 #define MAX_ON_EXITS 20
65 } on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
67 static int on_proc_exit_index,
74 while (--on_proc_exit_index >= 0)
75 (*on_proc_exit_list[on_proc_exit_index].function) (code,
76 on_proc_exit_list[on_proc_exit_index].arg);
83 while (--on_shmem_exit_index >= 0)
84 (*on_shmem_exit_list[on_shmem_exit_index].function) (code,
85 on_shmem_exit_list[on_shmem_exit_index].arg);
86 on_shmem_exit_index = 0;
90 on_shmem_exit(void (*function) (), Datum arg)
92 if (on_shmem_exit_index >= MAX_ON_EXITS)
93 elog(FATAL, "Out of on_shmem_exit slots");
95 on_shmem_exit_list[on_shmem_exit_index].function = function;
96 on_shmem_exit_list[on_shmem_exit_index].arg = arg;
98 ++on_shmem_exit_index;
104 on_shmem_exit_index = 0;
105 on_proc_exit_index = 0;
109 RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
114 ProcessInterrupts(void)
119 ExceptionalCondition(char *conditionName,
124 fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
125 errorType, conditionName,
126 fileName, lineNumber);
132 elog(int lev, const char *fmt,...)
136 fprintf(stderr, "elog(%s)\n", fmt);
142 /********* here's the actual test *********/
145 typedef struct MyStorage
147 PGShmemHeader header;
154 main(int argc, char **argv)
159 printf("Creating shared memory ... ");
162 storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433);
164 storage->flag = 1234;
168 printf("Creating semaphores ... ");
171 PGReserveSemaphores(2, 5433);
173 PGSemaphoreCreate(&storage->sem);
177 /* sema initial value is 1, so lock should work */
179 printf("Testing Lock ... ");
182 PGSemaphoreLock(&storage->sem, false);
186 /* now sema value is 0, so trylock should fail */
188 printf("Testing TryLock ... ");
191 if (PGSemaphoreTryLock(&storage->sem))
192 printf("unexpected result!\n");
196 /* unlocking twice and then locking twice should work... */
198 printf("Testing Multiple Lock ... ");
201 PGSemaphoreUnlock(&storage->sem);
202 PGSemaphoreUnlock(&storage->sem);
204 PGSemaphoreLock(&storage->sem, false);
205 PGSemaphoreLock(&storage->sem, false);
209 /* check Reset too */
211 printf("Testing Reset ... ");
214 PGSemaphoreUnlock(&storage->sem);
216 PGSemaphoreReset(&storage->sem);
218 if (PGSemaphoreTryLock(&storage->sem))
219 printf("unexpected result!\n");
223 /* Fork a child process and see if it can communicate */
225 printf("Forking child process ... ");
235 PGSemaphoreUnlock(&storage->sem);
241 printf("failed: %s\n", strerror(errno));
245 printf("forked child pid %d OK\n", cpid);
247 if (storage->flag != 1234)
248 printf("Wrong value found in shared memory!\n");
250 printf("Waiting for child (should wait 3 sec here) ... ");
253 PGSemaphoreLock(&storage->sem, false);
257 if (storage->flag != 1235)
258 printf("Wrong value found in shared memory!\n");
262 printf("Running shmem_exit processing ... ");
269 printf("Tests complete.\n");
273 return 0; /* not reached */