From 8cf1a878ccaa8d71afb7e975637f1fbcc20b6a53 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 24 Jul 2015 00:17:52 +0200 Subject: [PATCH] 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. --- renderdocui/Interop/CustomMarshaling.cs | 115 +++++++++++++----------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/renderdocui/Interop/CustomMarshaling.cs b/renderdocui/Interop/CustomMarshaling.cs index 438e395ca..b2f47b028 100644 --- a/renderdocui/Interop/CustomMarshaling.cs +++ b/renderdocui/Interop/CustomMarshaling.cs @@ -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); } }