bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: postgresql requires shm and sem


From: Marcus Brinkmann
Subject: Re: postgresql requires shm and sem
Date: Tue, 5 Jun 2001 02:33:10 +0200
User-agent: Mutt/1.3.18i

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 brinkmd@debian.org
Marcus Brinkmann              GNU    http://www.gnu.org    marcus@gnu.org
Marcus.Brinkmann@ruhr-uni-bochum.de
http://www.marcus-brinkmann.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]