Skip to content

Commit 17ea23d

Browse files
committed
Add a trivial testbed for pg_sema and pg_shmem code.
1 parent 2010a43 commit 17ea23d

File tree

2 files changed

+285
-3
lines changed

2 files changed

+285
-3
lines changed

src/backend/port/Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# be converted to Method 2.
1414
#
1515
# IDENTIFICATION
16-
# $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.12 2002/05/05 00:03:28 tgl Exp $
16+
# $Header: /cvsroot/pgsql/src/backend/port/Makefile,v 1.13 2002/05/05 16:02:37 tgl Exp $
1717
#
1818
#-------------------------------------------------------------------------
1919

@@ -25,7 +25,7 @@ OBJS = dynloader.o pg_sema.o pg_shmem.o
2525

2626
OBJS += $(GETHOSTNAME) $(GETRUSAGE) $(INET_ATON) $(ISINF) $(MEMCMP) \
2727
$(MISSING_RANDOM) $(SNPRINTF) $(SRANDOM) $(STRCASECMP) $(STRERROR) \
28-
$(STRTOL) $(STRTOUL) $(SNPRINTF)
28+
$(STRTOL) $(STRTOUL)
2929

3030
OBJS += $(TAS)
3131

@@ -68,8 +68,12 @@ darwin.dir:
6868
tas.o: tas.s
6969
$(CC) $(CFLAGS) -c $<
7070

71+
# IPC test program
72+
ipc_test: ipc_test.o pg_sema.o pg_shmem.o $(MEMCMP) $(SNPRINTF) $(STRERROR)
73+
$(CC) $(CFLAGS) $(LDFLAGS) $(export_dynamic) $^ $(LIBS) -o $@
74+
7175
distclean clean:
72-
rm -f SUBSYS.o $(OBJS)
76+
rm -f SUBSYS.o $(OBJS) ipc_test ipc_test.o
7377
$(MAKE) -C beos clean
7478
$(MAKE) -C darwin clean
7579
$(MAKE) -C qnx4 clean

src/backend/port/ipc_test.c

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* ipc_test.c
4+
* Simplistic testbed for shared memory and semaphore code.
5+
*
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.
17+
*
18+
*
19+
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
20+
* Portions Copyright (c) 1994, Regents of the University of California
21+
*
22+
*
23+
* IDENTIFICATION
24+
* $Header: /cvsroot/pgsql/src/backend/port/ipc_test.c,v 1.1 2002/05/05 16:02:37 tgl Exp $
25+
*
26+
*-------------------------------------------------------------------------
27+
*/
28+
#include "postgres.h"
29+
30+
#include <unistd.h>
31+
32+
#include "miscadmin.h"
33+
#include "storage/ipc.h"
34+
#include "storage/pg_sema.h"
35+
#include "storage/pg_shmem.h"
36+
#include "utils/exc.h"
37+
38+
39+
/********* stuff needed to satisfy references in shmem/sema code *********/
40+
41+
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;
48+
49+
bool IsUnderPostmaster = false;
50+
51+
int MaxBackends = DEF_MAXBACKENDS;
52+
int NBuffers = DEF_NBUFFERS;
53+
54+
#ifndef assert_enabled
55+
bool assert_enabled = true;
56+
#endif
57+
58+
Exception FailedAssertion = {"Failed Assertion"};
59+
60+
61+
#define MAX_ON_EXITS 20
62+
63+
static struct ONEXIT
64+
{
65+
void (*function) ();
66+
Datum arg;
67+
} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
68+
69+
static int on_proc_exit_index,
70+
on_shmem_exit_index;
71+
72+
void
73+
proc_exit(int code)
74+
{
75+
shmem_exit(code);
76+
while (--on_proc_exit_index >= 0)
77+
(*on_proc_exit_list[on_proc_exit_index].function) (code,
78+
on_proc_exit_list[on_proc_exit_index].arg);
79+
exit(code);
80+
}
81+
82+
void
83+
shmem_exit(int code)
84+
{
85+
while (--on_shmem_exit_index >= 0)
86+
(*on_shmem_exit_list[on_shmem_exit_index].function) (code,
87+
on_shmem_exit_list[on_shmem_exit_index].arg);
88+
on_shmem_exit_index = 0;
89+
}
90+
91+
void
92+
on_shmem_exit(void (*function) (), Datum arg)
93+
{
94+
if (on_shmem_exit_index >= MAX_ON_EXITS)
95+
elog(FATAL, "Out of on_shmem_exit slots");
96+
97+
on_shmem_exit_list[on_shmem_exit_index].function = function;
98+
on_shmem_exit_list[on_shmem_exit_index].arg = arg;
99+
100+
++on_shmem_exit_index;
101+
}
102+
103+
void
104+
on_exit_reset(void)
105+
{
106+
on_shmem_exit_index = 0;
107+
on_proc_exit_index = 0;
108+
}
109+
110+
void
111+
RecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2)
112+
{
113+
}
114+
115+
void
116+
ProcessInterrupts(void)
117+
{
118+
}
119+
120+
int
121+
ExceptionalCondition(char *conditionName,
122+
Exception *exceptionP,
123+
char *detail,
124+
char *fileName,
125+
int lineNumber)
126+
{
127+
fprintf(stderr, "TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
128+
exceptionP->message, conditionName,
129+
(detail == NULL ? "" : detail),
130+
fileName, lineNumber);
131+
abort();
132+
return 0;
133+
}
134+
135+
void
136+
elog(int lev, const char *fmt,...)
137+
{
138+
if (lev >= ERROR)
139+
{
140+
fprintf(stderr, "elog(%s)\n", fmt);
141+
abort();
142+
}
143+
}
144+
145+
146+
/********* here's the actual test *********/
147+
148+
149+
typedef struct MyStorage
150+
{
151+
PGShmemHeader header;
152+
int flag;
153+
PGSemaphoreData sem;
154+
} MyStorage;
155+
156+
157+
int
158+
main(int argc, char **argv)
159+
{
160+
MyStorage *storage;
161+
int cpid;
162+
163+
printf("Creating shared memory ... ");
164+
fflush(stdout);
165+
166+
storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433);
167+
168+
storage->flag = 1234;
169+
170+
printf("OK\n");
171+
172+
printf("Creating semaphores ... ");
173+
fflush(stdout);
174+
175+
PGReserveSemaphores(2, 5433);
176+
177+
PGSemaphoreCreate(&storage->sem);
178+
179+
printf("OK\n");
180+
181+
/* sema initial value is 1, so lock should work */
182+
183+
printf("Testing Lock ... ");
184+
fflush(stdout);
185+
186+
PGSemaphoreLock(&storage->sem, false);
187+
188+
printf("OK\n");
189+
190+
/* now sema value is 0, so trylock should fail */
191+
192+
printf("Testing TryLock ... ");
193+
fflush(stdout);
194+
195+
if (PGSemaphoreTryLock(&storage->sem))
196+
printf("unexpected result!\n");
197+
else
198+
printf("OK\n");
199+
200+
/* unlocking twice and then locking twice should work... */
201+
202+
printf("Testing Multiple Lock ... ");
203+
fflush(stdout);
204+
205+
PGSemaphoreUnlock(&storage->sem);
206+
PGSemaphoreUnlock(&storage->sem);
207+
208+
PGSemaphoreLock(&storage->sem, false);
209+
PGSemaphoreLock(&storage->sem, false);
210+
211+
printf("OK\n");
212+
213+
/* check Reset too */
214+
215+
printf("Testing Reset ... ");
216+
fflush(stdout);
217+
218+
PGSemaphoreUnlock(&storage->sem);
219+
220+
PGSemaphoreReset(&storage->sem);
221+
222+
if (PGSemaphoreTryLock(&storage->sem))
223+
printf("unexpected result!\n");
224+
else
225+
printf("OK\n");
226+
227+
/* Fork a child process and see if it can communicate */
228+
229+
printf("Forking child process ... ");
230+
fflush(stdout);
231+
232+
cpid = fork();
233+
if (cpid == 0)
234+
{
235+
/* In child */
236+
on_exit_reset();
237+
sleep(3);
238+
storage->flag++;
239+
PGSemaphoreUnlock(&storage->sem);
240+
proc_exit(0);
241+
}
242+
if (cpid < 0)
243+
{
244+
/* Fork failed */
245+
printf("failed: %s\n", strerror(errno));
246+
proc_exit(1);
247+
}
248+
249+
printf("forked child pid %d OK\n", cpid);
250+
251+
if (storage->flag != 1234)
252+
printf("Wrong value found in shared memory!\n");
253+
254+
printf("Waiting for child (should wait 3 sec here) ... ");
255+
fflush(stdout);
256+
257+
PGSemaphoreLock(&storage->sem, false);
258+
259+
printf("OK\n");
260+
261+
if (storage->flag != 1235)
262+
printf("Wrong value found in shared memory!\n");
263+
264+
/* Test shutdown */
265+
266+
printf("Running shmem_exit processing ... ");
267+
fflush(stdout);
268+
269+
shmem_exit(0);
270+
271+
printf("OK\n");
272+
273+
printf("Tests complete.\n");
274+
275+
proc_exit(0);
276+
277+
return 0; /* not reached */
278+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy