Пример #1
0
/*
 * PGSemaphoreCreate
 *
 * Allocate a PGSemaphore structure with initial count 1
 */
PGSemaphore
PGSemaphoreCreate(void)
{
	PGSemaphore sema;

	/* Can't do this in a backend, because static state is postmaster's */
	Assert(!IsUnderPostmaster);

	if (nextSemaNumber >= SEMAS_PER_SET)
	{
		/* Time to allocate another semaphore set */
		if (numSemaSets >= maxSemaSets)
			elog(PANIC, "too many semaphores created");
		mySemaSets[numSemaSets] = IpcSemaphoreCreate(SEMAS_PER_SET);
		numSemaSets++;
		nextSemaNumber = 0;
	}
	/* Use the next shared PGSemaphoreData */
	if (numSharedSemas >= maxSharedSemas)
		elog(PANIC, "too many semaphores created");
	sema = &sharedSemas[numSharedSemas++];
	/* Assign the next free semaphore in the current set */
	sema->semId = mySemaSets[numSemaSets - 1];
	sema->semNum = nextSemaNumber++;
	/* Initialize it to count 1 */
	IpcSemaphoreInitialize(sema->semId, sema->semNum, 1);

	return sema;
}
Пример #2
0
/*
 * PGSemaphoreCreate
 *
 * Initialize a PGSemaphore structure to represent a sema with count 1
 */
void
PGSemaphoreCreate(PGSemaphore sema)
{
	/* Can't do this in a backend, because static state is postmaster's */
	Assert(!IsUnderPostmaster);

	if (nextSemaNumber >= SEMAS_PER_SET)
	{
		/* Time to allocate another semaphore set */
		if (numSemaSets >= maxSemaSets)
			elog(PANIC, "too many semaphores created");
		mySemaSets[numSemaSets] = IpcSemaphoreCreate(SEMAS_PER_SET);
		numSemaSets++;
		nextSemaNumber = 0;
	}
	/* Assign the next free semaphore in the current set */
	sema->semId = mySemaSets[numSemaSets - 1];
	sema->semNum = nextSemaNumber++;
	/* Initialize it to count 1 */
	IpcSemaphoreInitialize(sema->semId, sema->semNum, 1);

	elog((Debug_print_semaphore_detail ? LOG : DEBUG5),
		 "created SYSV semaphore semId %d, semNum %d",
		 sema->semId, sema->semNum);
}
Пример #3
0
/*
 * CreateSpinlocks -- Create a sysV semaphore array for
 *	the spinlocks
 *
 */
bool
CreateSpinlocks(IPCKey key)
{
    
    int status;
    IpcSemaphoreId semid;
    semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection, 
			       IpcSemaphoreDefaultStartValue, 1, &status);
    if (status == IpcSemIdExist) {
	IpcSemaphoreKill(key);
	elog(NOTICE,"Destroying old spinlock semaphore");
	semid = IpcSemaphoreCreate(key, MAX_SPINS, IPCProtection, 
				   IpcSemaphoreDefaultStartValue, 1, &status);
    }
    
    if (semid >= 0) {
	SpinLockId = semid;
	return(TRUE);
    }
    /* cannot create spinlocks */
    elog(FATAL,"CreateSpinlocks: cannot create spin locks");
    return(FALSE);
}
Пример #4
0
/* ------------------------
 * InitProc -- create a per-process data structure for this process
 * used by the lock manager on semaphore queues.
 * ------------------------
 */
void
InitProcess(IPCKey key)
{
    bool found = false;
    int pid;
    int semstat;
    unsigned long location, myOffset;
    
    /* ------------------
     * Routine called if deadlock timer goes off. See ProcSleep()
     * ------------------
     */
#ifndef WIN32
    signal(SIGALRM, HandleDeadLock);
#endif /* WIN32 we'll have to figure out how to handle this later */

    SpinAcquire(ProcStructLock);
    
    /* attach to the free list */
    ProcGlobal = (PROC_HDR *)
	ShmemInitStruct("Proc Header",(unsigned)sizeof(PROC_HDR),&found);
    if (!found) {
	/* this should not happen. InitProcGlobal() is called before this. */
	elog(WARN, "InitProcess: Proc Header uninitialized");
    }
    
    if (MyProc != NULL)
	{
	    SpinRelease(ProcStructLock);
	    elog(WARN,"ProcInit: you already exist");
	    return;
	}
    
    /* try to get a proc from the free list first */
    
    myOffset = ProcGlobal->freeProcs;
    
    if (myOffset != INVALID_OFFSET)
	{
	    MyProc = (PROC *) MAKE_PTR(myOffset);
	    ProcGlobal->freeProcs = MyProc->links.next;
	}
    else
	{
	    /* have to allocate one.  We can't use the normal binding
	     * table mechanism because the proc structure is stored
	     * by PID instead of by a global name (need to look it
	     * up by PID when we cleanup dead processes).
	     */
	    
	    MyProc = (PROC *) ShmemAlloc((unsigned)sizeof(PROC));
	    if (! MyProc)
		{
		    SpinRelease(ProcStructLock);
		    elog (FATAL,"cannot create new proc: out of memory");
		}
	    
	    /* this cannot be initialized until after the buffer pool */
	    SHMQueueInit(&(MyProc->lockQueue));
	    MyProc->procId = ProcGlobal->numProcs;
	    ProcGlobal->numProcs++;
	}
    
    /*
     * zero out the spin lock counts and set the sLocks field for
     * ProcStructLock to 1 as we have acquired this spinlock above but 
     * didn't record it since we didn't have MyProc until now.
     */
    memset(MyProc->sLocks, 0, sizeof(MyProc->sLocks));
    MyProc->sLocks[ProcStructLock] = 1;


    if (IsUnderPostmaster) {
	IPCKey semKey;
	int semNum;
	int semId;
	union semun semun;

	ProcGetNewSemKeyAndNum(&semKey, &semNum);
	
	semId = IpcSemaphoreCreate(semKey,
				   PROC_NSEMS_PER_SET,
				   IPCProtection,
				   IpcSemaphoreDefaultStartValue,
				   0,
				   &semstat);
	/*
	 * we might be reusing a semaphore that belongs to a dead
	 * backend. So be careful and reinitialize its value here.
	 */
	semun.val = IpcSemaphoreDefaultStartValue;
	semctl(semId, semNum, SETVAL, semun);

	IpcSemaphoreLock(semId, semNum, IpcExclusiveLock);
	MyProc->sem.semId = semId;
	MyProc->sem.semNum = semNum;
	MyProc->sem.semKey = semKey;
    } else {
	MyProc->sem.semId = -1;
    }
    
    /* ----------------------
     * Release the lock.
     * ----------------------
     */
    SpinRelease(ProcStructLock);
    
    MyProc->pid = 0;
#if 0
    MyProc->pid = MyPid;
#endif
    
    /* ----------------
     * Start keeping spin lock stats from here on.  Any botch before
     * this initialization is forever botched
     * ----------------
     */
    memset(MyProc->sLocks, 0, MAX_SPINS*sizeof(*MyProc->sLocks));
    
    /* -------------------------
     * Install ourselves in the binding 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.
     * -------------------------
     */
    pid = getpid();
    location = MAKE_OFFSET(MyProc);
    if ((! ShmemPIDLookup(pid,&location)) || (location != MAKE_OFFSET(MyProc)))
	{
	    elog(FATAL,"InitProc: ShmemPID table broken");
	}
    
    MyProc->errType = NO_ERROR;
    SHMQueueElemInit(&(MyProc->links));
    
    on_exitpg(ProcKill, (caddr_t)pid);
    
    ProcInitialized = TRUE;
}