Static field causing threading issue? (DynamicTree<T>._stack)

Topics: Developer Forum
Jul 16, 2013 at 5:18 PM
I'm trying to use several Worlds at the same time (I'm evolving behaviour and I want each CPU to simulate it's own individual). Unfortunately, even though the worlds and the individuals are 100% separate, one world makes the other world crash. It looks like it's because of the static variable _stack in DynamicTree. If I make it non-static, the crash goes away but the program still crashes later. If I only use one world at a time, everything works fine.

Any ideas? Seems unintuitive to have a static array in a global class...
 public class DynamicTree<T>
    {
        internal const int NullNode = -1;
        private static Stack<int> _stack = new Stack<int>(256);
Jul 16, 2013 at 5:22 PM
Guess, what, the next crash appears in SeparationFunction which also has multiple static fields...
Jul 16, 2013 at 5:53 PM
Edited Jul 16, 2013 at 7:02 PM
Me again, I solved it by making _stack [ThreadStatic]
    public class DynamicTree<T>
    {
        internal const int NullNode = -1;
        [ThreadStatic]
        private static Stack<int> _stack;
and initlializing it in the query call
     public void Query(Func<int, bool> callback, ref AABB aabb)
        {
            _stack = _stack ?? new Stack<int>(256);
            _stack.Clear();
            _stack.Push(_root);
and making all the static fields in SeparationFunction thread static;
    public static class SeparationFunction
    {
        [ThreadStatic]
        private static Vector2 _axis;
        [ThreadStatic]
        private static Vector2 _localPoint;
        [ThreadStatic]
        private static DistanceProxy _proxyA = new DistanceProxy();
        [ThreadStatic]
        private static DistanceProxy _proxyB = new DistanceProxy();
        [ThreadStatic]
        private static Sweep _sweepA, _sweepB;
        [ThreadStatic]
        private static SeparationFunctionType _type;
with initializers for proxyA & proxyB in a couple of spots
Jul 16, 2013 at 6:02 PM
And this;
    public static class Distance
    {
        [ThreadStatic]
        public static int GJKCalls, GJKIters, GJKMaxIters;
Jul 16, 2013 at 10:12 PM
Edited Jul 16, 2013 at 10:13 PM
And this
    public static class TimeOfImpact
    {
        // CCD via the local separating axis method. This seeks progression
        // by computing the largest time at which separation is maintained.
        public static int TOICalls, TOIIters, TOIMaxIters;
        public static int TOIRootIters, TOIMaxRootIters;

        [ThreadStatic] 
        private static DistanceInput _distanceInput;
which requires an initializer in the code
        public static void CalculateTimeOfImpact(out TOIOutput output, TOIInput input)
        {
            ++TOICalls;

            _distanceInput = _distanceInput ?? new DistanceInput();
Coordinator
Jul 18, 2013 at 9:58 PM
The engine is not quite thread safe due to all the static fields you have found. I will take a look at it.
Coordinator
Jul 18, 2013 at 9:59 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.