-1

I'm making an image processing pipeline (with one thread per processing step) but I have been struggling with a SynchronizationLockException for a while. I can't figure out why it is raised.

Here is the code :

int bufferWriterPointer;
lock (_bufferPointerLock)
{
    bufferWriterPointer = _bufferWriterPointer++;
    if (_bufferWriterPointer == BufferNbr)
          _bufferWriterPointer = 0;
}

BitmapFrame frame = BytesBuffers[bufferWriterPointer];
lock(frame)
{
    SIMDHelper.Copy(newBuffer, frame.Data);
}

lock (_bufferPointerLock)
    UnReadBufferNbr++;

Here is the context

And here is the code of the bitmapFrame

public class BitmapFrame : Frame
{
    public Bitmap Bitmap { get; set; }

    public BitmapFrame(byte[] data) : base(data) { Bitmap = null; }

    public BitmapFrame(byte[] data, Bitmap bmp) : base(data)
    {
        Bitmap = bmp;
    }
}

And the SIMDHelper class is mapping a c++ lib :

    public static void Copy(byte[] sourceBuffer, byte[] destinationBuffer)
    {
        GCHandle pinnedSrcBuffer = GCHandle.Alloc(sourceBuffer, GCHandleType.Pinned);
        IntPtr srcBufferPtr = pinnedSrcBuffer.AddrOfPinnedObject();

        GCHandle pinnedDestBuffer = GCHandle.Alloc(destinationBuffer, GCHandleType.Pinned);
        IntPtr destBuffer = pinnedDestBuffer.AddrOfPinnedObject();

        SIMD.SimdCopy(srcBufferPtr, sourceBuffer.Length, sourceBuffer.Length, 1, 1, destBuffer, sourceBuffer.Length);

        pinnedDestBuffer.Free();
        pinnedSrcBuffer.Free();
    }

With :

[DllImport(SIMD_LIBRARY_FILENAME, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void SimdCopy(IntPtr sourcePointer, nint sourceStride, nint width, nint height, nint pixelSize, IntPtr destinationPointer, nint destinationStride);
Hidden_Bad
  • 33
  • 5
  • 1
    Why on are you using a raw monitor instead of a lock? Your exception is most likely because you are using the monitor incorrectly. If you just want a critical section, use a lock. It is only a wrapper around a monitor anyway, but adds all the safety boilerplate that is easy to forget. – JonasH Sep 14 '22 at 10:05
  • Unfortunately, I still get the same error – Hidden_Bad Sep 14 '22 at 10:07
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Sep 15 '22 at 01:14

1 Answers1

1

I figured out that the destination byte[] array was too small (by replacing my copy fuunction by Array.Copy()), so there probably was a segmentation fault in the unmanaged code and it was creating unexpected behavior such as a SynchronizationLockException.

Hidden_Bad
  • 33
  • 5
  • 1
    What's the purpose of this code? .NET has SIMD types in the Numerics namespace, including intrinsics. The Span and Memory types allow safer handling of native memory. – Panagiotis Kanavos Sep 14 '22 at 10:35
  • As for copying bytes, [BlockCopy](https://learn.microsoft.com/en-us/dotnet/api/system.buffer.blockcopy?view=net-6.0) and [MemoryCopy](https://learn.microsoft.com/en-us/dotnet/api/system.buffer.memorycopy?view=net-6.0) offer fast copying. I'm not sure SIMD offers any benefits when you're copying data from RAM location to RAM location. If anything, this will pollute the CPU's cache – Panagiotis Kanavos Sep 14 '22 at 10:41
  • Thanks for your advice, I will make some benchmark to check which option is faster – Hidden_Bad Sep 14 '22 at 10:55