- 
                Notifications
    You must be signed in to change notification settings 
- Fork 3
[DNM] remove thread safety #45
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -16,8 +16,8 @@ | |
| else | ||
| mutable struct Perm{T<:Integer} <: AP.AbstractPermutation | ||
| images::Vector{T} | ||
| @atomic inv::Perm{T} | ||
| @atomic cycles::AP.CycleDecomposition{T} | ||
| inv::Perm{T} | ||
| cycles::AP.CycleDecomposition{T} | ||
|  | ||
| function Perm{T}(images::Vector{T}; check::Bool = true) where {T} | ||
| if check && !isperm(images) | ||
|  | @@ -92,36 +92,36 @@ else | |
| function Base.copy(p::Perm) | ||
| imgs = copy(p.images) | ||
| q = typeof(p)(imgs; check = false) | ||
| if isdefined(p, :inv, :sequentially_consistent) | ||
| inv_imgs = copy(@atomic(p.inv).images) | ||
| if isdefined(p, :inv) | ||
| inv_imgs = copy(p.inv.images) | ||
| q⁻¹ = typeof(p)(inv_imgs; check = false) | ||
| @atomic q.inv = q⁻¹ | ||
| @atomic q⁻¹.inv = q | ||
| q.inv = q⁻¹ | ||
| q⁻¹.inv = q | ||
| end | ||
| return q | ||
| end | ||
|  | ||
| function Base.inv(σ::Perm) | ||
| if !isdefined(σ, :inv, :sequentially_consistent) | ||
| if !isdefined(σ, :inv) | ||
| if isone(σ) | ||
| @atomic σ.inv = σ | ||
| σ.inv = σ | ||
| else | ||
| σ⁻¹ = typeof(σ)(invperm(σ.images); check = false) | ||
| # we don't want to end up with two copies of inverse σ floating around | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is not valid (doesn't describe the code / not physically possible). There is an atomic annotation for this ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vtjnash thanks for the comments! Yeah, now after you pointed this, it seems obvious that I should have done @atomic σ⁻¹.inv = σ # fully sets up the "local inverse"
@atomic σ.inv = σ⁻¹ # makes the "local inverse" visible to the global world.so that  I guess reading of  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It isn't super clear what you want or need here. I think you're just asking for a release store, since the reverse order has the opposite problem since they reference each other. Otherwise you'd have to use a global mutex (to actually implement the comment) and I'm unclear that you actually want that behavior? You also must use atomiconce macro if you want this only happen once, otherwise it will be atomic, but happen potentially as many times as there are threads There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine this happening multiple times, cause once the field is defined there will be only reads to it; What I want to avoid is the situation where  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
 That is not quite what you implemented with  There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine if two/many threads enter the body of  To put it differently: Are these statements correct: 
 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that sounds like what you get from marking it with sequential consistency (though it can be slower than release-acquire which is all you really need). Though even without any atomic annotations, reference fields get implemented with release-consume, so these atomics don't appear that they would make a difference to the observable behaviors There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for the clarification!     if isdefined(p, :inv, :acquire)
        inv_imgs = copy(@atomic(p.inv).images)
        q⁻¹ = typeof(p)(inv_imgs; check = false)
        @atomic q⁻¹.inv = q # which ordering here?
        @atomiconce :release q.inv = q⁻¹
    endHmm, I'm not sure again if I understand how this could be achieved without atomics. e.g. I had situation where on lazy initializations I was getting "Access to undefined field" despite using  My understanding of the fine details of multithreading is lacking, so I appreciate all of the comments of yours. They help me to clarify things in my head, thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :release or :monotonic would be fine there, since that is not globally visible memory. You might get a torn read/write if it is a struct that can be inlined which can cause things to get into an inconsistent state. Using  | ||
| if !isdefined(σ, :inv, :sequentially_consistent) | ||
| @atomic σ.inv = σ⁻¹ | ||
| @atomic σ⁻¹.inv = σ | ||
| if !isdefined(σ, :inv) | ||
| σ.inv = σ⁻¹ | ||
| σ⁻¹.inv = σ | ||
| end | ||
| end | ||
| end | ||
| return σ.inv | ||
| end | ||
|  | ||
| function AP.cycles(σ::Perm) | ||
| if !isdefined(σ, :cycles, :sequentially_consistent) | ||
| if !isdefined(σ, :cycles) | ||
| cdec = AP.CycleDecomposition(σ) | ||
| # we can afford producing more than one cycle decomposition | ||
| @atomic σ.cycles = cdec | ||
| σ.cycles = cdec | ||
| end | ||
| return σ.cycles | ||
| end | ||
|  | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
You did have a bad mistake here (of generally the error sort, though generally not the crash sort), since you assigned these in the wrong order, the
:sequentially_consistentannotation is invalidated everywhere and invalid.