📄 shmem.c
字号:
infoP->dir = (long *) (((char *) location) + sizeof(HHDR)); 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. */boolShmemPIDLookup(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_OFFSETShmemPIDDestroy(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 * memory. * * This is called during initialization to find or allocate * a data structure in shared memory. If no other processes * have created the structure, this routine allocates space * for it. If it exists already, a pointer to the existing * table is returned. * * Returns: real pointer to the object. FoundPtr is TRUE if * the object is already in the shmem index (hence, already * initialized). */long *ShmemInitStruct(char *name, unsigned long size, bool *foundPtr){ ShmemIndexEnt *result, item; long *structPtr; strncpy(item.key, name, SHMEM_INDEX_KEYSIZE); item.location = BAD_LOCATION; SpinAcquire(ShmemIndexLock); if (!ShmemIndex) {#ifdef USE_ASSERT_CHECKING char *strname = "ShmemIndex";#endif /* * If the shmem index doesnt exist, we fake it. * * If we are creating the first shmem index, then let shmemalloc() * allocate the space for a new HTAB. Otherwise, find the old one * and return that. Notice that the ShmemIndexLock is held until * the shmem index has been completely initialized. */ Assert(!strcmp(name, strname)); if (ShmemBootstrap) { /* in POSTMASTER/Single process */ *foundPtr = FALSE; return (long *) ShmemAlloc(size); } else { Assert(ShmemIndexOffset); *foundPtr = TRUE; return (long *) MAKE_PTR(*ShmemIndexOffset); } } else { /* look it up in the shmem index */ result = (ShmemIndexEnt *) hash_search(ShmemIndex, (char *) &item, HASH_ENTER, foundPtr); } if (!result) { SpinRelease(ShmemIndexLock); elog(ERROR, "ShmemInitStruct: Shmem Index corrupted"); return NULL; } else if (*foundPtr) { /* * Structure is in the shmem index so someone else has allocated * it already. The size better be the same as the size we are * trying to initialize to or there is a name conflict (or worse). */ if (result->size != size) { SpinRelease(ShmemIndexLock); elog(NOTICE, "ShmemInitStruct: ShmemIndex entry size is wrong"); /* let caller print its message too */ return NULL; } structPtr = (long *) MAKE_PTR(result->location); } else { /* It isn't in the table yet. allocate and initialize it */ structPtr = ShmemAlloc((long) size); if (!structPtr) { /* out of memory */ Assert(ShmemIndex); hash_search(ShmemIndex, (char *) &item, HASH_REMOVE, foundPtr); SpinRelease(ShmemIndexLock); *foundPtr = FALSE; elog(NOTICE, "ShmemInitStruct: cannot allocate '%s'", name); return NULL; } result->size = size; result->location = MAKE_OFFSET(structPtr); } Assert(ShmemIsValid((unsigned long) structPtr)); SpinRelease(ShmemIndexLock); return structPtr;}/* * TransactionIdIsInProgress -- is given transaction running by some backend * * Strange place for this func, but we have to lookup process data structures * for all running backends. - vadim 11/26/96 * * We should keep all PROC structs not in ShmemIndex - this is too * general hash table... * */boolTransactionIdIsInProgress(TransactionId xid){ ShmemIndexEnt *result; PROC *proc; Assert(ShmemIndex); SpinAcquire(ShmemIndexLock); hash_seq((HTAB *) NULL); while ((result = (ShmemIndexEnt *) hash_seq(ShmemIndex)) != NULL) { if (result == (ShmemIndexEnt *) TRUE) { SpinRelease(ShmemIndexLock); return false; } if (result->location == INVALID_OFFSET || strncmp(result->key, "PID ", 4) != 0) continue; proc = (PROC *) MAKE_PTR(result->location); if (proc->xid == xid) { SpinRelease(ShmemIndexLock); return true; } } SpinRelease(ShmemIndexLock); elog(ERROR, "TransactionIdIsInProgress: ShmemIndex corrupted"); return false;}/* * GetSnapshotData -- returns information about running transactions. * * Yet another strange func for this place... - vadim 07/21/98 */SnapshotGetSnapshotData(bool serializable){ Snapshot snapshot = (Snapshot) malloc(sizeof(SnapshotData)); ShmemIndexEnt *result; PROC *proc; TransactionId cid = GetCurrentTransactionId(); TransactionId xid; uint32 count = 0; uint32 have = 32; Assert(ShmemIndex); snapshot->xip = (TransactionId *) malloc(have * sizeof(TransactionId)); snapshot->xmin = cid; SpinAcquire(ShmemIndexLock); /* * Unfortunately, we have to call ReadNewTransactionId() * after acquiring ShmemIndexLock above. It's not good because of * ReadNewTransactionId() does SpinAcquire(OidGenLockId) but * _necessary_. */ ReadNewTransactionId(&(snapshot->xmax)); hash_seq((HTAB *) NULL); while ((result = (ShmemIndexEnt *) hash_seq(ShmemIndex)) != NULL) { if (result == (ShmemIndexEnt *) TRUE) { if (serializable) MyProc->xmin = snapshot->xmin; /* Serializable snapshot must be computed before any other... */ Assert(MyProc->xmin != InvalidTransactionId); SpinRelease(ShmemIndexLock); snapshot->xcnt = count; return snapshot; } if (result->location == INVALID_OFFSET || strncmp(result->key, "PID ", 4) != 0) continue; proc = (PROC *) MAKE_PTR(result->location); /* * We don't use spin-locking when changing proc->xid * in GetNewTransactionId() and in AbortTransaction() !.. */ xid = proc->xid; if (proc == MyProc || xid < FirstTransactionId || xid >= snapshot->xmax) { /* * Seems that there is no sense to store xid >= snapshot->xmax * (what we got from ReadNewTransactionId above) in snapshot->xip * - we just assume that all xacts with such xid-s are running * and may be ignored. */ continue; } if (xid < snapshot->xmin) snapshot->xmin = xid; if (have == 0) { snapshot->xip = (TransactionId *) realloc(snapshot->xip, (count + 32) * sizeof(TransactionId)); have = 32; } snapshot->xip[count] = xid; have--; count++; } SpinRelease(ShmemIndexLock); free(snapshot->xip); free(snapshot); elog(ERROR, "GetSnapshotData: ShmemIndex corrupted"); return NULL;}/* * GetXmaxRecent -- returns oldest transaction that was running * when all current transaction was started. * It's used by vacuum to decide what deleted * tuples must be preserved in a table. * * And yet another strange func for this place... - vadim 03/18/99 */voidGetXmaxRecent(TransactionId *XmaxRecent){ ShmemIndexEnt *result; PROC *proc; TransactionId xmin; Assert(ShmemIndex); *XmaxRecent = GetCurrentTransactionId(); SpinAcquire(ShmemIndexLock); hash_seq((HTAB *) NULL); while ((result = (ShmemIndexEnt *) hash_seq(ShmemIndex)) != NULL) { if (result == (ShmemIndexEnt *) TRUE) { SpinRelease(ShmemIndexLock); return; } if (result->location == INVALID_OFFSET || strncmp(result->key, "PID ", 4) != 0) continue; proc = (PROC *) MAKE_PTR(result->location); xmin = proc->xmin; /* we don't use spin-locking in AbortTransaction() ! */ if (proc == MyProc || xmin < FirstTransactionId) continue; if (xmin < *XmaxRecent) *XmaxRecent = xmin; } SpinRelease(ShmemIndexLock); elog(ERROR, "GetXmaxRecent: ShmemIndex corrupted");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -