mirror of https://github.com/postgres/postgres
Add a trivial testbed for pg_sema and pg_shmem code.
This commit is contained in:
parent
2010a43fcb
commit
17ea23dd17
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
Loading…
Reference in New Issue