On Mon, Jun 04, 2001 at 08:11:31PM -0400, Roland McGrath wrote:
> Please give some details about how it uses those two facilities.
>From src/backend/storage/ipc/README:
The cache synchronization is done using a message queue. [...]
The message queue is implemented as a shared buffer segment. [...]
Access to this shared message buffer is synchronized by the lock manager.
shm.c:
/*
* POSTGRES processes share one or more regions of shared memory.
* The shared memory is created by a postmaster and is inherited
* by each backend via fork(). The routines in this file are used for
* allocating and binding to shared memory data structures.
[...] */
ipc.c: (esp case 2.)
* Currently, semaphores are used (my understanding anyway) in two
* different ways:
* 1. as mutexes on machines that don't have test-and-set (eg.
* mips R3000).
* 2. for putting processes to sleep when waiting on a lock
* and waking them up when the lock is free.
* The number of semaphores in (1) is fixed and those are shared
* among all backends. In (2), there is 1 semaphore per process and those
* are not shared with anyone else.
The failing (I think) semget():
semId = semget(semKey, numSems, IPC_CREAT | IPC_EXCL | permission);
If this succeeds, it does:
if (semctl(semId, 0, SETALL, semun) < 0)
It deletes the semaphore this way:
if (semctl(semId, 0, IPC_RMID, semun) < 0)
The locking mechanism (it also has a trylock function which sets sem_flg to
IPC_NOWAIT):
struct sembuf sops;
sops.sem_op = -1; /* decrement */
sops.sem_flg = 0;
sops.sem_num = sem;
[...]
do
{
ImmediateInterruptOK = interruptOK;
CHECK_FOR_INTERRUPTS();
errStatus = semop(semId, &sops, 1);
ImmediateInterruptOK = false;
} while (errStatus == -1 && errno == EINTR);
Unlocking:
sops.sem_op = 1; /* increment */
sops.sem_flg = 0;
sops.sem_num = sem;
[...]
do
{
errStatus = semop(semId, &sops, 1);
} while (errStatus == -1 && errno == EINTR);
Postgresql also has the following query functions:
GetValue
return semctl(semId, sem, GETVAL, dummy);
GetLastPID
return semctl(semId, sem, GETPID, dummy);
And a "fairly thin layer on top of SysV shared memory functionality", which
occupies the second half of the file:
Create:
shmid = shmget(memKey, size, IPC_CREAT | IPC_EXCL | permission);
[...]
memAddress = shmat(shmid, 0, 0);
Detach:
shmdt(DatumGetPointer(shmaddr)
Delete:
if (shmctl(DatumGetInt32(shmId), IPC_RMID, (struct shmid_ds *) NULL) < 0)
IsInUse:
if (shmctl(shmId, IPC_STAT, &shmStat) < 0)
I think that's about the extent it is using these features.
Thanks,
Marcus
--
`Rhubarb is no Egyptian god.' Debian http://www.debian.org [EMAIL PROTECTED]
Marcus Brinkmann GNU http://www.gnu.org [EMAIL PROTECTED]
[EMAIL PROTECTED]
http://www.marcus-brinkmann.de
_______________________________________________
Bug-hurd mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-hurd