Fix concurrency bug in bottom-up resolution walk.

Concurrency is hard, and now that we no longer track origin it doesn't
improve performance in any meaningful way.

Bug: 261787132

Test: m droid dist compliance_dumpgraph compliance_dumpresolutions \
        compliance_sbom compliance_listshare compliance_rtrace \
        compliance_checkshare xmlnotice textnotice htmlnotice \
        compliancenotice_shippedlibs compliancenotice_bom

Test: m compliance_checkshare cts && \
        out/host/linux-x86/bin/compliance_checkshare out/host/linux-x86/gen/META/lic_intermediates/out/host/linux-x86/cts/android-cts.zip.meta_lic

Test: similar command as above for gts on internal

Test: m compliance_checksare droid dist && \
        out/host/linux-x86/bin/compliance_checkshare out/target/product/sunfish/gen/META/lic_intermediates/out/target/product/sunfish/obj/PACKAGING/systemimage_intermediates/system.img.meta_lic

Change-Id: I57a75927bf879c3ce6603049d8d583211dc0ce29
diff --git a/tools/compliance/policy_resolve.go b/tools/compliance/policy_resolve.go
index fc8ed4c..0951ba1 100644
--- a/tools/compliance/policy_resolve.go
+++ b/tools/compliance/policy_resolve.go
@@ -14,10 +14,6 @@
 
 package compliance
 
-import (
-	"sync"
-)
-
 var (
 	// AllResolutions is a TraceConditions function that resolves all
 	// unfiltered license conditions.
@@ -53,16 +49,10 @@
 		// amap identifes targets previously walked. (guarded by mu)
 		amap := make(map[*TargetNode]struct{})
 
-		// mu guards concurrent access to amap
-		var mu sync.Mutex
-
 		var walk func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet
 
 		walk = func(target *TargetNode, treatAsAggregate bool) LicenseConditionSet {
 			priorWalkResults := func() (LicenseConditionSet, bool) {
-				mu.Lock()
-				defer mu.Unlock()
-
 				if _, alreadyWalked := amap[target]; alreadyWalked {
 					if treatAsAggregate {
 						return target.resolution, true
@@ -84,25 +74,17 @@
 				return cs
 			}
 
-			c := make(chan LicenseConditionSet, len(target.edges))
 			// add all the conditions from all the dependencies
 			for _, edge := range target.edges {
-				go func(edge *TargetEdge) {
-					// walk dependency to get its conditions
-					cs := walk(edge.dependency, treatAsAggregate && edge.dependency.IsContainer())
+				// walk dependency to get its conditions
+				dcs := walk(edge.dependency, treatAsAggregate && edge.dependency.IsContainer())
 
-					// turn those into the conditions that apply to the target
-					cs = depConditionsPropagatingToTarget(lg, edge, cs, treatAsAggregate)
-
-					c <- cs
-				}(edge)
+				// turn those into the conditions that apply to the target
+				dcs = depConditionsPropagatingToTarget(lg, edge, dcs, treatAsAggregate)
+				cs |= dcs
 			}
-			for i := 0; i < len(target.edges); i++ {
-				cs |= <-c
-			}
-			mu.Lock()
 			target.resolution |= cs
-			mu.Unlock()
+			cs = target.resolution
 
 			// return conditions up the tree
 			return cs
@@ -133,33 +115,21 @@
 
 	// short-cut if already walked and cached
 	lg.onceTopDown.Do(func() {
-		wg := &sync.WaitGroup{}
-		wg.Add(1)
-
 		// start with the conditions propagated up the graph
 		TraceBottomUpConditions(lg, conditionsFn)
 
 		// amap contains the set of targets already walked. (guarded by mu)
 		amap := make(map[*TargetNode]struct{})
 
-		// mu guards concurrent access to amap
-		var mu sync.Mutex
-
 		var walk func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool)
 
 		walk = func(fnode *TargetNode, cs LicenseConditionSet, treatAsAggregate bool) {
-			defer wg.Done()
 			continueWalk := func() bool {
-				mu.Lock()
-				defer mu.Unlock()
-
-				depcs := fnode.resolution
-				_, alreadyWalked := amap[fnode]
-				if alreadyWalked {
+				if _, alreadyWalked := amap[fnode]; alreadyWalked {
 					if cs.IsEmpty() {
 						return false
 					}
-					if cs.Difference(depcs).IsEmpty() {
+					if cs.Difference(fnode.resolution).IsEmpty() {
 						// no new conditions
 
 						// pure aggregates never need walking a 2nd time with same conditions
@@ -172,8 +142,9 @@
 						}
 						// previously walked as pure aggregate; need to re-walk as non-aggregate
 					}
+				} else {
+					fnode.resolution |= conditionsFn(fnode)
 				}
-				fnode.resolution |= conditionsFn(fnode)
 				fnode.resolution |= cs
 				fnode.pure = treatAsAggregate
 				amap[fnode] = struct{}{}
@@ -189,19 +160,15 @@
 				dcs := targetConditionsPropagatingToDep(lg, edge, cs, treatAsAggregate, conditionsFn)
 				dnode := edge.dependency
 				// add the conditions to the dependency
-				wg.Add(1)
-				go walk(dnode, dcs, treatAsAggregate && dnode.IsContainer())
+				walk(dnode, dcs, treatAsAggregate && dnode.IsContainer())
 			}
 		}
 
 		// walk each of the roots
 		for _, rname := range lg.rootFiles {
 			rnode := lg.targets[rname]
-			wg.Add(1)
 			// add the conditions to the root and its transitive closure
-			go walk(rnode, NewLicenseConditionSet(), rnode.IsContainer())
+			walk(rnode, NewLicenseConditionSet(), rnode.IsContainer())
 		}
-		wg.Done()
-		wg.Wait()
 	})
 }