go.empty_critical_section
Performance
Medium
Detects mutex locks protecting empty or trivial critical sections, causing unnecessary contention.
Why It Matters
Section titled “Why It Matters”Empty critical sections cause:
- Unnecessary contention - Goroutines block for nothing
- Deadlock risk - Complex lock patterns with no benefit
- Performance degradation - Lock overhead without protection
- Code smell - Often indicates incomplete implementations
Example
Section titled “Example”// ❌ Before (pointless locking)var mu sync.Mutex
func process() { mu.Lock() defer mu.Unlock() // Nothing protected!}
// Also problematicfunc update() { mu.Lock() mu.Unlock() // Immediate unlock doWork() // Work happens outside lock}// ✅ After (meaningful critical section)var mu sync.Mutexvar counter int
func process() { mu.Lock() defer mu.Unlock() counter++ // Actually protected}What Unfault Detects
Section titled “What Unfault Detects”Lock()/Unlock()with nothing between themdefer mu.Unlock()with no protected operations- Critical sections with only logging
- Lock/unlock without shared state access
Auto-Fix
Section titled “Auto-Fix”Unfault flags these for manual review since the fix depends on intent:
// Option 1: Remove unnecessary lockfunc process() { doWork() // If no shared state}
// Option 2: Add protected operationsfunc process() { mu.Lock() sharedData = newValue mu.Unlock() doWork()}