Return-Path: owner-postman Received: from localhost.Berkeley.EDU (localhost.Berkeley.EDU [127.0.0.1]) by nobozo.CS.Berkeley.EDU (8.6.9/8.6.3) with SMTP id AAA23796 for postgres-redist; Thu, 25 Aug 1994 00:13:25 -0700 Resent-From: POSTGRES mailing list Resent-Message-Id: <199408250713.AAA23796@nobozo.CS.Berkeley.EDU> Sender: owner-postman@postgres.Berkeley.EDU X-Return-Path: owner-postman Received: from faerie.CS.Berkeley.EDU (faerie.CS.Berkeley.EDU [128.32.37.53]) by nobozo.CS.Berkeley.EDU (8.6.9/8.6.3) with ESMTP id AAA23786 for ; Thu, 25 Aug 1994 00:13:24 -0700 Received: from localhost.Berkeley.EDU (localhost.Berkeley.EDU [127.0.0.1]) by faerie.CS.Berkeley.EDU (8.6.9/8.1B) with SMTP id AAA24838; Thu, 25 Aug 1994 00:13:19 -0700 Message-Id: <199408250713.AAA24838@faerie.CS.Berkeley.EDU> X-Authentication-Warning: faerie.CS.Berkeley.EDU: Host localhost.Berkeley.EDU didn't use HELO protocol From: aoki@cs.berkeley.edu (Paul M. Aoki) To: postgres@postgres.Berkeley.EDU Reply-To: aoki@cs.berkeley.edu (Paul M. Aoki) Subject: some random hacks... Date: Thu, 25 Aug 94 00:13:13 -0700 X-Sender: aoki@postgres.Berkeley.EDU Resent-To: postgres-redist@postgres.Berkeley.EDU X-Mts: smtp Resent-Date: Thu, 25 Aug 94 00:13:25 -0700 Resent-XMts: smtp here are some context diffs. they haven't been tested with any great rigor, you're on your own with these -- however, all but the one that is described last should be (at worst) innocuous on any system. still, save the old versions of your source in case you have to back out a change. (1) newbki.sh: i managed to break newbki, which is not so bad considering that the documentation for it was removed in 4.2, but here's a fix anyway. apply it. (2) postgres.faq: the FAQ is updated a bit. (3) postmaster.c: i threw in the environment variable fix that someone mentioned for the occasional "database xxx does not exist, bailing out..." that plagues some ports. this is probably a good one to apply -- it does seem to help under DEC OSF/1 2.0 and OSF/1 2.1, i don't know about other ports. (4) *all* of the other changes: spinlocks and some routines that use shared memory were kludged (to put it kindly) to work on multiprocessor sables (DEC 2100/A500MPs running the field-test DEC OSF/1 T3.0-2 (Rev. 307.2) -- these are hellishly cool boxes, every kid should have one!). if you *don't* have a multiprocessor sable, you may not want to apply these changes, since it is likely to slow things down on the platforms that don't have spinlocks (just ultrix, at this point, but if it ain't broke don't fix it, right?). -- Paul M. Aoki | University of California at Berkeley aoki@CS.Berkeley.EDU | Dept. of EECS, Computer Science Division (#1776) | Berkeley, CA 94720-1776 *** postgres-v4r2/./src/bin/newbki/newbki.sh Sun Dec 12 15:13:16 1993 --- postgres/./src/bin/newbki/newbki.sh Fri Jul 15 01:24:25 1994 *************** *** 52,57 **** for i in *.source do dest=`echo $i | sed 's/\.source$//'` ! sed -e "s/postgres PGUID/$name $pguid/" < $i > $dest done echo "Done. You must now run initdb." --- 52,58 ---- for i in *.source do dest=`echo $i | sed 's/\.source$//'` ! sed -e "s/postgres PGUID/$name $pguid/" \ ! -e "s/PGUID/$pguid/" < $i > $dest done echo "Done. You must now run initdb." *** postgres-v4r2/./src/doc/postgres.faq Thu Mar 31 00:58:54 1994 --- postgres/./src/doc/postgres.faq Wed Jul 13 11:32:14 1994 *************** *** 94,109 **** Q. What about SQL support? A. POSTGRES does not support SQL. A commercial version of POSTGRES ! produced by Montage Software, Inc. (see below) does support SQL. Q. What does POSTGRES run on? A. POSTGRES 4.2 is known to run on Sun-4 (SPARC) computers running SunOS ! 4.1.2 or higher, DECstation 3100 and 5000 (MIPS) computers running ! Ultrix 4.2 or higher, H-P 9000 Model 700 and 800 (PA-RISC) computers running HP-UX 9.00 or higher, DECstation 3000 (Alpha ! AXP) running OSF/1 1.3, and IBM RS/6000 (POWER) running AIX 3.2.3 ! or higher. The experience of outside developers indicates that POSTGRES is relatively easy to port to any system that supports: --- 94,110 ---- Q. What about SQL support? A. POSTGRES does not support SQL. A commercial version of POSTGRES ! produced by Illustra Information Technologies, Inc. (see below) ! does support SQL. Q. What does POSTGRES run on? A. POSTGRES 4.2 is known to run on Sun-4 (SPARC) computers running SunOS ! 4.1.3 and Solaris 2.3, DECstation 3100 and 5000 (MIPS) computers ! running Ultrix 4.2 or higher, H-P 9000 Model 700 and 800 (PA-RISC) computers running HP-UX 9.00 or higher, DECstation 3000 (Alpha ! AXP) running OSF/1 1.3 and 2.0, and IBM RS/6000 (POWER) running ! AIX 3.2.5 or higher. The experience of outside developers indicates that POSTGRES is relatively easy to port to any system that supports: *************** *** 212,226 **** Q. Is there a commercial version of POSTGRES? ! A. Yes. Montage Software, Inc. has performed a substantial amount of bullet-proofing and performance improvement and has added many new features (true log-based crash recovery, an type system that makes ! sense, SQL support). They also provide technical support. You can ! contact them at: ! Montage Software, Inc. 1111 Broadway, Suite 2000 Oakland, CA 94607 510-652-8000 510-652-8050 (fax) ! sales@montage.com --- 213,228 ---- Q. Is there a commercial version of POSTGRES? ! A. Yes. Illustra Information Technologies (formerly Montage ! Software, Inc.( has performed a substantial amount of bullet-proofing and performance improvement and has added many new features (true log-based crash recovery, an type system that makes ! sense, SQL support). They also provide technical support. You ! can contact them at: ! Illustra Information Technologies, Inc. 1111 Broadway, Suite 2000 Oakland, CA 94607 510-652-8000 510-652-8050 (fax) ! sales@illustra.com *** postgres-v4r2/./src/backend/postmaster/postmaster.c Wed Jun 15 20:23:06 1994 --- postgres/./src/backend/postmaster/postmaster.c Wed Aug 24 17:58:12 1994 *************** *** 1,5 **** /* ! * /usr/local/devel/postgres-v4r2/src/backend/postmaster/RCS/postmaster.c,v 1.79 1994/06/16 03:23:06 aoki Exp * * POSTMASTER * --- 1,5 ---- /* ! * $Header: /usr/local/devel/postgres/src/backend/postmaster/RCS/postmaster.c,v 1.80 1994/08/25 00:57:59 aoki Exp $ * * POSTMASTER * *************** *** 708,720 **** { int status = 0; /* return status */ BackendNode *bn; /* for backend cleanup */ ! int pid; ! char envEntry[4][2 * ARGV_SIZE]; /* * Set up the necessary environment variables for the backend * This should really be some sort of message.... */ sprintf(envEntry[0], "POSTPORT=%d", PostPortName); putenv(envEntry[0]); sprintf(envEntry[1], "POSTID=%d", NextBackendId); --- 708,723 ---- { int status = 0; /* return status */ BackendNode *bn; /* for backend cleanup */ ! int i, pid; ! char *envEntry[4]; /* * Set up the necessary environment variables for the backend * This should really be some sort of message.... */ + for (i = 0; i < 4; ++i) { + envEntry[i] = calloc(2 * ARGV_SIZE, 1); + } sprintf(envEntry[0], "POSTPORT=%d", PostPortName); putenv(envEntry[0]); sprintf(envEntry[1], "POSTID=%d", NextBackendId); *** postgres-v4r2/./src/backend/port/alpha/Makefile.inc Wed Jun 15 20:23:06 1994 --- postgres/./src/backend/port/alpha/Makefile.inc Mon Jul 18 18:40:55 1994 *************** *** 1,7 **** # # Alpha OSF/1 specific stuff # ! # /usr/local/devel/postgres-v4r2/src/backend/port/alpha/RCS/Makefile.inc,v 1.10 1994/06/16 03:23:06 aoki Exp # CFLAGS+= -DUSE_POSIX_TIME -DDISABLE_XOPEN_NLS -DNEED_ISINF -DHAS_LONG_LONG --- 1,7 ---- # # Alpha OSF/1 specific stuff # ! # $Header: /usr/local/devel/postgres/src/backend/port/alpha/RCS/Makefile.inc,v 1.11 1994/07/19 01:40:46 aoki Exp $ # CFLAGS+= -DUSE_POSIX_TIME -DDISABLE_XOPEN_NLS -DNEED_ISINF -DHAS_LONG_LONG *************** *** 17,20 **** HEADERS+= machine.h ! SRCS+= dynloader.c port.c tas.s --- 17,20 ---- HEADERS+= machine.h ! SRCS+= dynloader.c port.c *** postgres-v4r2/./src/backend/storage/ipc.h Fri Jun 24 17:43:46 1994 --- postgres/./src/backend/storage/ipc.h Mon Jul 18 18:41:10 1994 *************** *** 10,16 **** * be factored into the port/ directories. * * IDENTIFICATION ! * /usr/local/devel/postgres-v4r2/src/backend/storage/RCS/ipc.h,v 1.42 1994/06/25 00:43:46 aoki Exp */ #ifndef IPCIncluded /* Include this file only once */ --- 10,16 ---- * be factored into the port/ directories. * * IDENTIFICATION ! * $Header: /usr/local/devel/postgres/src/backend/storage/RCS/ipc.h,v 1.43 1994/07/19 01:41:04 aoki Exp $ */ #ifndef IPCIncluded /* Include this file only once */ *************** *** 62,71 **** typedef unsigned int slock_t; #else /* aix */ #if defined(PORTNAME_alpha) ! /* ! * The Alpha LDQ_L/STQ_C instructions operate on quadwords (long int). ! */ ! typedef long slock_t; #else /* alpha */ #if defined(PORTNAME_hpux) /* --- 62,69 ---- typedef unsigned int slock_t; #else /* aix */ #if defined(PORTNAME_alpha) ! #include ! typedef msemaphore slock_t; #else /* alpha */ #if defined(PORTNAME_hpux) /* *************** *** 91,97 **** extern int S_UNLOCK ARGS((slock_t *lock)); extern int S_INIT_LOCK ARGS((slock_t *lock)); ! #if defined(PORTNAME_hpux) extern int S_LOCK_FREE ARGS((slock_t *lock)); #else /* PORTNAME_hpux */ #define S_LOCK_FREE(lock) ((*lock) == 0) --- 89,95 ---- extern int S_UNLOCK ARGS((slock_t *lock)); extern int S_INIT_LOCK ARGS((slock_t *lock)); ! #if defined(PORTNAME_hpux) || defined(PORTNAME_alpha) extern int S_LOCK_FREE ARGS((slock_t *lock)); #else /* PORTNAME_hpux */ #define S_LOCK_FREE(lock) ((*lock) == 0) *** postgres-v4r2/./src/backend/storage/buffer/bufmgr.c Fri Jun 24 17:43:46 1994 --- postgres/./src/backend/storage/buffer/bufmgr.c Mon Jul 18 18:46:00 1994 *************** *** 2,8 **** * bufmgr.c -- buffer manager interface routines * * Identification: ! * /usr/local/devel/postgres-v4r2/src/backend/storage/buffer/RCS/bufmgr.c,v 1.83 1994/06/25 00:43:46 aoki Exp * * BufferAlloc() -- lookup a buffer in the buffer table. If * it isn't there add it, but do not read it into memory. --- 2,8 ---- * bufmgr.c -- buffer manager interface routines * * Identification: ! * $Header: /usr/local/devel/postgres/src/backend/storage/buffer/RCS/bufmgr.c,v 1.84 1994/07/19 01:39:20 aoki Exp $ * * BufferAlloc() -- lookup a buffer in the buffer table. If * it isn't there add it, but do not read it into memory. *************** *** 160,171 **** if (BufferIsValid(buffer)) { bufHdr = BufferGetBufferDescriptor(buffer); lrelId = RelationGetLRelId(relation); if (bufHdr->tag.blockNum == blockNumber && bufHdr->tag.relId.relId == lrelId.relId && ! bufHdr->tag.relId.dbId == lrelId.dbId) ! return buffer; ! } ! return(ReadBuffer(relation,blockNumber)); } /* --- 160,175 ---- if (BufferIsValid(buffer)) { bufHdr = BufferGetBufferDescriptor(buffer); lrelId = RelationGetLRelId(relation); + SpinAcquire(BufMgrLock); if (bufHdr->tag.blockNum == blockNumber && bufHdr->tag.relId.relId == lrelId.relId && ! bufHdr->tag.relId.dbId == lrelId.dbId) { ! SpinRelease(BufMgrLock); ! return(buffer); ! } ! return(ReadBufferWithBufferLock(relation, blockNumber, true)); ! } ! return(ReadBuffer(relation, blockNumber)); } /* *************** *** 192,197 **** --- 196,207 ---- return ReadBufferWithBufferLock(reln, blockNum, false); } + /* + * is_userbuffer + * + * XXX caller must have already acquired BufMgrLock + */ + static bool is_userbuffer(buffer) Buffer buffer; *************** *** 214,221 **** buffer = ReadBufferWithBufferLock(reln, blockNum, false); if (ShowPinTrace && is_userbuffer(buffer)) { ! BufferDesc *buf; ! buf = BufferGetBufferDescriptor(buffer); fprintf(stderr, "PIN(RD) %d relname = %.*s, blockNum = %d, \ refcount = %d, file: %s, line: %d\n", buffer, NAMEDATALEN, &(buf->sb_relname), buf->tag.blockNum, --- 224,231 ---- buffer = ReadBufferWithBufferLock(reln, blockNum, false); if (ShowPinTrace && is_userbuffer(buffer)) { ! BufferDesc *buf = BufferGetBufferDescriptor(buffer); ! fprintf(stderr, "PIN(RD) %d relname = %.*s, blockNum = %d, \ refcount = %d, file: %s, line: %d\n", buffer, NAMEDATALEN, &(buf->sb_relname), buf->tag.blockNum, *************** *** 230,238 **** * the buffer lock has already been held. this * is yet another effort to reduce the number of * semops in the system. - * - * This routine locks the buffer pool before calling BufferAlloc to - * avoid two semops. */ Buffer --- 240,245 ---- *************** *** 331,336 **** --- 338,345 ---- * read it. * * Returns: descriptor for buffer + * + * When this routine returns, the BufMgrLock is guaranteed NOT be held. */ BufferDesc * BufferAlloc(reln, blockNum, foundPtr, bufferLockHeld) *************** *** 410,423 **** */ inProgress = FALSE; for (buf = (BufferDesc *) NULL; buf == (BufferDesc *) NULL; ) { buf = GetFreeBuffer(); ! if (! buf) { ! /* out of free buffers. In trouble now. */ ! /* XXX actually, GetFreeBuffer already aborted us... */ ! SpinRelease(BufMgrLock); ! return((BufferDesc *) NULL); ! } ! /* * There should be exactly one pin on the buffer after * it is allocated -- ours. If it had a pin it wouldn't --- 419,428 ---- */ inProgress = FALSE; for (buf = (BufferDesc *) NULL; buf == (BufferDesc *) NULL; ) { + + /* GetFreeBuffer will abort if it can't find a free buffer */ buf = GetFreeBuffer(); ! /* * There should be exactly one pin on the buffer after * it is allocated -- ours. If it had a pin it wouldn't *************** *** 459,468 **** * you on machines that don't have spinlocks. If you don't * operate with much concurrency, well... */ ! #ifndef OPTIMIZE_SINGLE ! SpinRelease(BufMgrLock); ! #endif /* OPTIMIZE_SINGLE */ ! (void) BufferReplace(buf); BufferFlushCount++; #ifndef OPTIMIZE_SINGLE SpinAcquire(BufMgrLock); --- 464,470 ---- * you on machines that don't have spinlocks. If you don't * operate with much concurrency, well... */ ! (void) BufferReplace(buf, true); BufferFlushCount++; #ifndef OPTIMIZE_SINGLE SpinAcquire(BufMgrLock); *************** *** 589,596 **** } bufHdr = BufferGetBufferDescriptor(buffer); - Assert(bufHdr->refcount > 0); SpinAcquire(BufMgrLock); bufHdr->flags |= BM_DIRTY; UnpinBuffer(bufHdr); SpinRelease(BufMgrLock); --- 591,598 ---- } bufHdr = BufferGetBufferDescriptor(buffer); SpinAcquire(BufMgrLock); + Assert(bufHdr->refcount > 0); bufHdr->flags |= BM_DIRTY; UnpinBuffer(bufHdr); SpinRelease(BufMgrLock); *************** *** 671,688 **** return(STATUS_ERROR); } bufHdr = BufferGetBufferDescriptor(buffer); - Assert(bufHdr->refcount > 0); if (LateWrite) { SpinAcquire(BufMgrLock); bufHdr->flags |= BM_DIRTY; UnpinBuffer(bufHdr); SpinRelease(BufMgrLock); } else { ! BufferReplace(bufHdr); } - return(STATUS_OK); } --- 673,689 ---- return(STATUS_ERROR); } bufHdr = BufferGetBufferDescriptor(buffer); if (LateWrite) { SpinAcquire(BufMgrLock); + Assert(bufHdr->refcount > 0); bufHdr->flags |= BM_DIRTY; UnpinBuffer(bufHdr); SpinRelease(BufMgrLock); } else { ! BufferReplace(bufHdr, false); } return(STATUS_OK); } *************** *** 689,694 **** --- 690,700 ---- /* * FlushBuffer -- like WriteBuffer, but force the page to disk. + * + * 'buffer' is known to be dirty/pinned, so there should not be a + * problem reading the BufferDesc members without the BufMgrLock + * (nobody should be able to change tags, flags, etc. out from under + * us). */ FlushBuffer(buffer) Buffer buffer; *************** *** 706,739 **** bufHdr = BufferGetBufferDescriptor(buffer); ! /* ! * If the relation is not in our private cache, we don't bother trying ! * to instantiate it. Instead, we call the storage manager routine that ! * does a blind write. If we can get the reldesc, then we use the standard ! * write routine interface. ! */ ! ! bufdb = bufHdr->tag.relId.dbId; ! bufrel = bufHdr->tag.relId.relId; ! ! if (bufdb == MyDatabaseId || bufdb == (OID) NULL) ! reln = RelationIdCacheGetRelation(bufrel); ! else ! reln = (Relation) NULL; ! ! if (reln != (Relation) NULL) { ! status = smgrflush(bufHdr->bufsmgr, reln, bufHdr->tag.blockNum, ! (char *) MAKE_PTR(bufHdr->data)); ! } else { ! ! /* blind write always flushes */ ! status = smgrblindwrt(bufHdr->bufsmgr, &bufHdr->sb_dbname, ! &bufHdr->sb_relname, bufdb, bufrel, ! bufHdr->tag.blockNum, ! (char *) MAKE_PTR(bufHdr->data)); ! } ! ! if (status == SM_FAIL) { elog(WARN, "FlushBuffer: cannot flush %d for %16s", bufHdr->tag.blockNum, reln->rd_rel->relname); /* NOTREACHED */ --- 712,718 ---- bufHdr = BufferGetBufferDescriptor(buffer); ! if (!BufferReplace(bufHdr, false)) { elog(WARN, "FlushBuffer: cannot flush %d for %16s", bufHdr->tag.blockNum, reln->rd_rel->relname); /* NOTREACHED */ *************** *** 823,829 **** BufferAcquire(bufHdr) BufferDesc *bufHdr; { - SpinAcquire(BufMgrLock); PinBuffer(bufHdr); SpinRelease(BufMgrLock); --- 802,807 ---- *************** *** 843,852 **** } bufHdr = BufferGetBufferDescriptor(buffer); /* like we said -- already pinned */ Assert(bufHdr->refcount); - - SpinAcquire(BufMgrLock); PinBuffer(bufHdr); SpinRelease(BufMgrLock); return (TRUE); --- 821,829 ---- } bufHdr = BufferGetBufferDescriptor(buffer); + SpinAcquire(BufMgrLock); /* like we said -- already pinned */ Assert(bufHdr->refcount); PinBuffer(bufHdr); SpinRelease(BufMgrLock); return (TRUE); *************** *** 879,886 **** BufferDesc *bufHdr; int status; for (i=0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++) { ! if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY)) { bufdb = bufHdr->tag.relId.dbId; bufrel = bufHdr->tag.relId.relId; if (bufdb == MyDatabaseId || bufdb == (OID) 0) { --- 856,864 ---- BufferDesc *bufHdr; int status; + SpinAcquire(BufMgrLock); for (i=0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++) { ! if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY)) { bufdb = bufHdr->tag.relId.dbId; bufrel = bufHdr->tag.relId.relId; if (bufdb == MyDatabaseId || bufdb == (OID) 0) { *************** *** 892,897 **** --- 870,878 ---- * we did find it, use the standard interface. */ + #ifndef OPTIMIZE_SINGLE + SpinRelease(BufMgrLock); + #endif /* OPTIMIZE_SINGLE */ if (reln == (Relation) NULL) { status = smgrblindwrt(bufHdr->bufsmgr, &bufHdr->sb_dbname, &bufHdr->sb_relname, bufdb, bufrel, *************** *** 902,907 **** --- 883,891 ---- bufHdr->tag.blockNum, (char *) MAKE_PTR(bufHdr->data)); } + #ifndef OPTIMIZE_SINGLE + SpinAcquire(BufMgrLock); + #endif /* OPTIMIZE_SINGLE */ if (status == SM_FAIL) { elog(WARN, "cannot write %d for %16s", *************** *** 914,919 **** --- 898,904 ---- } } } + SpinRelease(BufMgrLock); } *************** *** 1208,1213 **** --- 1193,1199 ---- Buffer buffer; { Assert(BufferIsValid(buffer)); + /* XXX should be a critical section */ return (BufferGetBufferDescriptor(buffer)->tag.blockNum); } *************** *** 1219,1224 **** --- 1205,1211 ---- Assert(BufferIsValid(buffer)); + /* XXX should be a critical section */ relation = RelationIdGetRelation(LRelIdGetRelationId (BufferGetBufferDescriptor(buffer)->tag.relId)); *************** *** 1265,1272 **** #endif /* !NO_ASSERT_CHECKING */ ! BufferReplace(bufHdr) BufferDesc *bufHdr; { int blockSize; int blockNum; --- 1252,1267 ---- #endif /* !NO_ASSERT_CHECKING */ ! /* ! * BufferReplace ! * ! * Flush the buffer corresponding to 'bufHdr' ! * ! * Assumes that the BufMgrLock has NOT been acquired. ! */ ! BufferReplace(bufHdr, bufferLockHeld) BufferDesc *bufHdr; + bool bufferLockHeld; { int blockSize; int blockNum; *************** *** 1275,1280 **** --- 1270,1278 ---- ObjectId bufdb, bufrel; int status; + if (!bufferLockHeld) + SpinAcquire(BufMgrLock); + blockSize = BLOCKSZ(bufHdr); blockNum = bufHdr->tag.blockNum; *************** *** 1292,1297 **** --- 1290,1297 ---- else reln = (Relation) NULL; + SpinRelease(BufMgrLock); + if (reln != (Relation) NULL) { status = smgrflush(bufHdr->bufsmgr, reln, bufHdr->tag.blockNum, (char *) MAKE_PTR(bufHdr->data)); *************** *** 1311,1330 **** } /************************************************** - BufferIsDirty - - **************************************************/ - - bool - BufferIsDirty(buffer) - Buffer buffer; - { - return (bool) - (BufferGetBufferDescriptor(buffer)->flags & BM_DIRTY); - } - - - /************************************************** BufferIsInvalid **************************************************/ --- 1311,1316 ---- *************** *** 1396,1413 **** Relation tempreldesc; { register int i; BufferDesc *buf; for (i=1; i<=NBuffers; i++) { buf = BufferGetBufferDescriptor(i); ! if (BufferIsDirty(i) && (buf->tag.relId.dbId == MyDatabaseId) && (buf->tag.relId.relId == tempreldesc->rd_id)) { buf->flags &= ~BM_DIRTY; ! if (!(buf->flags & BM_FREE)) ! ReleaseBuffer(i); ! } ! } } /* --------------------------------------------------------------------- --- 1382,1409 ---- Relation tempreldesc; { register int i; + int holding = 0; BufferDesc *buf; for (i=1; i<=NBuffers; i++) { buf = BufferGetBufferDescriptor(i); ! if (!holding) { ! SpinAcquire(BufMgrLock); ! holding = 1; ! } ! if ((buf->flags & BM_DIRTY) && (buf->tag.relId.dbId == MyDatabaseId) && (buf->tag.relId.relId == tempreldesc->rd_id)) { buf->flags &= ~BM_DIRTY; ! if (!(buf->flags & BM_FREE)) { ! SpinRelease(BufMgrLock); ! holding = 0; ! ReleaseBuffer(i); ! } ! } ! } ! if (holding) ! SpinRelease(BufMgrLock); } /* --------------------------------------------------------------------- *************** *** 1429,1440 **** register int i; BufferDesc *buf; for (i=1; i<=NBuffers; i++) { buf = BufferGetBufferDescriptor(i); if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY)) { buf->flags &= ~BM_DIRTY; } ! } } /* ----------------------------------------------------------------- --- 1425,1438 ---- register int i; BufferDesc *buf; + SpinAcquire(BufMgrLock); for (i=1; i<=NBuffers; i++) { buf = BufferGetBufferDescriptor(i); if ((buf->tag.relId.dbId == dbid) && (buf->flags & BM_DIRTY)) { buf->flags &= ~BM_DIRTY; } ! } ! SpinRelease(BufMgrLock); } /* ----------------------------------------------------------------- *************** *** 1451,1456 **** --- 1449,1455 ---- int i; BufferDesc *buf = BufferDescriptors; + SpinAcquire(BufMgrLock); for (i = 0; i < NBuffers; ++i, ++buf) { elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%.*s, \ blockNum=%d, flags=0x%x, refcount=%d %d)", *************** *** 1458,1481 **** buf->tag.blockNum, buf->flags, buf->refcount, PrivateRefCount[i]); } } void - GetPageAddr(bufno) - long bufno; - { - long p; - - p = ShmemBase + BufferDescriptors[bufno].data; - printf("0x%lx (%ld)\n", p, p); - } - - void PrintPinnedBufs() { int i; BufferDesc *buf = BufferDescriptors; for (i = 0; i < NBuffers; ++i, ++buf) { if (PrivateRefCount[i] > 0) elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%.*s, \ --- 1457,1472 ---- buf->tag.blockNum, buf->flags, buf->refcount, PrivateRefCount[i]); } + SpinRelease(BufMgrLock); } void PrintPinnedBufs() { int i; BufferDesc *buf = BufferDescriptors; + SpinAcquire(BufMgrLock); for (i = 0; i < NBuffers; ++i, ++buf) { if (PrivateRefCount[i] > 0) elog(NOTICE, "[%02d] (freeNext=%d, freePrev=%d, relname=%.*s, \ *************** *** 1483,1489 **** i, buf->freeNext, buf->freePrev, NAMEDATALEN, &(buf->sb_relname), buf->tag.blockNum, buf->flags, buf->refcount, PrivateRefCount[i]); ! } } /* ----------------------------------------------------- --- 1474,1481 ---- i, buf->freeNext, buf->freePrev, NAMEDATALEN, &(buf->sb_relname), buf->tag.blockNum, buf->flags, buf->refcount, PrivateRefCount[i]); ! } ! SpinRelease(BufMgrLock); } /* ----------------------------------------------------- *** postgres-v4r2/./src/backend/storage/buffer/order.c Mon Aug 9 18:46:51 1993 --- postgres/./src/backend/storage/buffer/order.c Sat Jul 16 03:13:50 1994 *************** *** 5,11 **** #include "tmp/c.h" ! RcsId("/usr/local/devel/postgres-v4r2/src/backend/storage/buffer/RCS/order.c,v 1.13 1993/08/10 01:46:51 marc Exp"); #include "utils/log.h" --- 5,11 ---- #include "tmp/c.h" ! RcsId("$Header: /usr/local/devel/postgres/src/backend/storage/buffer/RCS/order.c,v 1.14 1994/07/16 10:09:26 aoki Exp $"); #include "utils/log.h" *************** *** 61,90 **** return(ret); } - /* - * bwinit - * - * Initialize the data structures needed for buffer ordering. - */ - - bwinit() - { - register int i; - - adjlist = (Stack**)malloc(NBuffers * sizeof(Stack*)); - datlist = (BufferDesc**)malloc(NBuffers * sizeof(BufferDesc*)); - used = (long *)malloc(NBuffers * sizeof(int)); - - for (i = 0; i < NBuffers; i++) { - adjlist[i] = (Stack *) NULL; - datlist[i] = (BufferDesc *) NULL; - used[i] = 0; - } - } - - - /* * bworder * * Enter two buffers into the partial ordering. --- 61,67 ---- *************** *** 130,273 **** /* Save the successor in the predecessor's adjacency list */ bs_push(after, &adjlist[before]); used[before] = used[after] = 1; - return(0); - } - - /* - * bwsort - * - * Determines which buffers must be written before 'item', given the - * partial order (DAG) created by calls to bw_before(). - * - * Returns an array of size NBuffers which contains the buffer numbers - * in the order in which they must be written (up to 'item'). - * - * Cannot cope with cycles. - * - * Uses the O(n+e) topological sort from Mellhorn, Vol. I. - */ - - BufferDesc ** - bwsort(item) - BufferDesc *item; - { - register int i; - int count = 0, active_bufs = 0; - register Stack *sp; - Stack *zeroindeg = (Stack *) NULL; - long *indeg; - static BufferDesc **ret; - - - indeg = (long *)malloc(NBuffers * sizeof(long)); - ret = (BufferDesc**)malloc(NBuffers * sizeof(BufferDesc*)); - for (i = 0; i < NBuffers; i++) { - ret[i] = (BufferDesc *) NULL; - indeg[i] = 0; - } - - /* Calculate indegrees for each vertex */ - for (i = 0; i < NBuffers; i++) - for (sp = adjlist[i]; sp != (Stack *) NULL; sp = sp->next) - indeg[sp->datum]++; - - /* - * Push all 'root' vertices onto the stack. - * While we do this, check to see if 'item' has an indegree of 0. - * If so, we don't have to do the topological sort. - */ - for (i = 0; i < NBuffers; i++) - if (indeg[i] == 0) - if (datlist[i] == item) { /* no need to sort */ - ret[0] = item; - free((char*)indeg); - free((char*)ret); - return(ret); - } else - bs_push(i, &zeroindeg); - - /* - * Perform the topological sort. - */ - while (zeroindeg != (Stack *) NULL) { - if ((i = bs_pop(&zeroindeg)) < 0) { - elog(WARN, "bwsort: stack error"); - free((char*)indeg); - free((char*)ret); - return((BufferDesc **) NULL); - } - if (used[i]) /* ignore unused buffers */ - ret[count++] = datlist[i]; - for (sp = adjlist[i]; sp != (Stack *) NULL; sp = sp->next) { - indeg[sp->datum]--; - if (indeg[sp->datum] == 0) - bs_push(sp->datum, &zeroindeg); - } - } - - /* Either 'item' is last or we have some kind of error */ - for (i = 0; i < NBuffers; i++) - active_bufs += used[i]; - if (count != active_bufs) { - elog(WARN, "bwsort: cycle in buffer ordering!"); - free((char*)indeg); - free((char*)ret); - return((BufferDesc **) NULL); - } - - free((char*)indeg); - free((char*)ret); - return(ret); - } - - - /* - * bwremove - * - * Remove the argument item from the ordering data structures. - */ - - bwremove(nitems, items) - int nitems; - BufferDesc *items[]; - { - register Stack *p; - register int i, j; - long *remove; - - remove = (long *)malloc(NBuffers * sizeof(long)); - if (nitems < 0 || nitems > NBuffers) { - elog(WARN, "bwremove: bad nitems %d", nitems); - free((char*)remove); - return(-1); - } - - /* Mark off the items in 'datlist' to remove */ - for (i = 0; i < nitems; i++) - for (j = 0; j < NBuffers; j++) - if (items[i] == datlist[j]) - remove[j] = 1; - for (i = 0; i < nitems; i++) - if (remove[i] != 1) { - elog(WARN, "bwremove: ordering corrupted"); - free((char*)remove); - return(-1); - } - - /* Remove everything in 'adjlist' having to do with those items */ - for (i = 0; i < NBuffers; i++) { - if ((p = adjlist[i]) == (Stack *) NULL) - continue; - else if (p->next == (Stack *) NULL) - if (remove[p->datum]) - adjlist[i] = (Stack *) NULL; - else - for (; p->next != (Stack *) NULL; - p = p->next) - if (remove[p->next->datum]) - p->next = p->next->next; - used[i] = 0; - } - free((char*)remove); return(0); } --- 107,111 ---- *** postgres-v4r2/./src/backend/storage/ipc/s_lock.c Fri Jun 24 17:43:46 1994 --- postgres/./src/backend/storage/ipc/s_lock.c Mon Jul 18 18:41:41 1994 *************** *** 28,34 **** * manual for POWER in any case. * * IDENTIFICATION ! * /usr/local/devel/postgres-v4r2/src/backend/storage/ipc/RCS/s_lock.c,v 1.13 1994/06/25 00:43:46 aoki Exp * ---------------------------------------------------------------- */ --- 28,34 ---- * manual for POWER in any case. * * IDENTIFICATION ! * $Header: /usr/local/devel/postgres/src/backend/storage/ipc/RCS/s_lock.c,v 1.14 1994/07/19 01:41:29 aoki Exp $ * ---------------------------------------------------------------- */ *************** *** 35,55 **** #include "storage/ipci.h" #include "storage/ipc.h" ! RcsId("/usr/local/devel/postgres-v4r2/src/backend/storage/ipc/RCS/s_lock.c,v 1.13 1994/06/25 00:43:46 aoki Exp"); #if defined(HAS_TEST_AND_SET) /* * OSF/1 (Alpha AXP) - * Solaris 2 * ! * Note that slock_t on the Alpha AXP is long instead of char * (see storage/ipc.h). */ ! #if defined(PORTNAME_alpha) || \ ! defined(PORTNAME_sparc_solaris) /* defined in port/.../tas.s */ extern int tas ARGS((slock_t *lock)); --- 35,86 ---- #include "storage/ipci.h" #include "storage/ipc.h" ! RcsId("$Header: /usr/local/devel/postgres/src/backend/storage/ipc/RCS/s_lock.c,v 1.14 1994/07/19 01:41:29 aoki Exp $"); #if defined(HAS_TEST_AND_SET) /* * OSF/1 (Alpha AXP) * ! * Note that slock_t on the Alpha AXP is msemaphore instead of char * (see storage/ipc.h). */ ! #if defined(PORTNAME_alpha) + S_LOCK(lock) + slock_t *lock; + { + while (msem_lock(lock, MSEM_IF_NOWAIT) < 0) + ; + } + + S_UNLOCK(lock) + slock_t *lock; + { + (void) msem_unlock(lock, 0); + } + + S_INIT_LOCK(lock) + slock_t *lock; + { + (void) msem_init(lock, MSEM_UNLOCKED); + } + + S_LOCK_FREE(lock) + slock_t *lock; + { + return(lock->msem_state ? 0 : 1); + } + + #endif /* PORTNAME_alpha */ + + /* + * Solaris 2 + */ + + #if defined(PORTNAME_sparc_solaris) + /* defined in port/.../tas.s */ extern int tas ARGS((slock_t *lock)); *************** *** 72,78 **** S_UNLOCK(lock); } ! #endif /* PORTNAME_alpha */ /* * AIX (POWER) --- 103,109 ---- S_UNLOCK(lock); } ! #endif /* PORTNAME_sparc_solaris */ /* * AIX (POWER) ============================================================================== To add/remove yourself to/from the POSTGRES mailing list: send mail with the subject line ADD or DEL to "postgres-request@postgres.Berkeley.EDU" If this fails, send mail to "post_questions@postgres.Berkeley.EDU" and a human will deal with it. DO NOT post to the "postgres" mailing list. ==============================================================================