chuigda-wasteland / Pr65

决战的时刻到了!
The Unlicense
3 stars 0 forks source link

Semaphore Optimization #4

Open SchrodingerZhu opened 4 years ago

SchrodingerZhu commented 4 years ago

Provide a Wrapper around original semaphore may result in a good one. According to my local benchmark, this performs better but the gaining is not apparent (because my test is too simple).

How about leave this issue open and give a benchmark to it after other DB features are ready.

pub(crate) struct FSemaphore {
    m_count: AtomicIsize,
    sema : Semaphore
}

impl FSemaphore {
    pub(crate) fn new(count : isize) -> FSemaphore {
        FSemaphore {
            m_count: AtomicIsize::new(count),
            sema: Semaphore::new(0)
        }
    }

    pub fn acquire(&self) {
        let count = self.m_count.fetch_sub(1, std::sync::atomic::Ordering::Relaxed);
        if count < 1 {
            self.sema.acquire();
        }
        core::sync::atomic::fence(std::sync::atomic::Ordering::Acquire);
    }

    pub fn release(&self) {
        core::sync::atomic::fence(std::sync::atomic::Ordering::Release);
        let count = self.m_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        if count < 1 {
            self.sema.release();
        }
    }

    pub fn access(&self) -> FSemaphoreGuard {
        self.acquire();
        FSemaphoreGuard { sem: self }
    }
}

pub struct FSemaphoreGuard<'a> {
    sem: &'a FSemaphore,
}

impl<'a> Drop for FSemaphoreGuard<'a> {
    fn drop(&mut self) {
        self.sem.release();
    }
}
chuigda commented 4 years ago

Great, will add it then.