shuffling-allocator 1.1.2

A shuffling allocator, randomizing heap object locations; useful for avoiding accidental cache locality during benchmarking, which can obscure performance evaluation.
Documentation
use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::{
    alloc::{handle_alloc_error, GlobalAlloc, Layout},
    ptr,
};
use winapi::um::synchapi::{
    AcquireSRWLockExclusive, ReleaseSRWLockExclusive, SRWLOCK, SRWLOCK_INIT,
};

pub(crate) struct WindowsMutex<A, T>
where
    A: 'static + GlobalAlloc,
{
    inner: *mut SRWLOCK,
    value: UnsafeCell<T>,
    allocator: &'static A,
}

impl<A, T> Drop for WindowsMutex<A, T>
where
    A: 'static + GlobalAlloc,
{
    fn drop(&mut self) {
        unsafe {
            let layout = Layout::new::<SRWLOCK>();
            self.allocator.dealloc(self.inner.cast(), layout);
        }
    }
}

impl<A, T> WindowsMutex<A, T>
where
    A: 'static + GlobalAlloc,
{
    pub fn new(allocator: &'static A, value: T) -> Self {
        let layout = Layout::new::<SRWLOCK>();
        let inner: *mut SRWLOCK = unsafe { allocator.alloc(layout).cast() };
        if inner.is_null() {
            handle_alloc_error(layout);
        }

        unsafe {
            ptr::write(inner, SRWLOCK_INIT);
        }

        WindowsMutex {
            inner,
            value: UnsafeCell::new(value),
            allocator,
        }
    }

    pub fn lock(&self) -> WindowsLockGuard<A, T> {
        unsafe {
            AcquireSRWLockExclusive(self.inner);
        }
        WindowsLockGuard { mutex: self }
    }
}

pub struct WindowsLockGuard<'a, A, T>
where
    A: 'static + GlobalAlloc,
{
    mutex: &'a WindowsMutex<A, T>,
}

impl<'a, A, T> Drop for WindowsLockGuard<'a, A, T>
where
    A: 'static + GlobalAlloc,
{
    fn drop(&mut self) {
        unsafe {
            ReleaseSRWLockExclusive(self.mutex.inner);
        }
    }
}

impl<'a, A, T> Deref for WindowsLockGuard<'a, A, T>
where
    A: 'static + GlobalAlloc,
{
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.mutex.value.get() }
    }
}

impl<'a, A, T> DerefMut for WindowsLockGuard<'a, A, T>
where
    A: 'static + GlobalAlloc,
{
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.mutex.value.get() }
    }
}