Follow up to Infinite loop in NativeHashMap TryAdd
Sorry for making another post, but this is kind of a serious issue has been plaguing our project for 6 months (I’ve had concerns about this for a while due to some weird behavior randomly appearing elsewhere) but I finally got a simple repo.
Tested in Unity 2019.3.9f1
Add these to your package manifest
“com.unity.burst”: “1.3.0-preview.12”,
“com.unity.entities”: “0.9.1-preview.15”,
this brings in collections 0.7.1-preview.3
(not using entities 0.10 due to another bug but this still exists in the latest version)
Add this script
-edit- I have a more consistent repo here:
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
public class HashMapSystem : SystemBase
{
private EntityQuery query;
protected override void OnCreate()
{
query = GetEntityQuery(ComponentType.ReadOnly<CommonComponent>());
var archetype0 = EntityManager.CreateArchetype(typeof(CommonComponent));
EntityManager.CreateEntity(archetype0, 4000, Allocator.Temp);
var archetype1 = EntityManager.CreateArchetype(typeof(CommonComponent), typeof(Component1));
EntityManager.CreateEntity(archetype1, 4000, Allocator.Temp);
var archetype2 = EntityManager.CreateArchetype(typeof(CommonComponent), typeof(Component1), typeof(Component2));
EntityManager.CreateEntity(archetype2, 4000, Allocator.Temp);
var archetype3 = EntityManager.CreateArchetype(typeof(CommonComponent), typeof(Component1), typeof(Component2), typeof(Component3));
EntityManager.CreateEntity(archetype3, 4000, Allocator.Temp);
}
protected override void OnUpdate()
{
var hashMap = new NativeHashMap<EntityArchetype, ushort>(query.CalculateChunkCount(), Allocator.TempJob);
Dependency = new WriteJob
{
HashMap = hashMap.AsParallelWriter(),
}
.Schedule(query, Dependency);
Dependency = new ReadJob
{
HashMap = hashMap,
}
.Schedule(query, Dependency);
hashMap.Dispose(Dependency);
}
[BurstCompile]
private struct WriteJob : IJobChunk
{
public NativeHashMap<EntityArchetype, ushort>.ParallelWriter HashMap;
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
{
DoJob(chunk.Archetype);
}
private void DoJob(EntityArchetype archetype)
{
HashMap.TryAdd(archetype, 1);
}
}
[BurstCompile]
private struct ReadJob : IJobChunk
{
[ReadOnly] public NativeHashMap<EntityArchetype, ushort> HashMap;
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
{
if (!HashMap.ContainsKey(chunk.Archetype))
{
Debug.LogError("FAILED STATE");
}
}
}
private struct CommonComponent : IComponentData{}
private struct Component1 : IComponentData
{
public int Value1;
}
private struct Component2 : IComponentData
{
public int Value1;
public int Value2;
}
private struct Component3 : IComponentData
{
public int Value1;
public int Value2;
public int Value3;
}
}
Hit play and let it run, it’ll fail eventually.
On my machine with a 3900X (lots of cores) it only takes a few seconds to fail, but it might take longer on a machine with less cores.
I’m going to log a bug report shortly.
Case 1245648