- 
                Notifications
    You must be signed in to change notification settings 
- Fork 10.6k
[Dependency Scanning] Isolate shared dependency scanner state #64615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    Conversation
  
    
      This file contains hidden or 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
    
  
  
    
    | @swift-ci test | 
Using mutual exclusion, ensuring that multiple threads executing dependency scans do not encounter data races on shared mutable state. There are two layers with shared state where we need to be careful: - `DependencyScanningTool`, as the main entity that scanning clients interact with. This tool instantiates compiler instances for individual scans, computing a scanning invocation hash. It needs to remember those instances for future use, and when creating instances it needs to reset LLVM argument processor's global state, meaning all uses of argument processing must be in a critical section. - `SwiftDependencyScanningService`, as the main cache where dependency scanning results are stored. Each individual scan instantiates a `ModuleDependenciesCache`, which uses the scanning service as the underlying storage. The services' storage is segmented to storing dependencies discovered in a scan with a given context hash, which means two different scanning invocations running at the same time will be accessing different locations in its storage, thus not requiring synchronization. But the service still has some shared state that must be protected, such as the collection of discovered source modules, and the map used to query context-hash-specific underlying cache storage.
880c260    to
    3d110f8      
    Compare
  
    | @swift-ci test | 
              
                    nkcsgexi
  
              
              approved these changes
              
                  
                    Mar 27, 2023 
                  
              
              
            
            
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me!
    
  artemcm 
      added a commit
        to artemcm/swift-driver
      that referenced
      this pull request
    
      Mar 28, 2023 
    
    
      
  
    
      
    
  
…pendency scan queries In the `InterModuleDependencyOracle`, which may be shared across different instances of the `Driver`, all dependency scanning queries are executed synchronously on a shared dispatch queue. This is no longer necessary with the scanner guarding its own shared state as of swiftlang/swift#64615.
    
  artemcm 
      added a commit
        to artemcm/swift-driver
      that referenced
      this pull request
    
      Apr 7, 2023 
    
    
      
  
    
      
    
  
…pendency scan queries In the `InterModuleDependencyOracle`, which may be shared across different instances of the `Driver`, all dependency scanning queries are executed synchronously on a shared dispatch queue. This is no longer necessary with the scanner guarding its own shared state as of swiftlang/swift#64615.
    
  artemcm 
      added a commit
        to artemcm/swift-driver
      that referenced
      this pull request
    
      Apr 7, 2023 
    
    
      
  
    
      
    
  
…pendency scan queries In the `InterModuleDependencyOracle`, which may be shared across different instances of the `Driver`, all dependency scanning queries are executed synchronously on a shared dispatch queue. This is no longer necessary with the scanner guarding its own shared state as of swiftlang/swift#64615.
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
      
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Using mutual exclusion, ensuring that multiple threads executing dependency scans do not encounter data races on shared mutable state of the scanning service.
There are two layers with shared state where we need to be careful:
DependencyScanningTool, as the main entity that scanning clients interact with. This tool instantiates compiler instances for individual scans, computing a scanning invocation hash. It needs to remember those instances for future use, and when creating instances it needs to reset LLVM argument processor's global state, meaning all uses of argument processing must be in a critical section.SwiftDependencyScanningService, as the main cache where dependency scanning results are stored. Each individual scan instantiates aModuleDependenciesCache, which uses the scanning service as the underlying storage. The services' storage is segmented to storing dependencies discovered in a scan with a given context hash, which means two different scanning invocations running at the same time will be accessing different locations in its storage, thus not requiring synchronization. But the service still has some shared state that must be protected, such as the collection of discovered source modules, and the map used to query context-hash-specific underlying cache storage.