Skip to content

Commit

Permalink
storage/concurrency: refactoring to use informActiveWaiters()
Browse files Browse the repository at this point in the history
when lock becomes free.

This reduces code duplication. Also added a TODO where the
!held => held transition happens, to change after cockroachdb#44885
merges.

Release note: None
  • Loading branch information
sumeerbhola committed Feb 13, 2020
1 parent ce7ed75 commit a1f1467
Showing 1 changed file with 18 additions and 54 deletions.
72 changes: 18 additions & 54 deletions pkg/storage/concurrency/lock_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,7 @@ func (l *lockState) informActiveWaiters() {
checkForWaitSelf = true
waitForTxn = l.reservation.txn
waitForTs = l.reservation.ts
if !findDistinguished && l.distinguishedWaiter.txn != nil &&
l.distinguishedWaiter.txn.ID == waitForTxn.ID {
if !findDistinguished && l.distinguishedWaiter.isTxn(waitForTxn) {
findDistinguished = true
l.distinguishedWaiter = nil
}
Expand Down Expand Up @@ -645,8 +644,7 @@ func (l *lockState) tryMakeNewDistinguished() {
} else if l.queuedWriters.Len() > 0 {
for e := l.queuedWriters.Front(); e != nil; e = e.Next() {
qg := e.Value.(*queuedGuard)
if qg.active &&
(l.reservation == nil || qg.guard.txn == nil || l.reservation.txn.ID != qg.guard.txn.ID) {
if qg.active && (l.reservation == nil || !qg.guard.isTxn(l.reservation.txn)) {
g = qg.guard
break
}
Expand Down Expand Up @@ -955,6 +953,8 @@ func (l *lockState) acquireLock(
g.doneWaitingAtLock(false, l)
}
}
// TODO: change to always informActiveWaiters since this is a transition from
// !held to held.
if brokeReservation {
l.informActiveWaiters()
}
Expand Down Expand Up @@ -1058,10 +1058,13 @@ func (l *lockState) tryClearLock() bool {
// Note that none of the current waiters can be requests
// from holderTxn.
waitState = waitingState{
stateKind: waitElsewhere,
txn: holderTxn,
ts: holderTs,
access: spanset.SpanReadWrite,
stateKind: waitElsewhere,
txn: holderTxn,
ts: holderTs,
key: l.key,
held: true,
access: spanset.SpanReadWrite,
guardAccess: spanset.SpanReadOnly,
}
} else {
l.holder.locked = false
Expand All @@ -1088,6 +1091,8 @@ func (l *lockState) tryClearLock() bool {
delete(g.mu.locks, l)
g.mu.Unlock()
}

waitState.guardAccess = spanset.SpanReadWrite
for e := l.queuedWriters.Front(); e != nil; {
qg := e.Value.(*queuedGuard)
curr := e
Expand Down Expand Up @@ -1289,17 +1294,13 @@ func (l *lockState) lockIsFree() (gc bool) {
if l.reservation != nil {
panic("lockTable bug")
}
// There may not be a distinguished waiter currently because of who had the
// previous reservation but we may be able to find one.
findDistinguished := l.distinguishedWaiter == nil
// All waiting readers don't need to wait here anymore.
for e := l.waitingReaders.Front(); e != nil; {
g := e.Value.(*lockTableGuardImpl)
curr := e
e = e.Next()
l.waitingReaders.Remove(curr)
if g == l.distinguishedWaiter {
findDistinguished = true
l.distinguishedWaiter = nil
}
g.doneWaitingAtLock(false, l)
Expand All @@ -1315,7 +1316,6 @@ func (l *lockState) lockIsFree() (gc bool) {
e = e.Next()
l.queuedWriters.Remove(curr)
if g == l.distinguishedWaiter {
findDistinguished = true
l.distinguishedWaiter = nil
}
g.doneWaitingAtLock(false, l)
Expand All @@ -1336,50 +1336,14 @@ func (l *lockState) lockIsFree() (gc bool) {
l.queuedWriters.Remove(e)
if qg.active {
g.doneWaitingAtLock(true, l)
if g == l.distinguishedWaiter {
l.distinguishedWaiter = nil
}
}
// Else inactive waiter and is waiting elsewhere.

// Need to find a new distinguished waiter if the current distinguished is
// from the same transaction (possibly it is the request that has reserved).
if l.distinguishedWaiter != nil && l.distinguishedWaiter.isTxn(l.reservation.txn) {
findDistinguished = true
l.distinguishedWaiter = nil
}

// Need to tell the remaining active waiting writers who they are waiting
// for.
waitForState := waitingState{
stateKind: waitFor,
txn: g.txn,
ts: g.ts,
key: l.key,
access: spanset.SpanReadWrite,
guardAccess: spanset.SpanReadWrite,
}
waitSelfState := waitingState{stateKind: waitSelf}
for e := l.queuedWriters.Front(); e != nil; e = e.Next() {
qg := e.Value.(*queuedGuard)
if qg.active {
g := qg.guard
var state waitingState
if g.isTxn(l.reservation.txn) {
state = waitSelfState
} else {
state = waitForState
if findDistinguished {
l.distinguishedWaiter = g
findDistinguished = false
}
}
g.mu.Lock()
g.mu.state = state
if l.distinguishedWaiter == g {
g.mu.state.stateKind = waitForDistinguished
}
g.notify()
g.mu.Unlock()
}
}
// Tell the active waiters who they are waiting for.
l.informActiveWaiters()
return false
}

Expand Down

0 comments on commit a1f1467

Please sign in to comment.