about summary refs log tree commit diff
path: root/db2/lock/lock_deadlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'db2/lock/lock_deadlock.c')
-rw-r--r--db2/lock/lock_deadlock.c108
1 files changed, 55 insertions, 53 deletions
diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c
index f947f901c3..566021fe89 100644
--- a/db2/lock/lock_deadlock.c
+++ b/db2/lock/lock_deadlock.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)lock_deadlock.c	10.21 (Sleepycat) 9/6/97";
+static const char sccsid[] = "@(#)lock_deadlock.c	10.25 (Sleepycat) 11/1/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -50,16 +50,19 @@ typedef struct {
 	int		valid;
 	u_int32_t	id;
 	DB_LOCK		last_lock;
+	db_pgno_t	pgno;
 } locker_info;
 
 static int  __dd_abort __P((DB_ENV *, locker_info *));
-static int  __dd_build __P((DB_ENV *, u_int32_t **, int *, locker_info **));
-#ifdef DEBUG
-static void __dd_debug __P((DB_ENV *, locker_info *, u_int32_t *, int));
-#endif
+static int  __dd_build
+	__P((DB_ENV *, u_int32_t **, u_int32_t *, locker_info **));
 static u_int32_t
 	   *__dd_find __P((u_int32_t *, locker_info *, u_int32_t));
 
+#ifdef DEBUG
+static void __dd_debug __P((DB_ENV *, locker_info *, u_int32_t *, u_int32_t));
+#endif
+
 int
 lock_detect(lt, flags, atype)
 	DB_LOCKTAB *lt;
@@ -68,8 +71,8 @@ lock_detect(lt, flags, atype)
 {
 	DB_ENV *dbenv;
 	locker_info *idmap;
-	u_int32_t *bitmap, *deadlock, killid;
-	int do_pass, i, nlockers, nentries, ret;
+	u_int32_t *bitmap, *deadlock, i, killid, nentries, nlockers;
+	int do_pass, ret;
 
 	/* Validate arguments. */
 	if ((ret =
@@ -77,17 +80,16 @@ lock_detect(lt, flags, atype)
 		return (ret);
 
 	/* Check if a detector run is necessary. */
-	do_pass = 1;
 	dbenv = lt->dbenv;
 	if (LF_ISSET(DB_LOCK_CONFLICT)) {
 		/* Make a pass every time a lock waits. */
 		LOCK_LOCKREGION(lt);
 		do_pass = dbenv->lk_info->region->need_dd != 0;
 		UNLOCK_LOCKREGION(lt);
-	}
 
-	if (!do_pass)
-		return (0);
+		if (!do_pass)
+			return (0);
+	}
 
 	/* Build the waits-for bitmap. */
 	if ((ret = __dd_build(dbenv, &bitmap, &nlockers, &idmap)) != 0)
@@ -118,8 +120,7 @@ lock_detect(lt, flags, atype)
 
 			if (killid == BAD_KILLID) {
 				__db_err(dbenv,
-				    "warning: could not find %s",
-				    "locker to abort");
+				    "warning: could not find locker to abort");
 				break;
 			}
 
@@ -137,11 +138,8 @@ lock_detect(lt, flags, atype)
 			/*
 			 * We are trying to calculate the id of the
 			 * locker whose entry is indicated by deadlock.
-			 * We know that this is less than nlockers, so
-			 * the cast below is valid.
 			 */
-			killid =
-			    (u_int32_t)((deadlock - bitmap) / nentries);
+			killid = (deadlock - bitmap) / nentries;
 			break;
 		case DB_LOCK_YOUNGEST:
 			/*
@@ -155,8 +153,7 @@ lock_detect(lt, flags, atype)
 
 			if (killid == BAD_KILLID) {
 				__db_err(dbenv,
-				    "warning: could not find %s",
-				    "locker to abort");
+				    "warning: could not find locker to abort");
 				break;
 			}
 			/*
@@ -184,8 +181,8 @@ lock_detect(lt, flags, atype)
 			    "warning: unable to abort locker %lx",
 			    (u_long)idmap[killid].id);
 	}
-	free(bitmap);
-	free(idmap);
+	__db_free(bitmap);
+	__db_free(idmap);
 
 	return (ret);
 }
@@ -197,15 +194,15 @@ lock_detect(lt, flags, atype)
 static int
 __dd_build(dbenv, bmp, nlockers, idmap)
 	DB_ENV *dbenv;
-	u_int32_t **bmp;
-	int *nlockers;
+	u_int32_t **bmp, *nlockers;
 	locker_info **idmap;
 {
-	DB_LOCKTAB *lt;
-	DB_LOCKOBJ *op, *lockerp;
 	struct __db_lock *lp;
-	u_int32_t *bitmap, count, *entryp, i, id, nentries, *tmpmap;
+	DB_LOCKTAB *lt;
+	DB_LOCKOBJ *op, *lo, *lockerp;
+	u_int8_t *pptr;
 	locker_info *id_array;
+	u_int32_t *bitmap, count, *entryp, i, id, nentries, *tmpmap;
 	int is_first, ret;
 
 	lt = dbenv->lk_info;
@@ -238,24 +235,24 @@ retry:	count = lt->region->nlockers;
 	 * We can probably save the malloc's between iterations just
 	 * reallocing if necessary because count grew by too much.
 	 */
-	if ((bitmap = (u_int32_t *)calloc((size_t)count,
+	if ((bitmap = (u_int32_t *)__db_calloc((size_t)count,
 	    sizeof(u_int32_t) * nentries)) == NULL) {
 		__db_err(dbenv, "%s", strerror(ENOMEM));
 		return (ENOMEM);
 	}
 
 	if ((tmpmap =
-	    (u_int32_t *)calloc(sizeof(u_int32_t), nentries)) == NULL) {
+	    (u_int32_t *)__db_calloc(sizeof(u_int32_t), nentries)) == NULL) {
 		__db_err(dbenv, "%s", strerror(ENOMEM));
-		free(bitmap);
+		__db_free(bitmap);
 		return (ENOMEM);
 	}
 
-	if ((id_array = (locker_info *)calloc((size_t)count,
+	if ((id_array = (locker_info *)__db_calloc((size_t)count,
 	    sizeof(locker_info))) == NULL) {
 		__db_err(dbenv, "%s", strerror(ENOMEM));
-		free(bitmap);
-		free(tmpmap);
+		__db_free(bitmap);
+		__db_free(tmpmap);
 		return (ENOMEM);
 	}
 
@@ -264,9 +261,9 @@ retry:	count = lt->region->nlockers;
 	 */
 	LOCK_LOCKREGION(lt);
 	if (lt->region->nlockers > count) {
-		free(bitmap);
-		free(tmpmap);
-		free(id_array);
+		__db_free(bitmap);
+		__db_free(tmpmap);
+		__db_free(id_array);
 		goto retry;
 	}
 
@@ -326,9 +323,8 @@ retry:	count = lt->region->nlockers;
 			    lp != NULL;
 			    is_first = 0,
 			    lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
-				if ((ret = __lock_getobj(lt,
-				    lp->holder, NULL, DB_LOCK_LOCKER, &lockerp))
-				    != 0) {
+				if ((ret = __lock_getobj(lt, lp->holder,
+				    NULL, DB_LOCK_LOCKER, &lockerp)) != 0) {
 					__db_err(dbenv,
 					    "warning unable to find object");
 					continue;
@@ -369,8 +365,16 @@ retry:	count = lt->region->nlockers;
 			continue;
 		}
 		lp = SH_LIST_FIRST(&lockerp->heldby, __db_lock);
-		if (lp != NULL)
+		if (lp != NULL) {
 			id_array[id].last_lock = LOCK_TO_OFFSET(lt, lp);
+			lo = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
+			pptr = SH_DBT_PTR(&lo->lockobj);
+			if (lo->lockobj.size >= sizeof(db_pgno_t))
+				memcpy(&id_array[id].pgno, pptr,
+				    sizeof(db_pgno_t));
+			else
+				id_array[id].pgno = 0;
+		}
 	}
 
 	/* Pass complete, reset the deadlock detector bit. */
@@ -384,21 +388,20 @@ retry:	count = lt->region->nlockers;
 	*nlockers = id;
 	*idmap = id_array;
 	*bmp = bitmap;
-	free(tmpmap);
+	__db_free(tmpmap);
 	return (0);
 }
 
 static u_int32_t *
 __dd_find(bmp, idmap, nlockers)
-	u_int32_t *bmp;
+	u_int32_t *bmp, nlockers;
 	locker_info *idmap;
-	u_int32_t nlockers;
 {
 	u_int32_t i, j, nentries, *mymap, *tmpmap;
 
 	/*
-	 * For each locker, or in the bits from the lockers
-	 * on which that locker is waiting.
+	 * For each locker, OR in the bits from the lockers on which that
+	 * locker is waiting.
 	 */
 	nentries = ALIGN(nlockers, 32) / 32;
 	for (mymap = bmp, i = 0; i < nlockers; i++, mymap += nentries) {
@@ -422,9 +425,9 @@ __dd_abort(dbenv, info)
 	DB_ENV *dbenv;
 	locker_info *info;
 {
+	struct __db_lock *lockp;
 	DB_LOCKTAB *lt;
 	DB_LOCKOBJ *lockerp, *sh_obj;
-	struct __db_lock *lockp;
 	int ret;
 
 	lt = dbenv->lk_info;
@@ -459,19 +462,17 @@ static void
 __dd_debug(dbenv, idmap, bitmap, nlockers)
 	DB_ENV *dbenv;
 	locker_info *idmap;
-	u_int32_t *bitmap;
-	int nlockers;
+	u_int32_t *bitmap, nlockers;
 {
-	u_int32_t *mymap;
-	int i, j, nentries;
+	u_int32_t i, j, *mymap, nentries;
 	char *msgbuf;
 
 	__db_err(dbenv, "Waitsfor array");
 	__db_err(dbenv, "waiter\twaiting on");
 	/*
-	 * Alloc space to print 10 bytes per item waited on.
+	 * Allocate space to print 10 bytes per item waited on.
 	 */
-	if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
+	if ((msgbuf = (char *)__db_malloc((nlockers + 1) * 10 + 64)) == NULL) {
 		__db_err(dbenv, "%s", strerror(ENOMEM));
 		return;
 	}
@@ -480,7 +481,8 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
 	for (mymap = bitmap, i = 0; i < nlockers; i++, mymap += nentries) {
 		if (!idmap[i].valid)
 			continue;
-		sprintf(msgbuf, "%lx\t\t", (u_long)idmap[i].id);/* Waiter. */
+		sprintf(msgbuf,					/* Waiter. */
+		    "%lx/%lu:\t", (u_long)idmap[i].id, (u_long)idmap[i].pgno);
 		for (j = 0; j < nlockers; j++)
 			if (ISSET_MAP(mymap, j))
 				sprintf(msgbuf, "%s %lx", msgbuf,
@@ -490,6 +492,6 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
 		__db_err(dbenv, msgbuf);
 	}
 
-	free(msgbuf);
+	__db_free(msgbuf);
 }
 #endif