Add locks around static use of CustomMarshal properties

* These locks shouldn't cover much work as generally the caches will
  quickly fill up and the inside-lock work will be quick.
* Also they shouldn't contend as it's quite rare for anything but the
  render thread to go through CustomMarshal.
This commit is contained in:
baldurk
2015-07-24 00:17:52 +02:00
parent 2967a8a5ce
commit 8cf1a878cc
+62 -53
View File
@@ -176,17 +176,20 @@ namespace renderdoc
private static CustomMarshalAsAttribute GetCustomAttr(Type t, FieldInfo[] fields, int fieldIdx)
{
if (!m_CustomAttrCache.ContainsKey(t))
lock (m_CustomAttrCache)
{
var arr = new CustomMarshalAsAttribute[fields.Length];
if (!m_CustomAttrCache.ContainsKey(t))
{
var arr = new CustomMarshalAsAttribute[fields.Length];
for (int i = 0; i < fields.Length; i++)
arr[i] = GetCustomAttr(fields[i]);
for (int i = 0; i < fields.Length; i++)
arr[i] = GetCustomAttr(fields[i]);
m_CustomAttrCache.Add(t, arr);
m_CustomAttrCache.Add(t, arr);
}
return m_CustomAttrCache[t][fieldIdx];
}
return m_CustomAttrCache[t][fieldIdx];
}
private static CustomMarshalAsAttribute GetCustomAttr(FieldInfo field)
@@ -275,28 +278,31 @@ namespace renderdoc
(structureType.IsArray && structureType.GetElementType().IsPrimitive))
return Marshal.SizeOf(structureType);
if (m_SizeCache.ContainsKey(structureType))
return m_SizeCache[structureType];
// Get instance fields of the structure type.
FieldInfo[] fieldInfo = structureType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
long size = 0;
int a = 0;
foreach (FieldInfo field in fieldInfo)
lock (m_SizeCache)
{
AddFieldSize(field, ref size);
a = Math.Max(a, AlignOf(field));
if (m_SizeCache.ContainsKey(structureType))
return m_SizeCache[structureType];
// Get instance fields of the structure type.
FieldInfo[] fieldInfo = structureType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
long size = 0;
int a = 0;
foreach (FieldInfo field in fieldInfo)
{
AddFieldSize(field, ref size);
a = Math.Max(a, AlignOf(field));
}
int alignment = (int)size % a;
if (alignment != 0) size += a - alignment;
m_SizeCache.Add(structureType, (int)size);
return (int)size;
}
int alignment = (int)size % a;
if (alignment != 0) size += a - alignment;
m_SizeCache.Add(structureType, (int)size);
return (int)size;
}
// caching the offset to the nth field from a base pointer to the type
@@ -310,40 +316,43 @@ namespace renderdoc
if (fieldInfo.Length == 0)
return ptr;
if (!m_OffsetAlignCache.ContainsKey(structureType))
lock (m_OffsetCache)
{
Int64[] cacheOffsets = new Int64[fieldInfo.Length];
int initialAlign = AlignOf(fieldInfo[0]);
Int64 p = 0;
for (int i = 0; i < fieldInfo.Length; i++)
if (!m_OffsetAlignCache.ContainsKey(structureType))
{
FieldInfo field = fieldInfo[i];
Int64[] cacheOffsets = new Int64[fieldInfo.Length];
int initialAlign = AlignOf(fieldInfo[0]);
int a = AlignOf(field);
Int64 p = 0;
for (int i = 0; i < fieldInfo.Length; i++)
{
FieldInfo field = fieldInfo[i];
int a = AlignOf(field);
int alignment = (int)p % a;
if (alignment != 0) p += a - alignment;
cacheOffsets[i] = p;
AddFieldSize(field, ref p);
}
m_OffsetAlignCache.Add(structureType, initialAlign);
m_OffsetCache.Add(structureType, cacheOffsets);
}
{
var p = ptr.ToInt64();
int a = m_OffsetAlignCache[structureType];
int alignment = (int)p % a;
if (alignment != 0) p += a - alignment;
cacheOffsets[i] = p;
p += m_OffsetCache[structureType][idx];
AddFieldSize(field, ref p);
return new IntPtr(p);
}
m_OffsetAlignCache.Add(structureType, initialAlign);
m_OffsetCache.Add(structureType, cacheOffsets);
}
{
var p = ptr.ToInt64();
int a = m_OffsetAlignCache[structureType];
int alignment = (int)p % a;
if (alignment != 0) p += a - alignment;
p += m_OffsetCache[structureType][idx];
return new IntPtr(p);
}
}