forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DNM] stop: disable task tracking in release builds, optimize task cr…
…eation This commit optimizes the Stopper for task creation by ripping out the existing heavyweight task tracking in production builds. I realized that my biggest concern with most of the proposals (cockroachdb#52843 and cockroachdb#51566) being floated to address cockroachdb#51544 was that they bought more into the inefficient tracking in the Stopper, not that they were doing anything inherently wrong themselves. Before this change, creating a task acquired an exclusive mutex and then wrote to a hashmap. At high levels of concurrency, this would have become a performance chokepoint. After this change, the cost of launching a Task is three atomic increments – one to acquire a read lock, one to register with a WaitGroup, and one to release the read lock. When no one is draining the Stopper, these are all wait-free operations, which means that task creation becomes wait-free. With a change like this, I would feel much more comfortable pushing on Stopper tasks to solve cockroachdb#51544.
- Loading branch information
1 parent
8324ed3
commit 626fa13
Showing
4 changed files
with
177 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright 2020 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
package stop | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
) | ||
|
||
// A TaskMap is returned by taskRegistry.RunningTasks(). | ||
type TaskMap map[string]int | ||
|
||
// String implements fmt.Stringer and returns a sorted multi-line listing of | ||
// the TaskMap. | ||
func (tm TaskMap) String() string { | ||
var lines []string | ||
for location, num := range tm { | ||
lines = append(lines, fmt.Sprintf("%-6d %s", num, location)) | ||
} | ||
sort.Sort(sort.Reverse(sort.StringSlice(lines))) | ||
return strings.Join(lines, "\n") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2020 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
// +build race | ||
|
||
package stop | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/cockroachdb/cockroach/pkg/util/syncutil" | ||
) | ||
|
||
// Drain and Register are never called concurrently. | ||
type taskRegistry struct { | ||
mu syncutil.Mutex | ||
wg sync.WaitGroup | ||
numTasks int | ||
tasks TaskMap | ||
} | ||
|
||
func makeTaskRegistry() taskRegistry { | ||
return taskRegistry{ | ||
tasks: TaskMap{}, | ||
} | ||
} | ||
|
||
func (r *taskRegistry) Register(taskName string) { | ||
r.mu.Lock() | ||
defer r.mu.Unlock() | ||
r.wg.Add(1) | ||
r.numTasks++ | ||
r.tasks[taskName]++ | ||
} | ||
|
||
func (r *taskRegistry) Unregister(taskName string) { | ||
r.mu.Lock() | ||
defer r.mu.Unlock() | ||
r.wg.Done() | ||
r.numTasks-- | ||
r.tasks[taskName]-- | ||
} | ||
|
||
func (r *taskRegistry) Quiesce() { | ||
r.wg.Wait() | ||
} | ||
|
||
func (r *taskRegistry) NumTasks() int { | ||
r.mu.Lock() | ||
defer r.mu.Unlock() | ||
return r.numTasks | ||
} | ||
|
||
// RunningTasks returns a map containing the count of running tasks keyed by | ||
// call site. | ||
func (r *taskRegistry) RunningTasks() TaskMap { | ||
r.mu.Lock() | ||
defer r.mu.Unlock() | ||
m := TaskMap{} | ||
for k := range r.tasks { | ||
if r.tasks[k] == 0 { | ||
continue | ||
} | ||
m[k] = r.tasks[k] | ||
} | ||
return m | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2020 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
// +build !race | ||
|
||
package stop | ||
|
||
import "sync" | ||
|
||
// Drain and Register are never called concurrently. | ||
type taskRegistry struct { | ||
wg sync.WaitGroup | ||
} | ||
|
||
func makeTaskRegistry() taskRegistry { | ||
return taskRegistry{} | ||
} | ||
|
||
func (r *taskRegistry) Register(taskName string) { | ||
r.wg.Add(1) | ||
} | ||
|
||
func (r *taskRegistry) Unregister(taskName string) { | ||
r.wg.Done() | ||
} | ||
|
||
func (r *taskRegistry) Quiesce() { | ||
r.wg.Wait() | ||
} | ||
|
||
func (r *taskRegistry) NumTasks() int { | ||
return -1 | ||
} | ||
|
||
func (r *taskRegistry) RunningTasks() TaskMap { | ||
return TaskMap{"tracking disabled": 0} | ||
} |