Search Unity

Direct Burst function call safety with refs to data in managed memory

Discussion in 'Data Oriented Technology Stack' started by Zuntatos, Apr 12, 2021.

  1. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    580
    To my understanding, there's 3 primary places data can reside and how they interact with GC:
    - stack (safe to reference, GC not involved)
    - managed memory (unsafe to reference; need to pin first)
    - unmanaged memory (safe to reference, unless you free it manually and invalidate the reference with that, or have an invalid pointer, etc)

    With the direct burst function calls you can now pass references to managed memory into native code. Is this handled correctly, or must we manually ensure that we only pass references to the stack or to unmanaged memory?

    A 'naive' implementation would introduce a risk of a GC cycle happening by some other thread running managed code that invalidates the referenced memory while a burst method is running.

    Example code (that practically would not really trigger the case, but to give an idea)

    Code (CSharp):
    1.  
    2. class Test
    3. {
    4.    float a;
    5.    float b;
    6.    float c;
    7.    float d;
    8.  
    9.    public void ManagedThing ()
    10.    {
    11.        BurstFunction.move(ref a, ref b, ref c, ref d);
    12.    }
    13.  
    14.    [Unity.Burst.BurstCompile]
    15.    static class BurstFunction
    16.    {
    17.        [Unity.Burst.BurstCompile]
    18.        public static void move (ref float a, ref float b, ref float c, ref float d)
    19.        {
    20.            b = a;
    21.            // consider a GC cycle happening here, which collects the Test instance which holds the floats
    22.            d = c;
    23.        }
    24.    }
    25. }
    26.  
    My version of ILSpy gives a NotSupportedException when trying to inspect the methods in a build dll, so I can't see if the generated wrapper deals with this situation.
    If it's making a stack copy and writing that back after the call than it would be okay, though that would have performance implications to consider in what to pass.
     
unityunity