1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-13 16:22:44 +03:00

Get rid of PID entries in shmem hash table; there is no longer any need

for them, and making them just wastes time during backend startup/shutdown.
Also, remove compile-time MAXBACKENDS limit per long-ago proposal.
You can now set MaxBackends as high as your kernel can stand without
any reconfiguration/recompilation.
This commit is contained in:
Tom Lane
2001-09-07 00:27:30 +00:00
parent 0059c4216c
commit 863aceb54f
12 changed files with 213 additions and 316 deletions

View File

@@ -10,10 +10,11 @@
* - this required changing sem_info from containig an array of sem_t to an array of sem_t*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.3 2001/03/22 03:59:42 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.4 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <errno.h>
#include <semaphore.h>
@@ -22,13 +23,13 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "postgres.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "port/darwin/sem.h"
#define SEMMAX IPC_NMAXSEM
#define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX)
#define OPMAX 8
#define MODE 0700
@@ -41,19 +42,23 @@ struct pending_ops
int idx; /* index of first free array member */
};
struct sem_set_info
{
key_t key;
int nsems;
sem_t *sem[SEMMAX]; /* array of POSIX semaphores */
struct sem semV[SEMMAX]; /* array of System V semaphore
* structures */
struct pending_ops pendingOps[SEMMAX]; /* array of pending
* operations */
};
struct sem_info
{
sem_t *sem;
struct
{
key_t key;
int nsems;
sem_t *sem[SEMMAX];/* array of POSIX semaphores */
struct sem semV[SEMMAX]; /* array of System V semaphore
* structures */
struct pending_ops pendingOps[SEMMAX]; /* array of pending
* operations */
} set[SETMAX];
int nsets;
/* there are actually nsets of these: */
struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
};
static struct sem_info *SemInfo = (struct sem_info *) - 1;
@@ -66,7 +71,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
sem_wait(SemInfo->sem);
if (semid < 0 || semid >= SETMAX ||
if (semid < 0 || semid >= SemInfo->nsets ||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
{
sem_post(SemInfo->sem);
@@ -132,8 +137,10 @@ semget(key_t key, int nsems, int semflg)
{
int fd,
semid,
semnum /* , semnum1 */ ;
semnum,
nsets;
int exist = 0;
Size sem_info_size;
char semname[64];
if (nsems < 0 || nsems > SEMMAX)
@@ -163,13 +170,20 @@ semget(key_t key, int nsems, int semflg)
return fd;
shm_unlink(SHM_INFO_NAME);
/* The size may only be set once. Ignore errors. */
ftruncate(fd, sizeof(struct sem_info));
SemInfo = mmap(NULL, sizeof(struct sem_info),
nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info);
ftruncate(fd, sem_info_size);
SemInfo = mmap(NULL, sem_info_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (SemInfo == MAP_FAILED)
return -1;
if (!exist)
{
/* initialize shared memory */
memset(SemInfo, 0, sem_info_size);
SemInfo->nsets = nsets;
for (semid = 0; semid < nsets; semid++)
SemInfo->set[semid].key = -1;
/* create semaphore for locking */
sprintf(semname, "%s-map", SEM_NAME);
#ifdef DEBUG_IPC
@@ -177,30 +191,25 @@ semget(key_t key, int nsems, int semflg)
#endif
SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1);
sem_unlink(semname);
sem_wait(SemInfo->sem);
/* initilize shared memory */
memset(SemInfo->set, 0, sizeof(SemInfo->set));
for (semid = 0; semid < SETMAX; semid++)
SemInfo->set[semid].key = -1;
sem_post(SemInfo->sem);
}
}
sem_wait(SemInfo->sem);
nsets = SemInfo->nsets;
if (key != IPC_PRIVATE)
{
/* search existing element */
semid = 0;
while (semid < SETMAX && SemInfo->set[semid].key != key)
while (semid < nsets && SemInfo->set[semid].key != key)
semid++;
if (!(semflg & IPC_CREAT) && semid >= SETMAX)
if (!(semflg & IPC_CREAT) && semid >= nsets)
{
sem_post(SemInfo->sem);
errno = ENOENT;
return -1;
}
else if (semid < SETMAX)
else if (semid < nsets)
{
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
{
@@ -228,12 +237,12 @@ semget(key_t key, int nsems, int semflg)
/* search first free element */
semid = 0;
while (semid < SETMAX && SemInfo->set[semid].key != -1)
while (semid < nsets && SemInfo->set[semid].key != -1)
semid++;
if (semid >= SETMAX)
if (semid >= nsets)
{
#ifdef DEBUG_IPC
fprintf(stderr, "darwin semget failed because all keys were -1 up to SETMAX\n");
fprintf(stderr, "darwin semget failed because all keys were -1\n");
#endif
sem_post(SemInfo->sem);
errno = ENOSPC;
@@ -249,15 +258,18 @@ semget(key_t key, int nsems, int semflg)
SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0);
sem_unlink(semname);
/* Currently sem_init always returns -1.
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
sem_close( SemInfo->set[semid].sem[semnum1] );
}
sem_post( SemInfo->sem );
return -1;
}
*/
/* Currently sem_init always returns -1. */
#ifdef NOT_USED
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
int semnum1;
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
sem_close( SemInfo->set[semid].sem[semnum1] );
}
sem_post( SemInfo->sem );
return -1;
}
#endif
}
SemInfo->set[semid].key = key;
@@ -279,7 +291,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
sem_wait(SemInfo->sem);
if (semid < 0 || semid >= SETMAX)
if (semid < 0 || semid >= SemInfo->nsets)
{
sem_post(SemInfo->sem);
errno = EINVAL;

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.6 2001/08/24 14:07:49 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/port/qnx4/Attic/sem.c,v 1.7 2001/09/07 00:27:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,14 +21,15 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "storage/ipc.h"
#include "storage/proc.h"
#include <sys/sem.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#define SETMAX ((MAXBACKENDS + PROC_NSEMS_PER_SET + 1) / PROC_NSEMS_PER_SET)
#define SEMMAX (PROC_NSEMS_PER_SET+1)
#define OPMAX 8
@@ -42,19 +43,23 @@ struct pending_ops
int idx; /* index of first free array member */
};
struct sem_set_info
{
key_t key;
int nsems;
sem_t sem[SEMMAX]; /* array of POSIX semaphores */
struct sem semV[SEMMAX]; /* array of System V semaphore
* structures */
struct pending_ops pendingOps[SEMMAX]; /* array of pending
* operations */
};
struct sem_info
{
sem_t sem;
struct
{
key_t key;
int nsems;
sem_t sem[SEMMAX];/* array of POSIX semaphores */
struct sem semV[SEMMAX]; /* array of System V semaphore
* structures */
struct pending_ops pendingOps[SEMMAX]; /* array of pending
* operations */
} set[SETMAX];
int nsets;
/* there are actually nsets of these: */
struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
};
static struct sem_info *SemInfo = (struct sem_info *) - 1;
@@ -78,7 +83,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
sem_wait(&SemInfo->sem);
if (semid < 0 || semid >= SETMAX ||
if (semid < 0 || semid >= SemInfo->nsets ||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
{
sem_post(&SemInfo->sem);
@@ -144,9 +149,11 @@ semget(key_t key, int nsems, int semflg)
{
int fd,
semid,
semnum /* , semnum1 */ ;
semnum,
nsets;
int exist = 0;
struct stat statbuf;
Size sem_info_size;
struct stat statbuf;
if (nsems < 0 || nsems > SEMMAX)
{
@@ -167,60 +174,64 @@ semget(key_t key, int nsems, int semflg)
if (fd == -1)
return fd;
/* The size may only be set once. Ignore errors. */
ltrunc(fd, sizeof(struct sem_info), SEEK_SET);
if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
{ /* error is EBADF */
close( fd );
return -1;
}
nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info);
ltrunc(fd, sem_info_size, SEEK_SET);
if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
{ /* error is EBADF */
close( fd );
return -1;
}
/*
* size is rounded by proc to the next __PAGESIZE
*/
if ( statbuf.st_size !=
((( sizeof(struct sem_info) /__PAGESIZE)+1) * __PAGESIZE) )
(((sem_info_size/__PAGESIZE)+1) * __PAGESIZE) )
{
fprintf( stderr,
"Found a pre-existing shared memory block for the semaphore memory\n"
"of a different size (%ld instead %ld). Make sure that all executables\n"
"are from the same release or remove the file \"/dev/shmem/%s\"\n"
"left by a previous version.\n", statbuf.st_size,
sizeof(struct sem_info), SHM_INFO_NAME);
"left by a previous version.\n",
(long) statbuf.st_size,
(long) sem_info_size,
SHM_INFO_NAME);
errno = EACCES;
return -1;
}
SemInfo = mmap(NULL, sizeof(struct sem_info),
SemInfo = mmap(NULL, sem_info_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (SemInfo == MAP_FAILED)
return -1;
if (!exist)
{
/* initialize shared memory */
memset(SemInfo, 0, sem_info_size);
SemInfo->nsets = nsets;
for (semid = 0; semid < nsets; semid++)
SemInfo->set[semid].key = -1;
/* create semaphore for locking */
sem_init(&SemInfo->sem, 1, 1);
sem_wait(&SemInfo->sem);
/* initilize shared memory */
memset(SemInfo->set, 0, sizeof(SemInfo->set));
for (semid = 0; semid < SETMAX; semid++)
SemInfo->set[semid].key = -1;
sem_post(&SemInfo->sem);
on_proc_exit( semclean, NULL );
on_proc_exit( semclean, 0 );
}
}
sem_wait(&SemInfo->sem);
nsets = SemInfo->nsets;
if (key != IPC_PRIVATE)
{
/* search existing element */
semid = 0;
while (semid < SETMAX && SemInfo->set[semid].key != key)
while (semid < nsets && SemInfo->set[semid].key != key)
semid++;
if (!(semflg & IPC_CREAT) && semid >= SETMAX)
if (!(semflg & IPC_CREAT) && semid >= nsets)
{
sem_post(&SemInfo->sem);
errno = ENOENT;
return -1;
}
else if (semid < SETMAX)
else if (semid < nsets)
{
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
{
@@ -244,9 +255,9 @@ semget(key_t key, int nsems, int semflg)
/* search first free element */
semid = 0;
while (semid < SETMAX && SemInfo->set[semid].key != -1)
while (semid < nsets && SemInfo->set[semid].key != -1)
semid++;
if (semid >= SETMAX)
if (semid >= nsets)
{
sem_post(&SemInfo->sem);
errno = ENOSPC;
@@ -256,15 +267,18 @@ semget(key_t key, int nsems, int semflg)
for (semnum = 0; semnum < nsems; semnum++)
{
sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
/* Currently sem_init always returns -1.
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
sem_destroy( &SemInfo->set[semid].sem[semnum1] );
}
sem_post( &SemInfo->sem );
return -1;
}
*/
/* Currently sem_init always returns -1. */
#ifdef NOT_USED
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
int semnum1;
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
sem_destroy( &SemInfo->set[semid].sem[semnum1] );
}
sem_post( &SemInfo->sem );
return -1;
}
#endif
}
SemInfo->set[semid].key = key;
@@ -286,7 +300,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
sem_wait(&SemInfo->sem);
if (semid < 0 || semid >= SETMAX)
if (semid < 0 || semid >= SemInfo->nsets)
{
sem_post(&SemInfo->sem);
errno = EINVAL;