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:
parent
0059c4216c
commit
863aceb54f
|
@ -73,20 +73,10 @@ user_write_unlock_oid(Oid oid)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
user_unlock_all()
|
user_unlock_all(void)
|
||||||
{
|
{
|
||||||
PROC *proc;
|
return LockReleaseAll(USER_LOCKMETHOD, MyProc, false,
|
||||||
SHMEM_OFFSET location;
|
InvalidTransactionId);
|
||||||
|
|
||||||
ShmemPIDLookup(MyProcPid, &location);
|
|
||||||
if (location == INVALID_OFFSET)
|
|
||||||
{
|
|
||||||
elog(NOTICE, "UserUnlockAll: unable to get proc ptr");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
proc = (PROC *) MAKE_PTR(location);
|
|
||||||
return LockReleaseAll(USER_LOCKMETHOD, proc, false, InvalidTransactionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end of file */
|
/* end of file */
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
* - this required changing sem_info from containig an array of sem_t to an array of sem_t*
|
* - this required changing sem_info from containig an array of sem_t to an array of sem_t*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 <errno.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
@ -22,13 +23,13 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "postgres.h"
|
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "port/darwin/sem.h"
|
#include "port/darwin/sem.h"
|
||||||
|
|
||||||
#define SEMMAX IPC_NMAXSEM
|
#define SEMMAX IPC_NMAXSEM
|
||||||
#define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX)
|
|
||||||
#define OPMAX 8
|
#define OPMAX 8
|
||||||
|
|
||||||
#define MODE 0700
|
#define MODE 0700
|
||||||
|
@ -41,19 +42,23 @@ struct pending_ops
|
||||||
int idx; /* index of first free array member */
|
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
|
struct sem_info
|
||||||
{
|
{
|
||||||
sem_t *sem;
|
sem_t *sem;
|
||||||
struct
|
int nsets;
|
||||||
{
|
/* there are actually nsets of these: */
|
||||||
key_t key;
|
struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
|
||||||
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];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sem_info *SemInfo = (struct sem_info *) - 1;
|
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);
|
sem_wait(SemInfo->sem);
|
||||||
|
|
||||||
if (semid < 0 || semid >= SETMAX ||
|
if (semid < 0 || semid >= SemInfo->nsets ||
|
||||||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
|
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
|
||||||
{
|
{
|
||||||
sem_post(SemInfo->sem);
|
sem_post(SemInfo->sem);
|
||||||
|
@ -132,8 +137,10 @@ semget(key_t key, int nsems, int semflg)
|
||||||
{
|
{
|
||||||
int fd,
|
int fd,
|
||||||
semid,
|
semid,
|
||||||
semnum /* , semnum1 */ ;
|
semnum,
|
||||||
|
nsets;
|
||||||
int exist = 0;
|
int exist = 0;
|
||||||
|
Size sem_info_size;
|
||||||
char semname[64];
|
char semname[64];
|
||||||
|
|
||||||
if (nsems < 0 || nsems > SEMMAX)
|
if (nsems < 0 || nsems > SEMMAX)
|
||||||
|
@ -163,13 +170,20 @@ semget(key_t key, int nsems, int semflg)
|
||||||
return fd;
|
return fd;
|
||||||
shm_unlink(SHM_INFO_NAME);
|
shm_unlink(SHM_INFO_NAME);
|
||||||
/* The size may only be set once. Ignore errors. */
|
/* The size may only be set once. Ignore errors. */
|
||||||
ftruncate(fd, sizeof(struct sem_info));
|
nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
|
||||||
SemInfo = mmap(NULL, sizeof(struct sem_info),
|
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);
|
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (SemInfo == MAP_FAILED)
|
if (SemInfo == MAP_FAILED)
|
||||||
return -1;
|
return -1;
|
||||||
if (!exist)
|
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 */
|
/* create semaphore for locking */
|
||||||
sprintf(semname, "%s-map", SEM_NAME);
|
sprintf(semname, "%s-map", SEM_NAME);
|
||||||
#ifdef DEBUG_IPC
|
#ifdef DEBUG_IPC
|
||||||
|
@ -177,30 +191,25 @@ semget(key_t key, int nsems, int semflg)
|
||||||
#endif
|
#endif
|
||||||
SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1);
|
SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1);
|
||||||
sem_unlink(semname);
|
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);
|
sem_wait(SemInfo->sem);
|
||||||
|
nsets = SemInfo->nsets;
|
||||||
|
|
||||||
if (key != IPC_PRIVATE)
|
if (key != IPC_PRIVATE)
|
||||||
{
|
{
|
||||||
/* search existing element */
|
/* search existing element */
|
||||||
semid = 0;
|
semid = 0;
|
||||||
while (semid < SETMAX && SemInfo->set[semid].key != key)
|
while (semid < nsets && SemInfo->set[semid].key != key)
|
||||||
semid++;
|
semid++;
|
||||||
if (!(semflg & IPC_CREAT) && semid >= SETMAX)
|
if (!(semflg & IPC_CREAT) && semid >= nsets)
|
||||||
{
|
{
|
||||||
sem_post(SemInfo->sem);
|
sem_post(SemInfo->sem);
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (semid < SETMAX)
|
else if (semid < nsets)
|
||||||
{
|
{
|
||||||
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
|
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
|
||||||
{
|
{
|
||||||
|
@ -228,12 +237,12 @@ semget(key_t key, int nsems, int semflg)
|
||||||
|
|
||||||
/* search first free element */
|
/* search first free element */
|
||||||
semid = 0;
|
semid = 0;
|
||||||
while (semid < SETMAX && SemInfo->set[semid].key != -1)
|
while (semid < nsets && SemInfo->set[semid].key != -1)
|
||||||
semid++;
|
semid++;
|
||||||
if (semid >= SETMAX)
|
if (semid >= nsets)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_IPC
|
#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
|
#endif
|
||||||
sem_post(SemInfo->sem);
|
sem_post(SemInfo->sem);
|
||||||
errno = ENOSPC;
|
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);
|
SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0);
|
||||||
sem_unlink(semname);
|
sem_unlink(semname);
|
||||||
|
|
||||||
/* Currently sem_init always returns -1.
|
/* Currently sem_init always returns -1. */
|
||||||
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
|
#ifdef NOT_USED
|
||||||
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
|
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
|
||||||
sem_close( SemInfo->set[semid].sem[semnum1] );
|
int semnum1;
|
||||||
}
|
|
||||||
sem_post( SemInfo->sem );
|
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
|
||||||
return -1;
|
sem_close( SemInfo->set[semid].sem[semnum1] );
|
||||||
}
|
}
|
||||||
*/
|
sem_post( SemInfo->sem );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SemInfo->set[semid].key = key;
|
SemInfo->set[semid].key = key;
|
||||||
|
@ -279,7 +291,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
|
||||||
|
|
||||||
sem_wait(SemInfo->sem);
|
sem_wait(SemInfo->sem);
|
||||||
|
|
||||||
if (semid < 0 || semid >= SETMAX)
|
if (semid < 0 || semid >= SemInfo->nsets)
|
||||||
{
|
{
|
||||||
sem_post(SemInfo->sem);
|
sem_post(SemInfo->sem);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "storage/ipc.h"
|
|
||||||
#include "storage/proc.h"
|
|
||||||
#include <sys/sem.h>
|
#include <sys/sem.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.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 SEMMAX (PROC_NSEMS_PER_SET+1)
|
||||||
#define OPMAX 8
|
#define OPMAX 8
|
||||||
|
|
||||||
|
@ -42,19 +43,23 @@ struct pending_ops
|
||||||
int idx; /* index of first free array member */
|
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
|
struct sem_info
|
||||||
{
|
{
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
struct
|
int nsets;
|
||||||
{
|
/* there are actually nsets of these: */
|
||||||
key_t key;
|
struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
|
||||||
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];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sem_info *SemInfo = (struct sem_info *) - 1;
|
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);
|
sem_wait(&SemInfo->sem);
|
||||||
|
|
||||||
if (semid < 0 || semid >= SETMAX ||
|
if (semid < 0 || semid >= SemInfo->nsets ||
|
||||||
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
|
semnum < 0 || semnum >= SemInfo->set[semid].nsems)
|
||||||
{
|
{
|
||||||
sem_post(&SemInfo->sem);
|
sem_post(&SemInfo->sem);
|
||||||
|
@ -144,9 +149,11 @@ semget(key_t key, int nsems, int semflg)
|
||||||
{
|
{
|
||||||
int fd,
|
int fd,
|
||||||
semid,
|
semid,
|
||||||
semnum /* , semnum1 */ ;
|
semnum,
|
||||||
|
nsets;
|
||||||
int exist = 0;
|
int exist = 0;
|
||||||
struct stat statbuf;
|
Size sem_info_size;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
if (nsems < 0 || nsems > SEMMAX)
|
if (nsems < 0 || nsems > SEMMAX)
|
||||||
{
|
{
|
||||||
|
@ -167,60 +174,64 @@ semget(key_t key, int nsems, int semflg)
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return fd;
|
return fd;
|
||||||
/* The size may only be set once. Ignore errors. */
|
/* The size may only be set once. Ignore errors. */
|
||||||
ltrunc(fd, sizeof(struct sem_info), SEEK_SET);
|
nsets = PROC_SEM_MAP_ENTRIES(MaxBackends);
|
||||||
if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
|
sem_info_size = sizeof(struct sem_info) + (nsets-1) * sizeof(struct sem_set_info);
|
||||||
{ /* error is EBADF */
|
ltrunc(fd, sem_info_size, SEEK_SET);
|
||||||
close( fd );
|
if ( fstat( fd, &statbuf ) ) /* would be strange : the only doc'ed */
|
||||||
return -1;
|
{ /* error is EBADF */
|
||||||
}
|
close( fd );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* size is rounded by proc to the next __PAGESIZE
|
* size is rounded by proc to the next __PAGESIZE
|
||||||
*/
|
*/
|
||||||
if ( statbuf.st_size !=
|
if ( statbuf.st_size !=
|
||||||
((( sizeof(struct sem_info) /__PAGESIZE)+1) * __PAGESIZE) )
|
(((sem_info_size/__PAGESIZE)+1) * __PAGESIZE) )
|
||||||
{
|
{
|
||||||
fprintf( stderr,
|
fprintf( stderr,
|
||||||
"Found a pre-existing shared memory block for the semaphore memory\n"
|
"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"
|
"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"
|
"are from the same release or remove the file \"/dev/shmem/%s\"\n"
|
||||||
"left by a previous version.\n", statbuf.st_size,
|
"left by a previous version.\n",
|
||||||
sizeof(struct sem_info), SHM_INFO_NAME);
|
(long) statbuf.st_size,
|
||||||
|
(long) sem_info_size,
|
||||||
|
SHM_INFO_NAME);
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SemInfo = mmap(NULL, sizeof(struct sem_info),
|
SemInfo = mmap(NULL, sem_info_size,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
if (SemInfo == MAP_FAILED)
|
if (SemInfo == MAP_FAILED)
|
||||||
return -1;
|
return -1;
|
||||||
if (!exist)
|
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 */
|
/* create semaphore for locking */
|
||||||
sem_init(&SemInfo->sem, 1, 1);
|
sem_init(&SemInfo->sem, 1, 1);
|
||||||
sem_wait(&SemInfo->sem);
|
on_proc_exit( semclean, 0 );
|
||||||
/* 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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_wait(&SemInfo->sem);
|
sem_wait(&SemInfo->sem);
|
||||||
|
nsets = SemInfo->nsets;
|
||||||
|
|
||||||
if (key != IPC_PRIVATE)
|
if (key != IPC_PRIVATE)
|
||||||
{
|
{
|
||||||
/* search existing element */
|
/* search existing element */
|
||||||
semid = 0;
|
semid = 0;
|
||||||
while (semid < SETMAX && SemInfo->set[semid].key != key)
|
while (semid < nsets && SemInfo->set[semid].key != key)
|
||||||
semid++;
|
semid++;
|
||||||
if (!(semflg & IPC_CREAT) && semid >= SETMAX)
|
if (!(semflg & IPC_CREAT) && semid >= nsets)
|
||||||
{
|
{
|
||||||
sem_post(&SemInfo->sem);
|
sem_post(&SemInfo->sem);
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (semid < SETMAX)
|
else if (semid < nsets)
|
||||||
{
|
{
|
||||||
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
|
if (semflg & IPC_CREAT && semflg & IPC_EXCL)
|
||||||
{
|
{
|
||||||
|
@ -244,9 +255,9 @@ semget(key_t key, int nsems, int semflg)
|
||||||
|
|
||||||
/* search first free element */
|
/* search first free element */
|
||||||
semid = 0;
|
semid = 0;
|
||||||
while (semid < SETMAX && SemInfo->set[semid].key != -1)
|
while (semid < nsets && SemInfo->set[semid].key != -1)
|
||||||
semid++;
|
semid++;
|
||||||
if (semid >= SETMAX)
|
if (semid >= nsets)
|
||||||
{
|
{
|
||||||
sem_post(&SemInfo->sem);
|
sem_post(&SemInfo->sem);
|
||||||
errno = ENOSPC;
|
errno = ENOSPC;
|
||||||
|
@ -256,15 +267,18 @@ semget(key_t key, int nsems, int semflg)
|
||||||
for (semnum = 0; semnum < nsems; semnum++)
|
for (semnum = 0; semnum < nsems; semnum++)
|
||||||
{
|
{
|
||||||
sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
|
sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
|
||||||
/* Currently sem_init always returns -1.
|
/* Currently sem_init always returns -1. */
|
||||||
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
|
#ifdef NOT_USED
|
||||||
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
|
if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
|
||||||
sem_destroy( &SemInfo->set[semid].sem[semnum1] );
|
int semnum1;
|
||||||
}
|
|
||||||
sem_post( &SemInfo->sem );
|
for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
|
||||||
return -1;
|
sem_destroy( &SemInfo->set[semid].sem[semnum1] );
|
||||||
}
|
}
|
||||||
*/
|
sem_post( &SemInfo->sem );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SemInfo->set[semid].key = key;
|
SemInfo->set[semid].key = key;
|
||||||
|
@ -286,7 +300,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
|
||||||
|
|
||||||
sem_wait(&SemInfo->sem);
|
sem_wait(&SemInfo->sem);
|
||||||
|
|
||||||
if (semid < 0 || semid >= SETMAX)
|
if (semid < 0 || semid >= SemInfo->nsets)
|
||||||
{
|
{
|
||||||
sem_post(&SemInfo->sem);
|
sem_post(&SemInfo->sem);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.237 2001/08/30 19:02:42 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.238 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
|
@ -138,9 +138,9 @@ char *UnixSocketDir;
|
||||||
char *VirtualHost;
|
char *VirtualHost;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MaxBackends is the actual limit on the number of backends we will
|
* MaxBackends is the limit on the number of backends we can start.
|
||||||
* start. The default is established by configure, but it can be
|
* The default is established by configure, but it can be altered at
|
||||||
* readjusted from 1..MAXBACKENDS with the postmaster -N switch. Note
|
* postmaster start with the postmaster's -N switch. Note
|
||||||
* that a larger MaxBackends value will increase the size of the shared
|
* that a larger MaxBackends value will increase the size of the shared
|
||||||
* memory area as well as cause the postmaster to grab more kernel
|
* memory area as well as cause the postmaster to grab more kernel
|
||||||
* semaphores, even if you never actually use that many backends.
|
* semaphores, even if you never actually use that many backends.
|
||||||
|
@ -777,8 +777,8 @@ usage(const char *progname)
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
printf(gettext(" -l enable SSL connections\n"));
|
printf(gettext(" -l enable SSL connections\n"));
|
||||||
#endif
|
#endif
|
||||||
printf(gettext(" -N MAX-CONNECT maximum number of allowed connections (1..%d, default %d)\n"),
|
printf(gettext(" -N MAX-CONNECT maximum number of allowed connections (default %d)\n"),
|
||||||
MAXBACKENDS, DEF_MAXBACKENDS);
|
DEF_MAXBACKENDS);
|
||||||
printf(gettext(" -o OPTIONS pass 'OPTIONS' to each backend server\n"));
|
printf(gettext(" -o OPTIONS pass 'OPTIONS' to each backend server\n"));
|
||||||
printf(gettext(" -p PORT port number to listen on (default %d)\n"), DEF_PGPORT);
|
printf(gettext(" -p PORT port number to listen on (default %d)\n"), DEF_PGPORT);
|
||||||
printf(gettext(" -S silent mode (start in background without logging output)\n"));
|
printf(gettext(" -S silent mode (start in background without logging output)\n"));
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.57 2001/03/22 03:59:45 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.58 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -259,92 +259,6 @@ ShmemInitHash(char *name, /* table string name for shmem index */
|
||||||
return hash_create(init_size, infoP, hash_flags);
|
return hash_create(init_size, infoP, hash_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ShmemPIDLookup -- lookup process data structure using process id
|
|
||||||
*
|
|
||||||
* Returns: TRUE if no error. locationPtr is initialized if PID is
|
|
||||||
* found in the shmem index.
|
|
||||||
*
|
|
||||||
* NOTES:
|
|
||||||
* only information about success or failure is the value of
|
|
||||||
* locationPtr.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
ShmemPIDLookup(int pid, SHMEM_OFFSET *locationPtr)
|
|
||||||
{
|
|
||||||
ShmemIndexEnt *result,
|
|
||||||
item;
|
|
||||||
bool found;
|
|
||||||
|
|
||||||
Assert(ShmemIndex);
|
|
||||||
MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
|
|
||||||
sprintf(item.key, "PID %d", pid);
|
|
||||||
|
|
||||||
SpinAcquire(ShmemIndexLock);
|
|
||||||
|
|
||||||
result = (ShmemIndexEnt *)
|
|
||||||
hash_search(ShmemIndex, (char *) &item, HASH_ENTER, &found);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
SpinRelease(ShmemIndexLock);
|
|
||||||
elog(ERROR, "ShmemInitPID: ShmemIndex corrupted");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
*locationPtr = result->location;
|
|
||||||
else
|
|
||||||
result->location = *locationPtr;
|
|
||||||
|
|
||||||
SpinRelease(ShmemIndexLock);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ShmemPIDDestroy -- destroy shmem index entry for process
|
|
||||||
* using process id
|
|
||||||
*
|
|
||||||
* Returns: offset of the process struct in shared memory or
|
|
||||||
* INVALID_OFFSET if not found.
|
|
||||||
*
|
|
||||||
* Side Effect: removes the entry from the shmem index
|
|
||||||
*/
|
|
||||||
SHMEM_OFFSET
|
|
||||||
ShmemPIDDestroy(int pid)
|
|
||||||
{
|
|
||||||
ShmemIndexEnt *result,
|
|
||||||
item;
|
|
||||||
bool found;
|
|
||||||
SHMEM_OFFSET location = 0;
|
|
||||||
|
|
||||||
Assert(ShmemIndex);
|
|
||||||
|
|
||||||
MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
|
|
||||||
sprintf(item.key, "PID %d", pid);
|
|
||||||
|
|
||||||
SpinAcquire(ShmemIndexLock);
|
|
||||||
|
|
||||||
result = (ShmemIndexEnt *)
|
|
||||||
hash_search(ShmemIndex, (char *) &item, HASH_REMOVE, &found);
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
location = result->location;
|
|
||||||
|
|
||||||
SpinRelease(ShmemIndexLock);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
elog(ERROR, "ShmemPIDDestroy: PID table corrupted");
|
|
||||||
return INVALID_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
return location;
|
|
||||||
else
|
|
||||||
return INVALID_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ShmemInitStruct -- Create/attach to a structure in shared
|
* ShmemInitStruct -- Create/attach to a structure in shared
|
||||||
* memory.
|
* memory.
|
||||||
|
@ -373,7 +287,6 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
|
||||||
|
|
||||||
if (!ShmemIndex)
|
if (!ShmemIndex)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the shmem index doesn't exist, we are bootstrapping: we must
|
* If the shmem index doesn't exist, we are bootstrapping: we must
|
||||||
* be trying to init the shmem index itself.
|
* be trying to init the shmem index itself.
|
||||||
|
@ -400,7 +313,6 @@ ShmemInitStruct(char *name, Size size, bool *foundPtr)
|
||||||
|
|
||||||
if (*foundPtr)
|
if (*foundPtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure is in the shmem index so someone else has allocated
|
* Structure is in the shmem index so someone else has allocated
|
||||||
* it already. The size better be the same as the size we are
|
* it already. The size better be the same as the size we are
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.93 2001/08/29 19:14:39 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.94 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Outside modules can create a lock table and acquire/release
|
* Outside modules can create a lock table and acquire/release
|
||||||
|
@ -1430,7 +1430,6 @@ LockShmemSize(int maxBackends)
|
||||||
void
|
void
|
||||||
DumpLocks(void)
|
DumpLocks(void)
|
||||||
{
|
{
|
||||||
SHMEM_OFFSET location;
|
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
SHM_QUEUE *procHolders;
|
SHM_QUEUE *procHolders;
|
||||||
HOLDER *holder;
|
HOLDER *holder;
|
||||||
|
@ -1438,12 +1437,10 @@ DumpLocks(void)
|
||||||
int lockmethod = DEFAULT_LOCKMETHOD;
|
int lockmethod = DEFAULT_LOCKMETHOD;
|
||||||
LOCKMETHODTABLE *lockMethodTable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
|
|
||||||
ShmemPIDLookup(MyProcPid, &location);
|
proc = MyProc;
|
||||||
if (location == INVALID_OFFSET)
|
if (proc == NULL)
|
||||||
return;
|
|
||||||
proc = (PROC *) MAKE_PTR(location);
|
|
||||||
if (proc != MyProc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
procHolders = &proc->procHolders;
|
procHolders = &proc->procHolders;
|
||||||
|
|
||||||
Assert(lockmethod < NumLockMethods);
|
Assert(lockmethod < NumLockMethods);
|
||||||
|
@ -1477,22 +1474,16 @@ DumpLocks(void)
|
||||||
void
|
void
|
||||||
DumpAllLocks(void)
|
DumpAllLocks(void)
|
||||||
{
|
{
|
||||||
SHMEM_OFFSET location;
|
|
||||||
PROC *proc;
|
PROC *proc;
|
||||||
HOLDER *holder = NULL;
|
HOLDER *holder = NULL;
|
||||||
LOCK *lock;
|
LOCK *lock;
|
||||||
int pid;
|
|
||||||
int lockmethod = DEFAULT_LOCKMETHOD;
|
int lockmethod = DEFAULT_LOCKMETHOD;
|
||||||
LOCKMETHODTABLE *lockMethodTable;
|
LOCKMETHODTABLE *lockMethodTable;
|
||||||
HTAB *holderTable;
|
HTAB *holderTable;
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
|
|
||||||
pid = getpid();
|
proc = MyProc;
|
||||||
ShmemPIDLookup(pid, &location);
|
if (proc == NULL)
|
||||||
if (location == INVALID_OFFSET)
|
|
||||||
return;
|
|
||||||
proc = (PROC *) MAKE_PTR(location);
|
|
||||||
if (proc != MyProc)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Assert(lockmethod < NumLockMethods);
|
Assert(lockmethod < NumLockMethods);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.106 2001/09/04 21:42:17 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.107 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -124,11 +124,18 @@ static void ProcFreeAllSemaphores(void);
|
||||||
void
|
void
|
||||||
InitProcGlobal(int maxBackends)
|
InitProcGlobal(int maxBackends)
|
||||||
{
|
{
|
||||||
|
int semMapEntries;
|
||||||
|
Size procGlobalSize;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
/* attach to the free list */
|
/* Compute size for ProcGlobal structure */
|
||||||
|
Assert(maxBackends > 0);
|
||||||
|
semMapEntries = PROC_SEM_MAP_ENTRIES(maxBackends);
|
||||||
|
procGlobalSize = sizeof(PROC_HDR) + (semMapEntries-1) * sizeof(SEM_MAP_ENTRY);
|
||||||
|
|
||||||
|
/* Create or attach to the ProcGlobal shared structure */
|
||||||
ProcGlobal = (PROC_HDR *)
|
ProcGlobal = (PROC_HDR *)
|
||||||
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
|
ShmemInitStruct("Proc Header", procGlobalSize, &found);
|
||||||
|
|
||||||
/* --------------------
|
/* --------------------
|
||||||
* We're the first - initialize.
|
* We're the first - initialize.
|
||||||
|
@ -141,10 +148,12 @@ InitProcGlobal(int maxBackends)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ProcGlobal->freeProcs = INVALID_OFFSET;
|
ProcGlobal->freeProcs = INVALID_OFFSET;
|
||||||
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
|
ProcGlobal->semMapEntries = semMapEntries;
|
||||||
|
|
||||||
|
for (i = 0; i < semMapEntries; i++)
|
||||||
{
|
{
|
||||||
ProcGlobal->procSemIds[i] = -1;
|
ProcGlobal->procSemMap[i].procSemId = -1;
|
||||||
ProcGlobal->freeSemMap[i] = 0;
|
ProcGlobal->procSemMap[i].freeSemMap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,11 +166,9 @@ InitProcGlobal(int maxBackends)
|
||||||
on_shmem_exit(ProcFreeAllSemaphores, 0);
|
on_shmem_exit(ProcFreeAllSemaphores, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pre-create the semaphores for the first maxBackends processes.
|
* Pre-create the semaphores.
|
||||||
*/
|
*/
|
||||||
Assert(maxBackends > 0 && maxBackends <= MAXBACKENDS);
|
for (i = 0; i < semMapEntries; i++)
|
||||||
|
|
||||||
for (i = 0; i < ((maxBackends - 1) / PROC_NSEMS_PER_SET + 1); i++)
|
|
||||||
{
|
{
|
||||||
IpcSemaphoreId semId;
|
IpcSemaphoreId semId;
|
||||||
|
|
||||||
|
@ -169,7 +176,7 @@ InitProcGlobal(int maxBackends)
|
||||||
IPCProtection,
|
IPCProtection,
|
||||||
1,
|
1,
|
||||||
false);
|
false);
|
||||||
ProcGlobal->procSemIds[i] = semId;
|
ProcGlobal->procSemMap[i].procSemId = semId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,9 +189,17 @@ InitProcGlobal(int maxBackends)
|
||||||
void
|
void
|
||||||
InitProcess(void)
|
InitProcess(void)
|
||||||
{
|
{
|
||||||
bool found = false;
|
SHMEM_OFFSET myOffset;
|
||||||
unsigned long location,
|
|
||||||
myOffset;
|
/*
|
||||||
|
* ProcGlobal should be set by a previous call to InitProcGlobal
|
||||||
|
* (if we are a backend, we inherit this by fork() from the postmaster).
|
||||||
|
*/
|
||||||
|
if (ProcGlobal == NULL)
|
||||||
|
elog(STOP, "InitProcess: Proc Header uninitialized");
|
||||||
|
|
||||||
|
if (MyProc != NULL)
|
||||||
|
elog(ERROR, "InitProcess: you already exist");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProcStructLock protects the freelist of PROC entries and the map
|
* ProcStructLock protects the freelist of PROC entries and the map
|
||||||
|
@ -196,27 +211,9 @@ InitProcess(void)
|
||||||
* this routine, be careful to release the lock manually before any
|
* this routine, be careful to release the lock manually before any
|
||||||
* elog(), else you'll have a stuck spinlock to add to your woes.
|
* elog(), else you'll have a stuck spinlock to add to your woes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SpinAcquire(ProcStructLock);
|
SpinAcquire(ProcStructLock);
|
||||||
|
|
||||||
/* attach to the ProcGlobal structure */
|
|
||||||
ProcGlobal = (PROC_HDR *)
|
|
||||||
ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
/* this should not happen. InitProcGlobal() is called before this. */
|
|
||||||
SpinRelease(ProcStructLock);
|
|
||||||
elog(STOP, "InitProcess: Proc Header uninitialized");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MyProc != NULL)
|
|
||||||
{
|
|
||||||
SpinRelease(ProcStructLock);
|
|
||||||
elog(ERROR, "InitProcess: you already exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to get a proc struct from the free list first */
|
/* try to get a proc struct from the free list first */
|
||||||
|
|
||||||
myOffset = ProcGlobal->freeProcs;
|
myOffset = ProcGlobal->freeProcs;
|
||||||
|
|
||||||
if (myOffset != INVALID_OFFSET)
|
if (myOffset != INVALID_OFFSET)
|
||||||
|
@ -263,23 +260,6 @@ InitProcess(void)
|
||||||
MemSet(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
|
MemSet(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
|
||||||
MyProc->sLocks[ProcStructLock] = 1;
|
MyProc->sLocks[ProcStructLock] = 1;
|
||||||
|
|
||||||
/*
|
|
||||||
* Release the lock while accessing shmem index; we still haven't
|
|
||||||
* installed ProcKill and so we don't want to hold lock if there's
|
|
||||||
* an error.
|
|
||||||
*/
|
|
||||||
SpinRelease(ProcStructLock);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Install ourselves in the shmem index table. The name to use is
|
|
||||||
* determined by the OS-assigned process id. That allows the cleanup
|
|
||||||
* process to find us after any untimely exit.
|
|
||||||
*/
|
|
||||||
location = MAKE_OFFSET(MyProc);
|
|
||||||
if ((!ShmemPIDLookup(MyProcPid, &location)) ||
|
|
||||||
(location != MAKE_OFFSET(MyProc)))
|
|
||||||
elog(STOP, "InitProcess: ShmemPID table broken");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arrange to clean up at backend exit. Once we do this, owned
|
* Arrange to clean up at backend exit. Once we do this, owned
|
||||||
* spinlocks will be released on exit, and so we can be a lot less
|
* spinlocks will be released on exit, and so we can be a lot less
|
||||||
|
@ -288,20 +268,21 @@ InitProcess(void)
|
||||||
on_shmem_exit(ProcKill, 0);
|
on_shmem_exit(ProcKill, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up a wait-semaphore for the proc. (Do this last so that we
|
* Set up a wait-semaphore for the proc. (We rely on ProcKill to clean
|
||||||
* can rely on ProcKill to clean up if it fails.)
|
* up if this fails.)
|
||||||
*/
|
*/
|
||||||
if (IsUnderPostmaster)
|
if (IsUnderPostmaster)
|
||||||
{
|
|
||||||
SpinAcquire(ProcStructLock);
|
|
||||||
ProcGetNewSemIdAndNum(&MyProc->sem.semId, &MyProc->sem.semNum);
|
ProcGetNewSemIdAndNum(&MyProc->sem.semId, &MyProc->sem.semNum);
|
||||||
SpinRelease(ProcStructLock);
|
|
||||||
/*
|
/* Done with freelist and sem map */
|
||||||
* We might be reusing a semaphore that belongs to a dead backend.
|
SpinRelease(ProcStructLock);
|
||||||
* So be careful and reinitialize its value here.
|
|
||||||
*/
|
/*
|
||||||
|
* We might be reusing a semaphore that belongs to a dead backend.
|
||||||
|
* So be careful and reinitialize its value here.
|
||||||
|
*/
|
||||||
|
if (MyProc->sem.semId >= 0)
|
||||||
ZeroProcSemaphore(MyProc);
|
ZeroProcSemaphore(MyProc);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we have a PROC, we could try to acquire locks, so
|
* Now that we have a PROC, we could try to acquire locks, so
|
||||||
|
@ -416,9 +397,7 @@ ProcReleaseLocks(bool isCommit)
|
||||||
static void
|
static void
|
||||||
ProcKill(void)
|
ProcKill(void)
|
||||||
{
|
{
|
||||||
SHMEM_OFFSET location;
|
Assert(MyProc != NULL);
|
||||||
|
|
||||||
Assert(MyProc);
|
|
||||||
|
|
||||||
/* Release any spinlocks I am holding */
|
/* Release any spinlocks I am holding */
|
||||||
ProcReleaseSpins(MyProc);
|
ProcReleaseSpins(MyProc);
|
||||||
|
@ -434,11 +413,6 @@ ProcKill(void)
|
||||||
LockReleaseAll(USER_LOCKMETHOD, MyProc, true, InvalidTransactionId);
|
LockReleaseAll(USER_LOCKMETHOD, MyProc, true, InvalidTransactionId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove my PROC struct from the shmem hash table */
|
|
||||||
location = ShmemPIDDestroy(MyProcPid);
|
|
||||||
Assert(location != INVALID_OFFSET);
|
|
||||||
Assert(MyProc == (PROC *) MAKE_PTR(location));
|
|
||||||
|
|
||||||
SpinAcquire(ProcStructLock);
|
SpinAcquire(ProcStructLock);
|
||||||
|
|
||||||
/* Free up my wait semaphore, if I got one */
|
/* Free up my wait semaphore, if I got one */
|
||||||
|
@ -449,9 +423,10 @@ ProcKill(void)
|
||||||
MyProc->links.next = ProcGlobal->freeProcs;
|
MyProc->links.next = ProcGlobal->freeProcs;
|
||||||
ProcGlobal->freeProcs = MAKE_OFFSET(MyProc);
|
ProcGlobal->freeProcs = MAKE_OFFSET(MyProc);
|
||||||
|
|
||||||
SpinRelease(ProcStructLock);
|
/* PROC struct isn't mine anymore; stop tracking spinlocks with it! */
|
||||||
|
|
||||||
MyProc = NULL;
|
MyProc = NULL;
|
||||||
|
|
||||||
|
SpinRelease(ProcStructLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -987,8 +962,8 @@ static void
|
||||||
ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum)
|
ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
IpcSemaphoreId *procSemIds = ProcGlobal->procSemIds;
|
int semMapEntries = ProcGlobal->semMapEntries;
|
||||||
int32 *freeSemMap = ProcGlobal->freeSemMap;
|
SEM_MAP_ENTRY *procSemMap = ProcGlobal->procSemMap;
|
||||||
int32 fullmask = (1 << PROC_NSEMS_PER_SET) - 1;
|
int32 fullmask = (1 << PROC_NSEMS_PER_SET) - 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -996,24 +971,24 @@ ProcGetNewSemIdAndNum(IpcSemaphoreId *semId, int *semNum)
|
||||||
* the bitmap to look for a free semaphore.
|
* the bitmap to look for a free semaphore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
|
for (i = 0; i < semMapEntries; i++)
|
||||||
{
|
{
|
||||||
int mask = 1;
|
int mask = 1;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (freeSemMap[i] == fullmask)
|
if (procSemMap[i].freeSemMap == fullmask)
|
||||||
continue; /* this set is fully allocated */
|
continue; /* this set is fully allocated */
|
||||||
if (procSemIds[i] < 0)
|
if (procSemMap[i].procSemId < 0)
|
||||||
continue; /* this set hasn't been initialized */
|
continue; /* this set hasn't been initialized */
|
||||||
|
|
||||||
for (j = 0; j < PROC_NSEMS_PER_SET; j++)
|
for (j = 0; j < PROC_NSEMS_PER_SET; j++)
|
||||||
{
|
{
|
||||||
if ((freeSemMap[i] & mask) == 0)
|
if ((procSemMap[i].freeSemMap & mask) == 0)
|
||||||
{
|
{
|
||||||
/* A free semaphore found. Mark it as allocated. */
|
/* A free semaphore found. Mark it as allocated. */
|
||||||
freeSemMap[i] |= mask;
|
procSemMap[i].freeSemMap |= mask;
|
||||||
|
|
||||||
*semId = procSemIds[i];
|
*semId = procSemMap[i].procSemId;
|
||||||
*semNum = j;
|
*semNum = j;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1039,14 +1014,15 @@ ProcFreeSem(IpcSemaphoreId semId, int semNum)
|
||||||
{
|
{
|
||||||
int32 mask;
|
int32 mask;
|
||||||
int i;
|
int i;
|
||||||
|
int semMapEntries = ProcGlobal->semMapEntries;
|
||||||
|
|
||||||
mask = ~(1 << semNum);
|
mask = ~(1 << semNum);
|
||||||
|
|
||||||
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
|
for (i = 0; i < semMapEntries; i++)
|
||||||
{
|
{
|
||||||
if (ProcGlobal->procSemIds[i] == semId)
|
if (ProcGlobal->procSemMap[i].procSemId == semId)
|
||||||
{
|
{
|
||||||
ProcGlobal->freeSemMap[i] &= mask;
|
ProcGlobal->procSemMap[i].freeSemMap &= mask;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1064,9 +1040,9 @@ ProcFreeAllSemaphores(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < PROC_SEM_MAP_ENTRIES; i++)
|
for (i = 0; i < ProcGlobal->semMapEntries; i++)
|
||||||
{
|
{
|
||||||
if (ProcGlobal->procSemIds[i] >= 0)
|
if (ProcGlobal->procSemMap[i].procSemId >= 0)
|
||||||
IpcSemaphoreKill(ProcGlobal->procSemIds[i]);
|
IpcSemaphoreKill(ProcGlobal->procSemMap[i].procSemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.89 2001/09/06 04:57:29 ishii Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.90 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
|
@ -281,7 +281,7 @@ InitPostgres(const char *dbname, const char *username)
|
||||||
|
|
||||||
InitBackendSharedInvalidationState();
|
InitBackendSharedInvalidationState();
|
||||||
|
|
||||||
if (MyBackendId > MAXBACKENDS || MyBackendId <= 0)
|
if (MyBackendId > MaxBackends || MyBackendId <= 0)
|
||||||
elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId);
|
elog(FATAL, "InitPostgres: bad backend id %d", MyBackendId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Support for grand unified configuration scheme, including SET
|
* Support for grand unified configuration scheme, including SET
|
||||||
* command, configuration file, and command line options.
|
* command, configuration file, and command line options.
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.46 2001/08/15 18:42:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.47 2001/09/07 00:27:29 tgl Exp $
|
||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
|
@ -286,7 +286,7 @@ static struct config_int
|
||||||
* constraints here are partially unused.
|
* constraints here are partially unused.
|
||||||
*/
|
*/
|
||||||
{"max_connections", PGC_POSTMASTER, &MaxBackends,
|
{"max_connections", PGC_POSTMASTER, &MaxBackends,
|
||||||
DEF_MAXBACKENDS, 1, MAXBACKENDS, NULL, NULL},
|
DEF_MAXBACKENDS, 1, INT_MAX, NULL, NULL},
|
||||||
|
|
||||||
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
|
{"shared_buffers", PGC_POSTMASTER, &NBuffers,
|
||||||
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
|
DEF_NBUFFERS, 16, INT_MAX, NULL, NULL},
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
|
* or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your
|
||||||
* changes will be overwritten the next time you run configure.
|
* changes will be overwritten the next time you run configure.
|
||||||
*
|
*
|
||||||
* $Id: pg_config.h.in,v 1.3 2001/09/06 03:23:38 momjian Exp $
|
* $Id: pg_config.h.in,v 1.4 2001/09/07 00:27:29 tgl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PG_CONFIG_H
|
#ifndef PG_CONFIG_H
|
||||||
|
@ -106,12 +106,6 @@
|
||||||
*------------------------------------------------------------------------
|
*------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Hard limit on number of backend server processes per postmaster.
|
|
||||||
* Increasing this costs about 32 bytes per process slot as of v 6.5.
|
|
||||||
*/
|
|
||||||
#define MAXBACKENDS (DEF_MAXBACKENDS > 1024 ? DEF_MAXBACKENDS : 1024)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default number of buffers in shared buffer pool (each of size BLCKSZ).
|
* Default number of buffers in shared buffer pool (each of size BLCKSZ).
|
||||||
* This is just the default setting for the postmaster's -B switch.
|
* This is just the default setting for the postmaster's -B switch.
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: proc.h,v 1.45 2001/07/06 21:04:26 tgl Exp $
|
* $Id: proc.h,v 1.46 2001/09/07 00:27:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -104,10 +104,21 @@ do { \
|
||||||
* in each set for identification purposes.)
|
* in each set for identification purposes.)
|
||||||
*
|
*
|
||||||
* PROC_SEM_MAP_ENTRIES is the number of semaphore sets we need to allocate
|
* PROC_SEM_MAP_ENTRIES is the number of semaphore sets we need to allocate
|
||||||
* to keep track of up to MAXBACKENDS backends.
|
* to keep track of up to maxBackends backends.
|
||||||
*/
|
*/
|
||||||
#define PROC_NSEMS_PER_SET 16
|
#define PROC_NSEMS_PER_SET 16
|
||||||
#define PROC_SEM_MAP_ENTRIES ((MAXBACKENDS-1)/PROC_NSEMS_PER_SET+1)
|
#define PROC_SEM_MAP_ENTRIES(maxBackends) (((maxBackends)-1)/PROC_NSEMS_PER_SET+1)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* info about a single set of per-process semaphores */
|
||||||
|
IpcSemaphoreId procSemId;
|
||||||
|
int32 freeSemMap;
|
||||||
|
/*
|
||||||
|
* In freeSemMap, bit i is set if the i'th semaphore of this sema
|
||||||
|
* set is allocated to a process. (i counts from 0 at the LSB)
|
||||||
|
*/
|
||||||
|
} SEM_MAP_ENTRY;
|
||||||
|
|
||||||
typedef struct procglobal
|
typedef struct procglobal
|
||||||
{
|
{
|
||||||
|
@ -115,13 +126,12 @@ typedef struct procglobal
|
||||||
SHMEM_OFFSET freeProcs;
|
SHMEM_OFFSET freeProcs;
|
||||||
|
|
||||||
/* Info about semaphore sets used for per-process semaphores */
|
/* Info about semaphore sets used for per-process semaphores */
|
||||||
IpcSemaphoreId procSemIds[PROC_SEM_MAP_ENTRIES];
|
int semMapEntries;
|
||||||
int32 freeSemMap[PROC_SEM_MAP_ENTRIES];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In each freeSemMap entry, bit i is set if the i'th semaphore of the
|
* VARIABLE LENGTH ARRAY: actual length is semMapEntries.
|
||||||
* set is allocated to a process. (i counts from 0 at the LSB)
|
* THIS MUST BE LAST IN THE STRUCT DECLARATION.
|
||||||
*/
|
*/
|
||||||
|
SEM_MAP_ENTRY procSemMap[1];
|
||||||
} PROC_HDR;
|
} PROC_HDR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: shmem.h,v 1.29 2001/06/18 21:38:02 momjian Exp $
|
* $Id: shmem.h,v 1.30 2001/09/07 00:27:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -71,8 +71,6 @@ extern void *ShmemAlloc(Size size);
|
||||||
extern bool ShmemIsValid(unsigned long addr);
|
extern bool ShmemIsValid(unsigned long addr);
|
||||||
extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
|
extern HTAB *ShmemInitHash(char *name, long init_size, long max_size,
|
||||||
HASHCTL *infoP, int hash_flags);
|
HASHCTL *infoP, int hash_flags);
|
||||||
extern bool ShmemPIDLookup(int pid, SHMEM_OFFSET *locationPtr);
|
|
||||||
extern SHMEM_OFFSET ShmemPIDDestroy(int pid);
|
|
||||||
extern void *ShmemInitStruct(char *name, Size size, bool *foundPtr);
|
extern void *ShmemInitStruct(char *name, Size size, bool *foundPtr);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue