head 1.45; access; symbols release_4_2:1.45 marc_alpha:1.42 aix_ok:1.42 Version_2_1:1.26 old_buffer_manager:1.21 C_Demo_1:1.6; locks; strict; comment @ * @; 1.45 date 94.06.28.18.04.28; author aoki; state Exp; branches; next 1.44; 1.44 date 94.02.01.11.55.34; author aoki; state Exp; branches; next 1.43; 1.43 date 93.10.31.23.26.35; author aoki; state Exp; branches; next 1.42; 1.42 date 93.08.10.01.46.51; author marc; state Exp; branches; next 1.41; 1.41 date 93.07.27.00.53.55; author aoki; state Exp; branches; next 1.40; 1.40 date 93.03.03.22.54.53; author marc; state Exp; branches; next 1.39; 1.39 date 92.12.31.02.32.59; author marc; state Exp; branches; next 1.38; 1.38 date 92.12.30.17.21.17; author marc; state Exp; branches; next 1.37; 1.37 date 91.10.16.16.56.46; author hong; state Exp; branches; next 1.36; 1.36 date 91.09.05.23.28.23; author hong; state Exp; branches; next 1.35; 1.35 date 91.08.29.23.54.07; author mer; state Exp; branches; next 1.34; 1.34 date 91.08.14.12.32.37; author mer; state Exp; branches; next 1.33; 1.33 date 91.07.24.10.06.28; author hong; state Exp; branches; next 1.32; 1.32 date 91.07.24.07.46.49; author mao; state Exp; branches; next 1.31; 1.31 date 91.07.17.23.45.36; author hong; state Exp; branches; next 1.30; 1.30 date 91.06.12.10.18.47; author kemnitz; state Exp; branches; next 1.29; 1.29 date 91.06.10.20.57.40; author kemnitz; state Exp; branches; next 1.28; 1.28 date 91.04.23.17.08.04; author kemnitz; state Exp; branches; next 1.27; 1.27 date 91.04.01.08.46.47; author hong; state Exp; branches; next 1.26; 1.26 date 91.03.07.22.04.48; author hong; state Exp; branches; next 1.25; 1.25 date 91.03.03.17.27.40; author hong; state Exp; branches; next 1.24; 1.24 date 91.02.28.21.46.04; author hong; state Exp; branches; next 1.23; 1.23 date 91.02.18.20.39.25; author hong; state Exp; branches; next 1.22; 1.22 date 91.01.18.22.15.21; author hong; state Exp; branches; next 1.21; 1.21 date 90.11.28.20.57.13; author hong; state Exp; branches; next 1.20; 1.20 date 90.11.12.08.15.19; author hong; state Exp; branches; next 1.19; 1.19 date 90.11.07.12.06.07; author hong; state Exp; branches; next 1.18; 1.18 date 90.10.23.17.19.06; author kemnitz; state Exp; branches; next 1.17; 1.17 date 90.10.17.17.09.19; author hong; state Exp; branches; next 1.16; 1.16 date 90.10.16.23.33.06; author hong; state Exp; branches; next 1.15; 1.15 date 90.10.02.12.11.10; author goh; state Exp; branches; next 1.14; 1.14 date 90.10.02.12.06.07; author goh; state Exp; branches; next 1.13; 1.13 date 90.09.30.15.53.11; author goh; state Exp; branches; next 1.12; 1.12 date 90.09.25.16.44.28; author kemnitz; state Exp; branches; next 1.11; 1.11 date 90.04.19.16.34.41; author kemnitz; state Exp; branches; next 1.10; 1.10 date 90.03.31.19.00.31; author cimarron; state Exp; branches; next 1.9; 1.9 date 90.03.12.16.26.40; author cimarron; state Exp; branches; next 1.8; 1.8 date 90.02.13.00.27.54; author kemnitz; state Exp; branches; next 1.7; 1.7 date 90.02.12.19.48.10; author cimarron; state Exp; branches; next 1.6; 1.6 date 89.09.05.17.23.33; author mao; state C_Demo_1; branches; next 1.5; 1.5 date 89.08.03.00.06.06; author dillon; state Exp; branches; next 1.4; 1.4 date 89.04.19.15.12.31; author dillon; state Exp; branches; next 1.3; 1.3 date 89.04.14.18.31.00; author dillon; state Exp; branches; next 1.2; 1.2 date 89.02.02.16.15.58; author dillon; state Stab; branches; next 1.1; 1.1 date 89.01.17.05.57.19; author cimarron; state Exp; branches; next ; desc @@ 1.45 log @solaris semctl needs fourth arg all the time @ text @/* ---------------------------------------------------------------- * ipc.c -- * POSTGRES inter-process communication definitions. * * Identification: * $Header: /import/faerie/faerie/aoki/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.44 1994/02/01 11:55:34 aoki Exp aoki $ * ---------------------------------------------------------------- */ #include #include #include #include /* XXX - the following dependency should be moved into the defaults.mk file */ #ifndef _IPC_ #define _IPC_ #include #include #include #endif #include "storage/ipci.h" /* for PrivateIPCKey XXX */ #include "storage/ipc.h" #include "utils/memutils.h" #include "utils/log.h" #include "tcop/slaves.h" #if defined(PORTNAME_bsd44) int UsePrivateMemory = 1; #else int UsePrivateMemory = 0; #endif #ifdef PARALLELDEBUG #include "executor/paralleldebug.h" #endif /* ---------------------------------------------------------------- * exit() handling stuff * ---------------------------------------------------------------- */ #define MAX_ON_EXITS 20 static struct ONEXIT { void (*function)(); caddr_t arg; } onexit_list[ MAX_ON_EXITS ]; static int onexit_index; typedef struct _PrivateMemStruct { int id; char *memptr; } PrivateMem; PrivateMem IpcPrivateMem[16]; int PrivateMemoryCreate ( memKey , size , permission ) IpcMemoryKey memKey; uint32 size; { static int memid = 0; UsePrivateMemory = 1; IpcPrivateMem[memid].id = memid; IpcPrivateMem[memid].memptr = malloc(size); if (IpcPrivateMem[memid].memptr == NULL) elog(WARN, "PrivateMemoryCreate: not enough memory to malloc"); bzero(IpcPrivateMem[memid].memptr, size); /* XXX PURIFY */ return (memid++); } char * PrivateMemoryAttach ( memid , ignored1 , ignored2 ) IpcMemoryId memid; int ignored1; int ignored2; { return ( IpcPrivateMem[memid].memptr ); } /* ---------------------------------------------------------------- * exitpg * * this function calls all the callbacks registered * for it (to free resources) and then calls exit. * This should be the only function to call exit(). * -cim 2/6/90 * ---------------------------------------------------------------- */ int exitpg_inprogress = 0; void exitpg(code) int code; { int i; /* ---------------- * if exitpg_inprocess is true, then it means that we * are being invoked from within an on_exit() handler * and so we return immediately to avoid recursion. * ---------------- */ if (exitpg_inprogress) return; exitpg_inprogress = 1; /* ---------------- * call all the callbacks registered before calling exit(). * ---------------- */ for (i = onexit_index - 1; i >= 0; --i) (*onexit_list[i].function)(code, onexit_list[i].arg); exit(code); } /* ------------------ * Run all of the on_exitpg routines but don't exit in the end. * This is used by the postmaster to re-initialize shared memory and * semaphores after a backend dies horribly * ------------------ */ void quasi_exitpg() { int i; /* ---------------- * if exitpg_inprocess is true, then it means that we * are being invoked from within an on_exit() handler * and so we return immediately to avoid recursion. * ---------------- */ if (exitpg_inprogress) return; exitpg_inprogress = 1; /* ---------------- * call all the callbacks registered before calling exit(). * ---------------- */ for (i = onexit_index - 1; i >= 0; --i) (*onexit_list[i].function)(0, onexit_list[i].arg); onexit_index = 0; exitpg_inprogress = 0; } /* ---------------------------------------------------------------- * on_exitpg * * this function adds a callback function to the list of * functions invoked by exitpg(). -cim 2/6/90 * ---------------------------------------------------------------- */ on_exitpg(function, arg) void (*function)(); caddr_t arg; { if (onexit_index >= MAX_ON_EXITS) return(-1); onexit_list[ onexit_index ].function = function; onexit_list[ onexit_index ].arg = arg; ++onexit_index; return(0); } /****************************************************************************/ /* IPCPrivateSemaphoreKill(status, semId) */ /* */ /****************************************************************************/ void IPCPrivateSemaphoreKill(status, semId) int status; int semId; /* caddr_t */ { union semun semun; semctl(semId, 0, IPC_RMID, semun); } /****************************************************************************/ /* IPCPrivateMemoryKill(status, shmId) */ /* */ /****************************************************************************/ void IPCPrivateMemoryKill(status, shmId) int status; int shmId; /* caddr_t */ { if ( UsePrivateMemory ) { /* free ( IpcPrivateMem[shmId].memptr ); */ } else { if (shmctl(shmId, IPC_RMID, (struct shmid_ds *) NULL) < 0) { elog(NOTICE, "IPCPrivateMemoryKill: shmctl(%d, %d, 0) failed: %m", shmId, IPC_RMID); } } } /****************************************************************************/ /* IpcSemaphoreCreate(semKey, semNum, permission, semStartValue) */ /* */ /* - returns a semaphore identifier: */ /* */ /* if key doesn't exist: return a new id, status:= IpcSemIdNotExist */ /* if key exists: return the old id, status:= IpcSemIdExist */ /* if semNum > MAX : return # of argument, status:=IpcInvalidArgument */ /* */ /****************************************************************************/ /* * Note: * XXX This should be split into two different calls. One should * XXX be used to create a semaphore set. The other to "attach" a * XXX existing set. It should be an error for the semaphore set * XXX to to already exist or for it not to, respectively. * * Currently, the semaphore sets are "attached" and an error * is detected only when a later shared memory attach fails. */ IpcSemaphoreId IpcSemaphoreCreate(semKey, semNum, permission, semStartValue, status) IpcSemaphoreKey semKey; /* input patameter */ int semNum; /* input patameter */ int permission; /* input patameter */ int semStartValue; /* input patameter */ int *status; /* output parameter */ { int i; int errStatus; int semId; ushort array[IPC_NMAXSEM]; union semun semun; /* get a semaphore if non-existent */ /* check arguments */ if (semNum > IPC_NMAXSEM || semNum <= 0) { *status = IpcInvalidArgument; return(2); /* returns the number of the invalid argument */ } semId = semget(semKey, 0, 0); if (semId == -1) { *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */ #ifdef DEBUG_IPC fprintf(stderr,"calling semget with %d, %d , %d\n", semKey, semNum, IPC_CREAT|permission ); #endif semId = semget(semKey, semNum, IPC_CREAT|permission); if (semId < 0) { perror("semget"); exitpg(3); } for (i = 0; i < semNum; i++) { array[i] = semStartValue; } semun.array = array; errStatus = semctl(semId, 0, SETALL, semun); if (errStatus == -1) { perror("semctl"); } /* if (semKey == PrivateIPCKey) */ on_exitpg(IPCPrivateSemaphoreKill, (caddr_t)semId); } else { /* there is a semaphore id for this key */ *status = IpcSemIdExist; } #ifdef DEBUG_IPC fprintf(stderr,"\nIpcSemaphoreCreate, status %d, returns %d\n", *status, semId ); fflush(stdout); fflush(stderr); #endif return(semId); } /* ---------------- * IpcSemaphoreCreateWithoutOnExit * * this is a copy of IpcSemaphoreCreate, but it doesn't register * an on_exitpg procedure. This is necessary for the executor * semaphores because we need a special on-exit procedure to * do the right thing depending on if the postgres process is * a master or a slave process. In a master process, we should * kill the semaphores when we exit but in a slave process we * should release them. * ---------------- */ IpcSemaphoreId IpcSemaphoreCreateWithoutOnExit(semKey, semNum, permission, semStartValue, status) IpcSemaphoreKey semKey; /* input patameter */ int semNum; /* input patameter */ int permission; /* input patameter */ int semStartValue; /* input patameter */ int *status; /* output parameter */ { int i; int errStatus; int semId; ushort array[IPC_NMAXSEM]; union semun semun; /* get a semaphore if non-existent */ /* check arguments */ if (semNum > IPC_NMAXSEM || semNum <= 0) { *status = IpcInvalidArgument; return(2); /* returns the number of the invalid argument */ } semId = semget(semKey, 0, 0); if (semId == -1) { *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */ semId = semget(semKey, semNum, IPC_CREAT|permission); if (semId < 0) { perror("semget"); exitpg(3); } for (i = 0; i < semNum; i++) { array[i] = semStartValue; } semun.array = array; errStatus = semctl(semId, 0, SETALL, semun); if (errStatus == -1) { perror("semctl"); } } else { /* there is a semaphore id for this key */ *status = IpcSemIdExist; } return(semId); } /****************************************************************************/ /* IpcSemaphoreSet() - sets the initial value of the semaphore */ /* */ /* note: the xxx_return variables are only used for debugging. */ /****************************************************************************/ int IpcSemaphoreSet_return; void IpcSemaphoreSet(semId, semno, value) int semId; int semno; int value; { int errStatus; union semun semun; semun.val = value; errStatus = semctl(semId, semno, SETVAL, semun); IpcSemaphoreSet_return = errStatus; if (errStatus == -1) perror("semctl"); } /****************************************************************************/ /* IpcSemaphoreKill(key) - removes a semaphore */ /* */ /****************************************************************************/ void IpcSemaphoreKill(key) IpcSemaphoreKey key; { int i; int semId; int status; union semun semun; /* kill semaphore if existent */ semId = semget(key, 0, 0); if (semId != -1) semctl(semId, 0, IPC_RMID, semun); } /****************************************************************************/ /* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */ /* */ /* note: the xxx_return variables are only used for debugging. */ /****************************************************************************/ int IpcSemaphoreLock_return; void IpcSemaphoreLock(semId, sem, lock) IpcSemaphoreId semId; int sem; int lock; { extern int errno; int errStatus; struct sembuf sops; sops.sem_op = lock; sops.sem_flg = 0; sops.sem_num = sem; /* ---------------- * Note: if errStatus is -1 and errno == EINTR then it means we * returned from the operation prematurely because we were * sent a signal. So we try and lock the semaphore again. * I am not certain this is correct, but the semantics aren't * clear it fixes problems with parallel abort synchronization, * namely that after processing an abort signal, the semaphore * call returns with -1 (and errno == EINTR) before it should. * -cim 3/28/90 * ---------------- */ do { errStatus = semop(semId, (struct sembuf **)&sops, 1); } while (errStatus == -1 && errno == EINTR); IpcSemaphoreLock_return = errStatus; if (errStatus == -1) { perror("semop"); exitpg(255); } } /* ---------------- * IpcSemaphoreSilentLock * * This does what IpcSemaphoreLock() does but does not * produce error messages. * * note: the xxx_return variables are only used for debugging. * ---------------- */ int IpcSemaphoreSilentLock_return; void IpcSemaphoreSilentLock(semId, sem, lock) IpcSemaphoreId semId; int sem; int lock; { int errStatus; struct sembuf sops; sops.sem_op = lock; sops.sem_flg = 0; sops.sem_num = sem; IpcSemaphoreSilentLock_return = semop(semId, (struct sembuf **)&sops, 1); } /****************************************************************************/ /* IpcSemaphoreUnlock(semId, sem, lock) - unlocks a semaphore */ /* */ /* note: the xxx_return variables are only used for debugging. */ /****************************************************************************/ int IpcSemaphoreUnlock_return; void IpcSemaphoreUnlock(semId, sem, lock) IpcSemaphoreId semId; int sem; int lock; { extern int errno; int errStatus; struct sembuf sops; sops.sem_op = -lock; sops.sem_flg = 0; sops.sem_num = sem; /* ---------------- * Note: if errStatus is -1 and errno == EINTR then it means we * returned from the operation prematurely because we were * sent a signal. So we try and lock the semaphore again. * I am not certain this is correct, but the semantics aren't * clear it fixes problems with parallel abort synchronization, * namely that after processing an abort signal, the semaphore * call returns with -1 (and errno == EINTR) before it should. * -cim 3/28/90 * ---------------- */ do { errStatus = semop(semId, (struct sembuf **)&sops, 1); } while (errStatus == -1 && errno == EINTR); IpcSemaphoreUnlock_return = errStatus; if (errStatus == -1) { perror("semop"); exitpg(255); } } /* ---------------- * IpcSemaphoreSilentUnlock * * This does what IpcSemaphoreUnlock() does but does not * produce error messages. This is used in the slave backends * when they exit because it is possible that the master backend * may have died and removed the semaphore before this code gets * to execute in the slaves. * * note: the xxx_return variables are only used for debugging. * ---------------- */ int IpcSemaphoreSilentUnlock_return; void IpcSemaphoreSilentUnlock(semId, sem, lock) IpcSemaphoreId semId; int sem; int lock; { int errStatus; struct sembuf sops; sops.sem_op = -lock; sops.sem_flg = 0; sops.sem_num = sem; IpcSemaphoreSilentUnlock_return = semop(semId, (struct sembuf **)&sops, 1); } int IpcSemaphoreGetCount(semId, sem) IpcSemaphoreId semId; int sem; { int semncnt; union semun dummy; /* for Solaris */ semncnt = semctl(semId, sem, GETNCNT, &dummy); return semncnt; } int IpcSemaphoreGetValue(semId, sem) IpcSemaphoreId semId; int sem; { int semval; union semun dummy; /* for Solaris */ semval = semctl(semId, sem, GETVAL, &dummy); return semval; } /****************************************************************************/ /* IpcMemoryCreate(memKey) */ /* */ /* - returns the memory identifier, if creation succeeds */ /* returns IpcMemCreationFailed, if failure */ /****************************************************************************/ IpcMemoryId IpcMemoryCreate(memKey, size, permission) IpcMemoryKey memKey; uint32 size; int permission; { IpcMemoryId shmid; int errStatus; if ( memKey == PrivateIPCKey && !(ParallelExecutorEnabled()) ) { /* private */ shmid = PrivateMemoryCreate ( memKey, size , IPC_CREAT|permission); } else { shmid = shmget(memKey, size, IPC_CREAT|permission); } if (shmid < 0) { fprintf(stderr,"IpcMemoryCreate: memKey=%d , size=%d , permission=%d", memKey, size , permission ); perror("IpcMemoryCreate: shmget(..., create, ...) failed"); return(IpcMemCreationFailed); } /* if (memKey == PrivateIPCKey) */ on_exitpg(IPCPrivateMemoryKill, (caddr_t)shmid); return(shmid); } /* ---------------- * IpcMemoryCreateWithoutOnExit * * Like IpcSemaphoreCreateWithoutOnExit(), this function * creates shared memory without registering an on_exit * procedure. * ---------------- */ IpcMemoryId IpcMemoryCreateWithoutOnExit(memKey, size, permission) IpcMemoryKey memKey; uint32 size; int permission; { IpcMemoryId shmid; int errStatus; if ( memKey == PrivateIPCKey && (!(ParallelExecutorEnabled())) ) { /* private */ shmid = PrivateMemoryCreate ( memKey, size , IPC_CREAT|permission); } else { shmid = shmget(memKey, size, IPC_CREAT|permission); } if (shmid < 0) { fprintf(stderr,"IpcMemoryCreate: memKey=%d , size=%d , permission=%d", memKey, size , permission ); perror("IpcMemoryCreateWithoutOnExit: shmget(, IPC_CREAT,) failed"); return(IpcMemCreationFailed); } return(shmid); } /****************************************************************************/ /* IpcMemoryIdGet(memKey, size) returns the shared memory Id */ /* or IpcMemIdGetFailed */ /****************************************************************************/ IpcMemoryId IpcMemoryIdGet(memKey, size) IpcMemoryKey memKey; uint32 size; { IpcMemoryId shmid; shmid = shmget(memKey, size, 0); if (shmid < 0) { fprintf(stderr,"IpcMemoryIdGet: memKey=%d , size=%d , permission=%d", memKey, size , 0 ); perror("IpcMemoryIdGet: shmget() failed"); return(IpcMemIdGetFailed); } return(shmid); } /****************************************************************************/ /* IpcMemoryDetach(status, shmaddr) removes a shared memory segment */ /* from a backend address space */ /* (only called by backends running under the postmaster) */ /****************************************************************************/ void IpcMemoryDetach(status, shmaddr) int status; char *shmaddr; { if (shmdt(shmaddr) < 0) { elog(NOTICE, "IpcMemoryDetach: shmdt(0x%x): %m", shmaddr); } } /****************************************************************************/ /* IpcMemoryAttach(memId) returns the adress of shared memory */ /* or IpcMemAttachFailed */ /* */ /* CALL IT: addr = (struct *) IpcMemoryAttach(memId); */ /* */ /****************************************************************************/ char * IpcMemoryAttach(memId) IpcMemoryId memId; { char *memAddress; int errStatus; if (UsePrivateMemory) { memAddress = (char *) PrivateMemoryAttach(memId, 0, 0); } else { memAddress = (char *) shmat(memId, 0, 0); } /* if ( *memAddress == -1) { XXX ??? */ if ( memAddress == (char *)-1) { perror("IpcMemoryAttach: shmat() failed"); return(IpcMemAttachFailed); } if (!UsePrivateMemory) on_exitpg(IpcMemoryDetach, (caddr_t) memAddress); return((char *) memAddress); } /****************************************************************************/ /* IpcMemoryKill(memKey) removes a shared memory segment */ /* (only called by the postmaster and standalone backends) */ /****************************************************************************/ void IpcMemoryKill(memKey) IpcMemoryKey memKey; { IpcMemoryId shmid; if (!UsePrivateMemory && (shmid = shmget(memKey, 0, 0)) >= 0) { if (shmctl(shmid, IPC_RMID, (struct shmid_ds *) NULL) < 0) { elog(NOTICE, "IpcMemoryKill: shmctl(%d, %d, 0) failed: %m", shmid, IPC_RMID); } } } #ifdef HAS_TEST_AND_SET /* ------------------ * use hardware locks to replace semaphores for sequent machines * to avoid costs of swapping processes and to provide unlimited * supply of locks. * ------------------ */ static SLock *SLockArray = NULL; static SLock **FreeSLockPP; static int *UnusedSLockIP; static slock_t *SLockMemoryLock; static IpcMemoryId SLockMemoryId = -1; struct ipcdummy { /* to get alignment/size right */ SLock *free; int unused; slock_t memlock; SLock slocks[NSLOCKS]; }; static int SLockMemorySize = sizeof(struct ipcdummy); void CreateAndInitSLockMemory(key) IPCKey key; { int id; SLock *slckP; SLockMemoryId = IpcMemoryCreate(key, SLockMemorySize, 0700); AttachSLockMemory(key); *FreeSLockPP = NULL; *UnusedSLockIP = (int)FIRSTFREELOCKID; for (id=0; id<(int)FIRSTFREELOCKID; id++) { slckP = &(SLockArray[id]); S_INIT_LOCK(&(slckP->locklock)); slckP->flag = NOLOCK; slckP->nshlocks = 0; S_INIT_LOCK(&(slckP->shlock)); S_INIT_LOCK(&(slckP->exlock)); S_INIT_LOCK(&(slckP->comlock)); slckP->next = NULL; } return; } void AttachSLockMemory(key) IPCKey key; { struct ipcdummy *slockM; if (SLockMemoryId == -1) SLockMemoryId = IpcMemoryIdGet(key,SLockMemorySize); if (SLockMemoryId == -1) elog(FATAL, "SLockMemory not in shared memory"); slockM = (struct ipcdummy *) IpcMemoryAttach(SLockMemoryId); if (slockM == IpcMemAttachFailed) elog(FATAL, "AttachSLockMemory: could not attach segment"); FreeSLockPP = (SLock **) &(slockM->free); UnusedSLockIP = (int *) &(slockM->unused); SLockMemoryLock = (slock_t *) &(slockM->memlock); S_INIT_LOCK(SLockMemoryLock); SLockArray = (SLock *) &(slockM->slocks[0]); return; } int CreateLock() { int lockid; SLock *slckP; S_LOCK(SLockMemoryLock); if (*FreeSLockPP != NULL) { lockid = *FreeSLockPP - SLockArray; *FreeSLockPP = (*FreeSLockPP)->next; } else { lockid = *UnusedSLockIP; (*UnusedSLockIP)++; } slckP = &(SLockArray[lockid]); S_INIT_LOCK(&(slckP->locklock)); slckP->flag = NOLOCK; slckP->nshlocks = 0; S_INIT_LOCK(&(slckP->shlock)); S_INIT_LOCK(&(slckP->exlock)); S_INIT_LOCK(&(slckP->comlock)); slckP->next = NULL; S_UNLOCK(SLockMemoryLock); return lockid; } void RelinquishLock(lockid) int lockid; { SLock *slckP; slckP = &(SLockArray[lockid]); S_LOCK(SLockMemoryLock); slckP->next = *FreeSLockPP; *FreeSLockPP = slckP; S_UNLOCK(SLockMemoryLock); return; } #ifdef LOCKDEBUG extern int MyPid; #define PRINT_LOCK(LOCK) printf("(locklock = %d, flag = %d, nshlocks = %d, \ shlock = %d, exlock =%d)\n", LOCK->locklock, \ LOCK->flag, LOCK->nshlocks, LOCK->shlock, \ LOCK->exlock) #endif void SharedLock(lockid) int lockid; { SLock *slckP; #ifdef PARALLELDEBUG BeginParallelDebugInfo(PDI_SHAREDLOCK); #endif slckP = &(SLockArray[lockid]); #ifdef LOCKDEBUG printf("Proc %d SharedLock(%d)\n", MyPid, lockid); printf("IN: "); PRINT_LOCK(slckP); #endif sh_try_again: S_LOCK(&(slckP->locklock)); switch (slckP->flag) { case NOLOCK: slckP->flag = SHAREDLOCK; slckP->nshlocks = 1; S_LOCK(&(slckP->exlock)); S_UNLOCK(&(slckP->locklock)); #ifdef LOCKDEBUG printf("OUT: "); PRINT_LOCK(slckP); #endif #ifdef PARALLELDEBUG EndParallelDebugInfo(PDI_SHAREDLOCK); #endif return; case SHAREDLOCK: (slckP->nshlocks)++; S_UNLOCK(&(slckP->locklock)); #ifdef LOCKDEBUG printf("OUT: "); PRINT_LOCK(slckP); #endif #ifdef PARALLELDEBUG EndParallelDebugInfo(PDI_SHAREDLOCK); #endif return; case EXCLUSIVELOCK: (slckP->nshlocks)++; S_UNLOCK(&(slckP->locklock)); S_LOCK(&(slckP->shlock)); (slckP->nshlocks)--; S_UNLOCK(&(slckP->comlock)); goto sh_try_again; } } void SharedUnlock(lockid) int lockid; { SLock *slckP; slckP = &(SLockArray[lockid]); #ifdef LOCKDEBUG printf("Proc %d SharedUnlock(%d)\n", MyPid, lockid); printf("IN: "); PRINT_LOCK(slckP); #endif S_LOCK(&(slckP->locklock)); (slckP->nshlocks)--; if (slckP->nshlocks == 0) { slckP->flag = NOLOCK; S_UNLOCK(&(slckP->exlock)); } S_UNLOCK(&(slckP->locklock)); #ifdef LOCKDEBUG printf("OUT: "); PRINT_LOCK(slckP); #endif return; } void ExclusiveLock(lockid) int lockid; { SLock *slckP; #ifdef PARALLELDEBUG BeginParallelDebugInfo(PDI_EXCLUSIVELOCK); #endif slckP = &(SLockArray[lockid]); #ifdef LOCKDEBUG printf("Proc %d ExclusiveLock(%d)\n", MyPid, lockid); printf("IN: "); PRINT_LOCK(slckP); #endif ex_try_again: S_LOCK(&(slckP->locklock)); switch (slckP->flag) { case NOLOCK: slckP->flag = EXCLUSIVELOCK; S_LOCK(&(slckP->exlock)); S_LOCK(&(slckP->shlock)); S_UNLOCK(&(slckP->locklock)); #ifdef LOCKDEBUG printf("OUT: "); PRINT_LOCK(slckP); #endif #ifdef PARALLELDEBUG EndParallelDebugInfo(PDI_EXCLUSIVELOCK); #endif return; case SHAREDLOCK: case EXCLUSIVELOCK: S_UNLOCK(&(slckP->locklock)); S_LOCK(&(slckP->exlock)); S_UNLOCK(&(slckP->exlock)); goto ex_try_again; } } void ExclusiveUnlock(lockid) int lockid; { SLock *slckP; int i; slckP = &(SLockArray[lockid]); #ifdef LOCKDEBUG printf("Proc %d ExclusiveUnlock(%d)\n", MyPid, lockid); printf("IN: "); PRINT_LOCK(slckP); #endif S_LOCK(&(slckP->locklock)); /* ------------- * give favor to read processes * ------------- */ slckP->flag = NOLOCK; if (slckP->nshlocks > 0) { while (slckP->nshlocks > 0) { S_UNLOCK(&(slckP->shlock)); S_LOCK(&(slckP->comlock)); } S_UNLOCK(&(slckP->shlock)); } else { S_UNLOCK(&(slckP->shlock)); } S_UNLOCK(&(slckP->exlock)); S_UNLOCK(&(slckP->locklock)); #ifdef LOCKDEBUG printf("OUT: "); PRINT_LOCK(slckP); #endif return; } bool LockIsFree(lockid) int lockid; { return(SLockArray[lockid].flag == NOLOCK); } #endif /* HAS_TEST_AND_SET */ @ 1.44 log @fix shmem size allocation calculation to account for padding @ text @d6 1 a6 1 * $Header: /import/faerie/faerie/aoki/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.43 1993/10/31 23:26:35 aoki Exp aoki $ d562 1 d564 1 a564 1 semncnt = semctl(semId, sem, GETNCNT, NULL); d574 1 d576 1 a576 1 semval = semctl(semId, sem, GETVAL, NULL); @ 1.43 log @added IpcMemoryDetach @ text @d6 1 a6 1 * $Header: /faerie/aoki/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.42 1993/08/10 01:46:51 marc Exp aoki $ a440 1 #ifndef SINGLE_USER a441 3 #else errStatus = 0; #endif a476 1 #ifndef SINGLE_USER a477 3 #else 0; #endif a513 1 #ifndef SINGLE_USER a514 3 #else errStatus = 0; #endif a552 1 #ifndef SINGLE_USER a553 3 #else 0; #endif d750 8 a757 2 static int SLockMemorySize = sizeof(SLock*) + sizeof(int) + sizeof(slock_t) + NSLOCKS*sizeof(SLock); d788 2 a789 1 char *slockM; d794 1 a794 1 slockM = IpcMemoryAttach(SLockMemoryId); d797 3 a799 3 FreeSLockPP = (SLock**)slockM; UnusedSLockIP = (int*)(FreeSLockPP + 1); SLockMemoryLock = (slock_t*)(UnusedSLockIP + 1); d801 1 a801 1 SLockArray = (SLock*)LONGALIGN((SLockMemoryLock + 1)); @ 1.42 log @alpha port @ text @d6 1 a6 1 * $Header: /usr/local/devel/postgres.alpha.merge/src/backend/storage/ipc/RCS/ipc.c,v 1.41 1993/07/27 00:53:55 aoki Exp marc $ d209 4 a212 1 shmctl(shmId, IPC_RMID, (struct shmid_ds *)NULL); d688 14 d717 2 a718 2 if ( UsePrivateMemory ) { memAddress = (char *)PrivateMemoryAttach ( memId , 0 , 0 ); d729 3 d738 1 a738 1 /* */ d747 4 a750 1 shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0); @ 1.41 log @bzero new pages to shut up purify. probably ought to #ifdef this. @ text @d6 1 a6 1 * $Header: /home2/aoki/master/src/backend/storage/ipc/RCS/ipc.c,v 1.42 1993/07/21 07:08:08 aoki Exp $ d26 1 a26 1 #include "tmp/align.h" @ 1.40 log @bogus check that lost error message before exiting. @ text @d6 1 a6 1 * $Header: /usr/local/devel/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.39 1992/12/31 02:32:59 marc Exp marc $ d74 1 @ 1.39 log @-DPORTNAME_bsd44 (duh...) @ text @d6 1 a6 1 * $Header: /usr/local/devel/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.38 1992/12/30 17:21:17 marc Exp marc $ d447 1 a447 7 if (!ParallelExecutorEnabled() && errno == EIDRM) /* * this is a hack. currently the master backend kills the * slave backend by removing the semaphores that they are waiting * on. does not want it to complain. */ perror("semop"); @ 1.38 log @no IPC on bsd44 yet. @ text @d6 1 a6 1 * $Header: /a/staff/marc/src/postgres/src/backend/storage/ipc/RCS/ipc.c,v 1.37 91/10/16 16:56:46 hong Exp Locker: marc $ d30 1 a30 1 #if PORTNAME == bsd44 @ 1.37 log @give more accurate termination condition to slave backends @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.36 91/09/05 23:28:23 hong Exp $ a18 2 #ifndef sequent a21 8 #else #include "/usr/att/usr/include/sys/ipc.h" #include "/usr/att/usr/include/sys/sem.h" #include "/usr/att/usr/include/sys/shm.h" #endif /* defined(sequent) */ d30 3 d34 1 @ 1.36 log @fix sequent compilation errors @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.35 91/08/29 23:54:07 mer Exp $ d453 1 a453 1 if (!ParallelExecutorEnabled()) @ 1.35 log @purge old lmgr code @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.34 91/08/14 12:32:37 mer Exp $ d760 1 a760 1 LockId id; d802 1 a802 1 SemId d852 1 a852 1 SemId lockid; d903 1 a903 1 SemId lockid; d928 1 a928 1 SemId lockid; d967 1 a967 1 SemId lockid; d1005 1 a1005 1 SemId lockid; @ 1.34 log @add quasi_exitpg - run all exitpg scripts without exiting!! @ text @d6 1 a6 1 * $Header: /users/mer/postgres/src/storage/ipc/RCS/ipc.c,v 1.33 91/07/24 10:06:28 hong Exp Locker: mer $ a35 1 #include "storage/plparam.h" d252 1 a252 1 ushort array[NMAXSEM]; d257 1 a257 1 if (semNum > NMAXSEM || semNum <= 0) { d331 1 a331 1 ushort array[NMAXSEM]; d336 1 a336 1 if (semNum > NMAXSEM || semNum <= 0) { @ 1.33 log @fixed a compilation error @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.32 91/07/24 07:46:49 mao Exp Locker: hong $ d131 33 @ 1.32 log @cleanup and add main memory storage manager @ text @d6 1 a6 1 * $Header: /users/mao/postgres/src/storage/ipc/RCS/ipc.c,v 1.31 1991/07/17 23:45:36 hong Exp $ d736 2 a737 2 *UnusedSLockIP = (SLock) FIRSTFREELOCKID; for (id=0; id<(LockId)FIRSTFREELOCKID; id++) { @ 1.31 log @include slaves.h to get rid of some compile warnings @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.30 91/06/12 10:18:47 kemnitz Exp Locker: hong $ d736 2 a737 2 *UnusedSLockIP = FIRSTFREELOCKID; for (id=0; id IpcMaxNumSem || semNum <= 0) { d297 1 a297 1 ushort array[IpcMaxNumSem]; d302 1 a302 1 if (semNum > IpcMaxNumSem || semNum <= 0) { @ 1.25 log @measure time spent in locking for debugging of parallel executor @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.24 91/02/28 21:46:04 hong Exp $ d41 1 a41 5 #include usclk_t ExclusiveLockTime; usclk_t SharedLockTime; int ExclusiveLockCount; int SharedLockCount; d805 1 a805 3 usclk_t st; st = getusclk(); SharedLockCount++; d826 1 a826 1 SharedLockTime += (getusclk() - st); d837 1 a837 1 SharedLockTime += (getusclk() - st); d881 1 a881 3 usclk_t st; st = getusclk(); ExclusiveLockCount++; d902 1 a902 1 ExclusiveLockTime += (getusclk() - st); @ 1.24 log @tell slave backends to shut up when exiting. @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.23 91/02/18 20:39:25 hong Exp Locker: hong $ d40 8 d808 5 d831 3 d842 3 d886 5 d908 3 @ 1.23 log @specify size for SLock memory for sequent @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.22 91/01/18 22:15:21 hong Exp Locker: hong $ d410 7 a416 1 perror("semop"); @ 1.22 log @added two new routines for semaphore handling @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.21 90/11/28 20:57:13 hong Exp Locker: hong $ d693 2 d703 1 a703 4 sizeof(SLock*) + sizeof(int) + sizeof(slock_t) + NSLOCKS*sizeof(SLock), d705 1 a705 1 AttachSLockMemory(); d727 1 a727 1 SLockMemoryId = IpcMemoryIdGet(key,0); @ 1.21 log @fixed the locking routines , now deadlock free @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.20 90/11/12 08:15:19 hong Exp Locker: hong $ d519 21 @ 1.20 log @initialize reserved locks @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.19 90/11/07 12:06:07 hong Exp Locker: hong $ d695 1 d742 1 d806 1 a806 1 S_UNLOCK(&(slckP->shlock)); d889 1 a889 1 while (slckP->nshlocks > 0) d891 3 d906 8 @ 1.19 log @changes in the locking routines for sequent @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.18 90/10/23 17:19:06 kemnitz Exp Locker: hong $ d676 3 d687 10 a696 1 *UnusedSLockIP = 3; /* 0, 1, 2 are reserved */ @ 1.18 log @fixed problem with SLocks on sequent when postmaster is run @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.17 90/10/17 17:09:19 hong Exp $ d747 8 d761 6 d772 1 d774 4 d782 4 d791 3 a793 2 SharedLock(lockid); return; d803 5 d815 4 d828 6 d838 2 d841 4 d850 2 a851 2 ExclusiveLock(lockid); return; d860 2 d863 5 d875 2 a876 2 slckP->nshlocks = 0; S_UNLOCK(&(slckP->shlock)); d879 1 a879 1 S_UNLOCK(&(slckP->exlock)); d881 1 d883 4 @ 1.17 log @to complain when malloc out of memory @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.16 90/10/16 23:33:06 hong Exp Locker: hong $ d689 2 a690 1 AttachSLockMemory() d694 3 a696 1 elog(FATAL, "SLockMemory not in shared memory"); @ 1.16 log @replace semaphores with hardware locks for sequent @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.15 90/10/02 12:11:10 goh Exp Locker: hong $ d72 2 @ 1.15 log @yet another fix to coexist peacefully with parallel executor @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.13 90/09/30 15:53:11 goh Exp $ d36 1 d657 171 @ 1.14 log @fix for parallel stuff @ text @d533 1 a533 1 if ( memKey == PrivateIPCKey ) { d570 1 a570 1 if ( memKey == PrivateIPCKey ) { @ 1.13 log @cleaned up dependencies ... also, if running standalone, uses private instead of shared memory @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.12 90/08/14 15:41:42 cimarron Exp $ d570 7 a576 1 shmid = shmget(memKey, size, IPC_CREAT|permission); @ 1.12 log @Updating from revision 1.11 to revision 1.12 @ text @d10 1 d13 2 d16 1 d19 2 a20 1 #ifndef sequent a21 6 #else #include "/usr/att/usr/include/sys/ipc.h" #endif #endif #ifndef sequent d24 1 d26 2 d30 2 a33 2 #include d37 2 d53 4 d58 27 d169 5 a173 1 shmctl(shmId, IPC_RMID, (struct shmid_ds *)NULL); d223 6 d230 1 d251 8 a258 1 d516 1 d532 8 a539 2 shmid = shmget(memKey, size, IPC_CREAT|permission); d541 2 d572 2 d594 1 d596 2 d620 6 a625 3 /* memAddress = (char *) malloc(sizeof(int)); XXX ??? */ memAddress = (char *) shmat(memId, 0, 0); a630 10 /* XXX huh? switch (errno) { case EINVAL: case EACCES: case ENOMEM: case EMFILE: perror("IpcMemoryAttach: shmat() failed:"); return(IpcMemAttachFailed); } */ d646 1 a646 1 if ((shmid = shmget(memKey, 0, 0)) >= 0) { @ 1.11 log @Added sequent compatilibity stuff @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.10 90/03/31 19:00:31 cimarron Exp Locker: kemnitz $ d32 2 a33 2 #include "ipci.h" /* for PrivateIPCKey XXX */ #include "ipc.h" @ 1.10 log @*** empty log message *** @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.9 90/03/12 16:26:40 cimarron Exp $ d15 1 d17 2 d20 1 d22 1 d25 5 @ 1.9 log @Integration Checkin @ text @d1 1 a1 1 /* d6 2 a7 1 * $Header: RCS/ipc.c,v 1.8 90/02/13 00:27:54 kemnitz Exp $ d49 1 d57 15 a104 1 static a118 1 static d199 60 d260 1 d264 1 d266 2 d269 4 a272 1 IpcSemaphoreSet(semId, value) a273 1 int i; a274 2 int semId; ushort array[IpcMaxNumSem]; d277 3 a279 1 /* **** RESUME HERE **** */ d281 1 a281 3 semun.array = array; errStatus = semctl(semId, 0, SETALL, semun); if (errStatus == -1) { a282 1 } d308 1 d310 2 d318 1 d326 17 a342 1 errStatus = semop(semId, (struct sembuf **)&sops, 1); d349 10 d360 17 d378 1 a378 1 /* IpcSemaphoreUnLock(semId, sem, lock) - unlocks a semaphore */ d380 1 d382 2 d390 1 d397 1 d399 17 a415 1 errStatus = semop(semId, (struct sembuf **)&sops, 1); d422 13 d436 16 a452 1 d478 26 @ 1.8 log @Added "code" to arg list of exitpg() @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.7 90/02/12 19:48:10 cimarron Exp Locker: kemnitz $ d184 22 @ 1.7 log @added buffer manager statistics and exitpg() stuff -cim @ text @d6 1 a6 1 * $Header: RCS/ipc.c,v 1.6 89/09/05 17:23:33 mao C_Demo_1 $ d56 1 a56 1 (*onexit_list[i].function)(onexit_list[i].arg); @ 1.6 log @Working version of C-only demo @ text @d6 1 a6 1 * $Header: /usr6/postgres/mao/postgres/src/storage/ipc/RCS/ipc.c,v 1.5 89/08/03 00:06:06 dillon Exp $ d11 1 d16 1 d20 1 a21 1 d24 3 a26 3 /* * IPCPrivateSemaphoreKill -- * On_exit(3) termination handler. d28 21 a48 1 extern d50 4 a53 4 IPCPrivateSemaphoreKill ARGS(( int status, int semId )); d55 12 a66 3 /* * IPCPrivateMemoryKill -- * On_exit(3) termination handler. d68 21 a88 1 extern d90 7 a96 4 IPCPrivateMemoryKill ARGS(( int status, int shmId )); d98 1 d100 14 d115 7 a121 5 /* - returns a semaphore identifier: */ /* if key doesn't exist: return a new id, status:= IpcSemIdNotExist */ /* if key exists: return the old id, status:= IpcSemIdExist */ /* if semNum > MAX : return # of argument, status:=IpcInvalidArgument*/ /* */ d123 1 d134 1 d137 5 a141 5 IpcSemaphoreKey semKey; /* input patameter */ int semNum; /* input patameter */ int permission; /* input patameter */ int semStartValue; /* input patameter */ int *status; /* output parameter */ d143 20 a162 34 int i; int errStatus; int semId; ushort array[IpcMaxNumSem]; union semun semun; /* get a semaphore if non-existent */ /* check arguments */ if (semNum > IpcMaxNumSem || semNum <= 0) { *status = IpcInvalidArgument; return(2); /* returns the number of the invalid argument */ } semId = semget(semKey, 0, 0); if (semId == -1) { *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */ semId = semget(semKey, semNum, IPC_CREAT|permission); if (semId < 0) { perror("semget"); exit(3); } for (i = 0; i < semNum; i++) { array[i] = semStartValue; } semun.array = array; errStatus = semctl(semId, 0, SETALL, semun); if (errStatus == -1) { perror("semctl"); } /* if (semKey == PrivateIPCKey) */ on_exit(IPCPrivateSemaphoreKill, (caddr_t)semId); } else { /* there is a semaphore id for this key */ *status = IpcSemIdExist; d164 18 a181 1 return(semId); d186 2 a187 2 /* IpcSemaphoreKill(key) - removes a semaphore */ /* */ d191 1 a191 1 IpcSemaphoreKey key; d193 10 a202 11 int i, semId; int status; /* kill semaphore if existent */ semId = semget(key, 0, 0); if (semId != -1) { union semun semun; semctl(semId, 0, IPC_RMID, semun); } d206 2 a207 2 /* IpcSemaphoreLock(semId, sem, lock) - locks a semaphore */ /* */ d211 3 a213 3 IpcSemaphoreId semId; int sem; int lock; d215 12 a226 12 int errStatus; struct sembuf sops; sops.sem_op = lock; sops.sem_flg = 0; sops.sem_num = sem; errStatus = semop(semId, (struct sembuf **)&sops, 1); if (errStatus == -1) { perror("semop"); exit(255); } d231 2 a232 2 /* IpcSemaphoreUnLock(semId, sem, lock) - unlocks a semaphore */ /* */ d236 3 a238 3 IpcSemaphoreId semId; int sem; int lock; d240 12 a251 12 int errStatus; struct sembuf sops; sops.sem_op = -lock; sops.sem_flg = 0; sops.sem_num = sem; errStatus = semop(semId, (struct sembuf **)&sops, 1); if (errStatus == -1) { perror("semop"); exit(255); } d258 4 a261 3 /* IpcMemoryCreate(memKey) */ /* - returns the memory identifier, if creation succeeds*/ /* returns IpcMemCreationFailed, if failure */ d263 1 d266 3 a268 3 IpcMemoryKey memKey; uint32 size; int permission; d270 13 a282 13 IpcMemoryId shmid; int errStatus; shmid = shmget(memKey, size, IPC_CREAT|permission); if (shmid < 0) { perror("IpcMemoryCreate: shmget(..., create, ...) failed"); return(IpcMemCreationFailed); } /* if (memKey == PrivateIPCKey) */ on_exit(IPCPrivateMemoryKill, (caddr_t)shmid); return(shmid); d287 2 a288 2 /* IpcMemoryIdGet(memKey, size) returns the shared memory Id */ /* or IpcMemIdGetFailed */ d292 2 a293 2 IpcMemoryKey memKey; uint32 size; d295 9 a303 8 IpcMemoryId shmid; shmid = shmget(memKey, size, 0); if (shmid < 0) { perror("IpcMemoryIdGet: shmget() failed"); return(IpcMemIdGetFailed); } return(shmid); d308 5 a312 5 /* IpcMemoryAttach(memId) returns the adress of shared memory */ /* or IpcMemAttachFailed */ /* */ /* CALL IT: addr = (struct *) IpcMemoryAttach(memId); */ /* */ d316 1 a316 1 IpcMemoryId memId; d318 23 a340 20 char *memAddress; int errStatus; /* memAddress = (char *) malloc(sizeof(int)); XXX ??? */ memAddress = (char *) shmat(memId, 0, 0); /* if ( *memAddress == -1) { XXX ??? */ if ( memAddress == (char *)-1) { perror("IpcMemoryAttach: shmat() failed"); return(IpcMemAttachFailed); } /* XXX huh? switch (errno) { case EINVAL: case EACCES: case ENOMEM: case EMFILE: perror("IpcMemoryAttach: shmat() failed:"); return(IpcMemAttachFailed); } */ return((char *) memAddress); d345 2 a346 2 /* IpcMemoryKill(memKey) removes a shared memory segment */ /* */ d350 1 a350 1 IpcMemoryKey memKey; d352 5 a356 5 IpcMemoryId shmid; if ((shmid = shmget(memKey, 0, 0)) >= 0) { shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0); } a357 19 static void IPCPrivateSemaphoreKill(status, semId) int status; int semId; /* caddr_t */ { union semun semun; semctl(semId, 0, IPC_RMID, semun); } static void IPCPrivateMemoryKill(status, shmId) int status; int shmId; /* caddr_t */ { shmctl(shmId, IPC_RMID, (struct shmid_ds *)NULL); } @ 1.5 log @shared memory lock manager code (does not used semaphores) @ text @d6 1 a6 1 * $Header: ipc.c,v 1.2 89/02/02 16:15:58 dillon Locked $ @ 1.4 log @*** empty log message *** @ text @d6 1 a6 1 * $Header: /usr6/postgres/dillon/ptree/src/storage/ipc/RCS/ipc.c,v 1.3 89/04/14 18:31:00 dillon Exp $ a8 1 #include a82 3 /* printf("%d = semget(%d,%d,0%od)\n", semId, semKey, semNum, permission); */ d84 1 a84 1 *status = IpcSemIdNotExist;/* there doesn't exist a semaphore*/ a85 5 /* printf("%d = semget(%d,%d,0%od)\n", semId, semKey, semNum, IPC_CREAT|permission ); */ a198 4 fprintf(stderr, "Arguments: memKey=%08lx, size=%ld, perm=0%o\n", memKey, size, permission | IPC_CREAT ); @ 1.3 log @*** empty log message *** @ text @d6 1 a6 1 * $Header: /usr6/postgres/dillon/ptree/src/storage/ipc/RCS/ipc.c,v 1.2 89/02/02 16:15:58 dillon Stab $ d84 3 d88 1 a88 1 *status = IpcSemIdNotExist; /* there doesn't exist a semaphore */ d90 5 @ 1.2 log @Txfer from old tree @ text @d6 1 a6 1 * $Header: ipc.c,v 1.1 88/06/15 17:15:38 dillon Locked $ d9 1 d200 4 @ 1.1 log @Initial revision @ text @a0 1 a1 26 * * POSTGRES Data Base Management System * * Copyright (c) 1988 Regents of the University of California * * Permission to use, copy, modify, and distribute this software and its * documentation for educational, research, and non-profit purposes and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of the University of California not be used in advertising * or publicity pertaining to distribution of the software without * specific, written prior permission. Permission to incorporate this * software into commercial products can be obtained from the Campus * Software Office, 295 Evans Hall, University of California, Berkeley, * Ca., 94720 provided only that the the requestor give the University * of California a free licence to any derived software for educational * and research purposes. The University of California makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /* d6 1 a6 1 * $Header: ipc.c,v 1.1 88/11/11 16:37:37 postgres Exp $ @