Skip to content

Conversation

@pchintalapudi
Copy link
Member

These atomics depend on the following rules:

On the write side:

  1. Once set, specptr may never change to an invalid value (i.e. it must always be callable as a specptr)
  2. specsigflags & 0b1 may only be set if the current thread just set specptr and the previous value of specptr was NULL
  3. Once set, invokeptr may never change to an invalid value (i.e. it must always be callable as an invokeptr)
  4. specsigflags & 0b10 must be set after the current thread sets both invokeptr and specptr

On the read side:

  1. When planning to read from specsigflags or specptr, invokeptr should be loaded with at least acquire semantics
  2. When reading from specsigflags or specptr for non-calling purposes, if specptr is non-null, then it is necessary to busy-loop on specsigflags & 0b10 until that bit is set
  3. invokeptr must be reloaded (relaxed) after the previous busyloop

The reasoning behind this set of changes is that we want to support multiple threads setting specptr/invokeptr/specsig to potentially different values, and we don't want to end up in a situation where the codeinst transitions from being valid to be called to invalid to be called. This motivates the once-set restrictions. However, we also want to support potential future upgrading of invokeptr/specptr (e.g. to transition from interpreted to compiled, or compiled at low optimization to compiled at high optimization), which motivates being able to override specptr and invokeptr as long as those values are equivalently callable.

Invokeptr must be reloaded after checking for 0b10 in specsigflags due to the case of the original load returning an invokeptr that does not rely on specptr (for interpretation), but then another thread sets specptr. In this case, we want to grab the updated invokeptr which we know is definitely written after specsigflags & 0b10 is set.

@pchintalapudi pchintalapudi requested a review from vtjnash December 7, 2022 23:18
@pchintalapudi pchintalapudi force-pushed the pc/invoke-specptr-atomics branch 2 times, most recently from 0aba553 to 3d37f33 Compare December 8, 2022 05:44
@pchintalapudi pchintalapudi requested a review from tkf December 9, 2022 04:56
@pchintalapudi pchintalapudi force-pushed the pc/invoke-specptr-atomics branch from 3d37f33 to 51fe491 Compare December 12, 2022 19:28
Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (reviewed in-person)

Should we also make this a little more accurate (requiring forward progress of each iteration):

diff --git a/src/gf.c b/src/gf.c
index df50b42216..b8223efb7c 100644
--- a/src/gf.c
+++ b/src/gf.c
@@ -2199,10 +2199,11 @@ jl_value_t *jl_fptr_const_return(jl_value_t *f, jl_value_t **args, uint32_t narg
 
 jl_value_t *jl_fptr_args(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m)
 {
+    jl_fptr_args_t invoke = jl_atomic_load_relaxed(&m->specptr.fptr1);
     while (1) {
-        jl_fptr_args_t invoke = jl_atomic_load_relaxed(&m->specptr.fptr1);
         if (invoke)
             return invoke(f, args, nargs);
+        invoke = jl_atomic_load_acquire(&m->specptr.fptr1);
     }
 }

@pchintalapudi
Copy link
Member Author

@maleadt does GPUCompiler use any of codeinst->(invoke, specptr, isspecsig)? If so, we'll need to update those parts of GPUCompiler to conform to these restrictions.

@maleadt
Copy link
Member

maleadt commented Dec 13, 2022

@maleadt does GPUCompiler use any of codeinst->(invoke, specptr, isspecsig)?

No, we never use what's been compiled by the JIT, but use aotcompile directly.

@brenhinkeller brenhinkeller added compiler:codegen Generation of LLVM IR and native code multithreading Base.Threads and related functionality labels Dec 20, 2022
@vtjnash
Copy link
Member

vtjnash commented Feb 3, 2023

bump? Looks like this needs a rebase

@pchintalapudi pchintalapudi force-pushed the pc/invoke-specptr-atomics branch from 670bf11 to d6b7fd6 Compare February 3, 2023 06:12
@pchintalapudi pchintalapudi force-pushed the pc/invoke-specptr-atomics branch from 9ccd54c to 41fb231 Compare February 13, 2023 19:04
@pchintalapudi pchintalapudi added the merge me PR is reviewed. Merge when all tests are passing label Feb 13, 2023
@vchuravy vchuravy merged commit 6412a56 into master Feb 22, 2023
@vchuravy vchuravy deleted the pc/invoke-specptr-atomics branch February 22, 2023 04:07
@vchuravy vchuravy added the backport 1.9 Change should be backported to release-1.9 label Feb 22, 2023
@giordano giordano removed the merge me PR is reviewed. Merge when all tests are passing label Feb 22, 2023
pchintalapudi added a commit that referenced this pull request Mar 2, 2023
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Dilum Aluthge <[email protected]>
(cherry picked from commit 6412a56)
pchintalapudi added a commit that referenced this pull request Mar 2, 2023
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Dilum Aluthge <[email protected]>
(cherry picked from commit 6412a56)
@KristofferC KristofferC mentioned this pull request Mar 3, 2023
50 tasks
vchuravy pushed a commit that referenced this pull request Mar 3, 2023
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Dilum Aluthge <[email protected]>
(cherry picked from commit 6412a56)
KristofferC pushed a commit that referenced this pull request Mar 3, 2023
Co-authored-by: Jameson Nash <[email protected]>
Co-authored-by: Dilum Aluthge <[email protected]>
(cherry picked from commit 6412a56)
@KristofferC KristofferC removed the backport 1.9 Change should be backported to release-1.9 label Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler:codegen Generation of LLVM IR and native code multithreading Base.Threads and related functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants