Remove deviceInstalls from bootImageVariant

The use of this field to return information from buildBootImageVariant
up the call stack to one of the callers resulted in data races being
detected. This change simply passes the deviceInstalls up the call
stack.

Bug: 245956352
Test: m nothing
      go test -race ./sdk/... -run TestSnapshotWithBootclasspathFragment_ImageName -test.count 100
      # Run the previous command without this change and sometimes it
      # shows the data race around deviceInstalls. When run with this
      # change it reports no data races.
Change-Id: I3c73920dcb17a6c89a63c6a9c3a0bb049a98a690
This commit is contained in:
Paul Duffin
2022-10-04 16:39:18 +01:00
parent 9f6ac0bb42
commit e10a9f2e5e
2 changed files with 33 additions and 18 deletions

View File

@@ -598,8 +598,9 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule) copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule)
} }
for _, variant := range imageConfig.apexVariants() { for _, variant := range bootImageFiles.variants {
arch := variant.target.Arch.ArchType.String() archType := variant.config.target.Arch.ArchType
arch := archType.String()
for _, install := range variant.deviceInstalls { for _, install := range variant.deviceInstalls {
// Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") installDir := strings.TrimPrefix(filepath.Dir(install.To), "/")
@@ -1302,8 +1303,17 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
// If the boot image files for the android variants are in the prebuilt apex, we must use those // If the boot image files for the android variants are in the prebuilt apex, we must use those
// rather than building new ones because those boot image files are going to be used on device. // rather than building new ones because those boot image files are going to be used on device.
files := bootImageFilesByArch{} files := bootImageFilesByArch{}
bootImageFiles := bootImageOutputs{
byArch: files,
profile: profile,
}
for _, variant := range imageConfig.apexVariants() { for _, variant := range imageConfig.apexVariants() {
arch := variant.target.Arch.ArchType arch := variant.target.Arch.ArchType
bootImageFiles.variants = append(bootImageFiles.variants, bootImageVariantOutputs{
variant,
// No device installs needed when installed in APEX.
nil,
})
for _, toPath := range variant.imagesDeps { for _, toPath := range variant.imagesDeps {
apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base()) apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
// Get the path to the file that the deapexer extracted from the prebuilt apex file. // Get the path to the file that the deapexer extracted from the prebuilt apex file.
@@ -1321,10 +1331,7 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
}) })
} }
} }
return bootImageOutputs{ return bootImageFiles
files,
profile,
}
} else { } else {
if profile == nil { if profile == nil {
ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex") ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")

View File

@@ -336,11 +336,6 @@ type bootImageVariant struct {
// Deprecated: Not initialized correctly, see struct comment. // Deprecated: Not initialized correctly, see struct comment.
unstrippedInstalls android.RuleBuilderInstalls unstrippedInstalls android.RuleBuilderInstalls
// Rules which should be used in make to install the outputs on device.
//
// Deprecated: Not initialized correctly, see struct comment.
deviceInstalls android.RuleBuilderInstalls
// Path to the license metadata file for the module that built the image. // Path to the license metadata file for the module that built the image.
// //
// Deprecated: Not initialized correctly, see struct comment. // Deprecated: Not initialized correctly, see struct comment.
@@ -591,6 +586,8 @@ type bootImageOutputs struct {
// Map from arch to the paths to the boot image files created/obtained for that arch. // Map from arch to the paths to the boot image files created/obtained for that arch.
byArch bootImageFilesByArch byArch bootImageFilesByArch
variants []bootImageVariantOutputs
// The path to the profile file created/obtained for the boot image. // The path to the profile file created/obtained for the boot image.
profile android.WritablePath profile android.WritablePath
} }
@@ -602,17 +599,19 @@ type bootImageOutputs struct {
// It returns a map from android.ArchType to the predefined paths of the boot image files. // It returns a map from android.ArchType to the predefined paths of the boot image files.
func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageOutputs { func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageOutputs {
filesByArch := bootImageFilesByArch{} filesByArch := bootImageFilesByArch{}
imageOutputs := bootImageOutputs{
byArch: filesByArch,
profile: profile,
}
for _, variant := range image.variants { for _, variant := range image.variants {
if variant.target.Os == requiredOsType { if variant.target.Os == requiredOsType {
buildBootImageVariant(ctx, variant, profile) variantOutputs := buildBootImageVariant(ctx, variant, profile)
imageOutputs.variants = append(imageOutputs.variants, variantOutputs)
filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths() filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths()
} }
} }
return bootImageOutputs{ return imageOutputs
filesByArch,
profile,
}
} }
// buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files. // buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files.
@@ -640,8 +639,13 @@ func buildBootImageZipInPredefinedLocation(ctx android.ModuleContext, image *boo
rule.Build("zip_"+image.name, "zip "+image.name+" image") rule.Build("zip_"+image.name, "zip "+image.name+" image")
} }
type bootImageVariantOutputs struct {
config *bootImageVariant
deviceInstalls android.RuleBuilderInstalls
}
// Generate boot image build rules for a specific target. // Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) { func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs {
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx)
@@ -802,8 +806,12 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
image.installs = rule.Installs() image.installs = rule.Installs()
image.vdexInstalls = vdexInstalls image.vdexInstalls = vdexInstalls
image.unstrippedInstalls = unstrippedInstalls image.unstrippedInstalls = unstrippedInstalls
image.deviceInstalls = deviceInstalls
image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile())
return bootImageVariantOutputs{
image,
deviceInstalls,
}
} }
const failureMessage = `ERROR: Dex2oat failed to compile a boot image. const failureMessage = `ERROR: Dex2oat failed to compile a boot image.