Skip to content

Commit 643ee5b

Browse files
committedAug 26, 2019
Added extracted code from ccl. Hello new repo.
1 parent f3ff937 commit 643ee5b

File tree

6 files changed

+1334
-0
lines changed

6 files changed

+1334
-0
lines changed
 

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
**/*.rs.bk
3+
Cargo.lock

‎.gitlab-ci.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
image: 'rust:latest'
2+
3+
stages:
4+
- rustfmt
5+
- test
6+
7+
rustfmt:
8+
stage: rustfmt
9+
script:
10+
- rustup install stable
11+
- rustup component add rustfmt --toolchain stable-x86_64-unknown-linux-gnu
12+
- cargo fmt --version
13+
- cargo fmt -- --check
14+
15+
test:
16+
stage: test
17+
when: delayed
18+
start_in: 15 seconds
19+
script:
20+
- rustc --version
21+
- cargo --version
22+
- cargo test --verbose
23+
24+
cache:
25+
paths:
26+
- target/

‎Cargo.toml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[package]
2+
name = "dashmap"
3+
version = "1.0.0"
4+
authors = ["acrimon <joel.wejdenstal@gmail.com>"]
5+
edition = "2018"
6+
license = "MIT"
7+
repository = "https://gitlab.nebulanet.cc/xacrimon/dashmap"
8+
homepage = "https://gitlab.nebulanet.cc/xacrimon/dashmap"
9+
description = "Extremely fast concurrent map."
10+
readme = "README.md"
11+
documentation = "https://docs.rs/dashmap"
12+
keywords = ["atomic", "concurrent", "hashmap"]
13+
categories = ["concurrency", "algorithms", "data-structures"]
14+
15+
[package.metadata.docs.rs]
16+
rustdoc-args = ["--html-in-header", ".cargo/registry/src/6github.com-1ecc6299db9ec823/pwnies-0.0.14/pwnies.html"]
17+
18+
[features]
19+
nightly = ["parking_lot/nightly", "hashbrown/nightly"]
20+
21+
[dependencies]
22+
hashbrown = "0.6.0"
23+
parking_lot = { version = "0.9.0", features = ["owning_ref"] }
24+
num_cpus = "1.10.1"
25+
seahash = "3.0.6"
26+
owning_ref = "0.4.0"
27+
slab = "0.4.2"
28+
stable_deref_trait = "1.1.1"
29+
futures-preview = "=0.3.0-alpha.17"
30+
31+
[dev-dependencies]
32+
rayon = "1.1.0"

‎src/fut_rwlock.rs

+302
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
use parking_lot::Mutex as RegularMutex;
2+
use parking_lot::RwLock as RegularRwLock;
3+
use parking_lot::RwLockReadGuard as RegularRwLockReadGuard;
4+
use parking_lot::RwLockWriteGuard as RegularRwLockWriteGuard;
5+
use slab::Slab;
6+
use stable_deref_trait::StableDeref;
7+
use std::cell::UnsafeCell;
8+
use std::future::Future;
9+
use std::mem;
10+
use std::ops::{Deref, DerefMut};
11+
use std::pin::Pin;
12+
use std::task::{Context, Poll, Waker};
13+
use std::time::Duration;
14+
15+
const WAIT_KEY_NONE: usize = std::usize::MAX;
16+
17+
enum Waiter {
18+
Waiting(Waker),
19+
Woken,
20+
}
21+
22+
impl Waiter {
23+
#[inline]
24+
fn register(&mut self, w: &Waker) {
25+
match self {
26+
Waiter::Waiting(waker) if w.will_wake(waker) => {}
27+
_ => *self = Waiter::Waiting(w.clone()),
28+
}
29+
}
30+
31+
#[inline]
32+
fn wake(&mut self) {
33+
match mem::replace(self, Waiter::Woken) {
34+
Waiter::Waiting(waker) => waker.wake(),
35+
Waiter::Woken => {}
36+
}
37+
}
38+
}
39+
40+
pub struct RwLockReadGuard<'a, T> {
41+
_inner_guard: Option<RegularRwLockReadGuard<'a, ()>>,
42+
lock: &'a RwLock<T>,
43+
}
44+
45+
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
46+
type Target = T;
47+
48+
#[inline]
49+
fn deref(&self) -> &Self::Target {
50+
unsafe { &*self.lock.data.get() }
51+
}
52+
}
53+
54+
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
55+
#[inline]
56+
fn drop(&mut self) {
57+
drop(self._inner_guard.take());
58+
let mut waiters = self.lock.waiters.lock();
59+
if let Some((_i, waiter)) = waiters.iter_mut().next() {
60+
waiter.wake();
61+
}
62+
}
63+
}
64+
65+
pub struct RwLockWriteGuard<'a, T> {
66+
_inner_guard: Option<RegularRwLockWriteGuard<'a, ()>>,
67+
lock: &'a RwLock<T>,
68+
}
69+
70+
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
71+
type Target = T;
72+
73+
#[inline]
74+
fn deref(&self) -> &Self::Target {
75+
unsafe { &*self.lock.data.get() }
76+
}
77+
}
78+
79+
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
80+
#[inline]
81+
fn deref_mut(&mut self) -> &mut Self::Target {
82+
unsafe { &mut *self.lock.data.get() }
83+
}
84+
}
85+
86+
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
87+
#[inline]
88+
fn drop(&mut self) {
89+
drop(self._inner_guard.take());
90+
let mut waiters = self.lock.waiters.lock();
91+
if let Some((_i, waiter)) = waiters.iter_mut().next() {
92+
waiter.wake();
93+
}
94+
}
95+
}
96+
97+
pub struct RwLock<T> {
98+
lock: RegularRwLock<()>,
99+
waiters: RegularMutex<Slab<Waiter>>,
100+
data: UnsafeCell<T>,
101+
}
102+
103+
impl<T> RwLock<T> {
104+
fn remove_waker(&self, wait_key: usize, wake_another: bool) {
105+
if wait_key != WAIT_KEY_NONE {
106+
let mut waiters = self.waiters.lock();
107+
match waiters.remove(wait_key) {
108+
Waiter::Waiting(_) => {}
109+
Waiter::Woken => {
110+
// We were awoken, but then dropped before we could
111+
// wake up to acquire the lock. Wake up another
112+
// waiter.
113+
if wake_another {
114+
if let Some((_i, waiter)) = waiters.iter_mut().next() {
115+
waiter.wake();
116+
}
117+
}
118+
}
119+
}
120+
}
121+
}
122+
123+
pub fn new(data: T) -> Self {
124+
Self {
125+
lock: RegularRwLock::new(()),
126+
waiters: RegularMutex::new(Slab::new()),
127+
data: UnsafeCell::new(data),
128+
}
129+
}
130+
131+
#[inline]
132+
pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
133+
self.lock.try_read().map(|guard| RwLockReadGuard {
134+
_inner_guard: Some(guard),
135+
lock: self,
136+
})
137+
}
138+
139+
#[inline]
140+
pub fn try_read_for(&self, d: Duration) -> Option<RwLockReadGuard<'_, T>> {
141+
self.lock.try_read_for(d).map(|guard| RwLockReadGuard {
142+
_inner_guard: Some(guard),
143+
lock: self,
144+
})
145+
}
146+
147+
#[inline]
148+
pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
149+
self.lock.try_write().map(|guard| RwLockWriteGuard {
150+
_inner_guard: Some(guard),
151+
lock: self,
152+
})
153+
}
154+
155+
#[inline]
156+
pub fn try_write_for(&self, d: Duration) -> Option<RwLockWriteGuard<'_, T>> {
157+
self.lock.try_write_for(d).map(|guard| RwLockWriteGuard {
158+
_inner_guard: Some(guard),
159+
lock: self,
160+
})
161+
}
162+
163+
#[inline]
164+
pub fn read(&self) -> RwLockReadGuard<'_, T> {
165+
RwLockReadGuard {
166+
_inner_guard: Some(self.lock.read()),
167+
lock: self,
168+
}
169+
}
170+
171+
#[inline]
172+
pub fn write(&self) -> RwLockWriteGuard<'_, T> {
173+
RwLockWriteGuard {
174+
_inner_guard: Some(self.lock.write()),
175+
lock: self,
176+
}
177+
}
178+
179+
#[inline]
180+
pub fn async_read(&self) -> RwLockReadFuture<'_, T> {
181+
RwLockReadFuture {
182+
lock: Some(self),
183+
wait_key: WAIT_KEY_NONE,
184+
}
185+
}
186+
187+
#[inline]
188+
pub fn async_write(&self) -> RwLockWriteFuture<'_, T> {
189+
RwLockWriteFuture {
190+
lock: Some(self),
191+
wait_key: WAIT_KEY_NONE,
192+
}
193+
}
194+
}
195+
196+
pub struct RwLockReadFuture<'a, T> {
197+
lock: Option<&'a RwLock<T>>,
198+
wait_key: usize,
199+
}
200+
201+
impl<'a, T> Drop for RwLockReadFuture<'a, T> {
202+
#[inline]
203+
fn drop(&mut self) {
204+
if let Some(lock) = self.lock {
205+
lock.remove_waker(self.wait_key, true);
206+
}
207+
}
208+
}
209+
210+
impl<'a, T> Future for RwLockReadFuture<'a, T> {
211+
type Output = RwLockReadGuard<'a, T>;
212+
213+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
214+
let lock = self.lock.expect("polled after completion");
215+
216+
if let Some(guard) = lock.try_read() {
217+
lock.remove_waker(self.wait_key, false);
218+
self.lock = None;
219+
return Poll::Ready(guard);
220+
}
221+
222+
{
223+
let mut waiters = lock.waiters.lock();
224+
if self.wait_key == WAIT_KEY_NONE {
225+
self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
226+
} else {
227+
waiters[self.wait_key].register(cx.waker())
228+
}
229+
}
230+
231+
if let Some(guard) = lock.try_read() {
232+
lock.remove_waker(self.wait_key, false);
233+
self.lock = None;
234+
return Poll::Ready(guard);
235+
}
236+
237+
Poll::Pending
238+
}
239+
}
240+
241+
pub struct RwLockWriteFuture<'a, T> {
242+
lock: Option<&'a RwLock<T>>,
243+
wait_key: usize,
244+
}
245+
246+
impl<'a, T> Drop for RwLockWriteFuture<'a, T> {
247+
#[inline]
248+
fn drop(&mut self) {
249+
if let Some(lock) = self.lock {
250+
lock.remove_waker(self.wait_key, true);
251+
}
252+
}
253+
}
254+
255+
impl<'a, T> Future for RwLockWriteFuture<'a, T> {
256+
type Output = RwLockWriteGuard<'a, T>;
257+
258+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
259+
let lock = self.lock.expect("polled after completion");
260+
261+
if let Some(guard) = lock.try_write() {
262+
lock.remove_waker(self.wait_key, false);
263+
self.lock = None;
264+
return Poll::Ready(guard);
265+
}
266+
267+
{
268+
let mut waiters = lock.waiters.lock();
269+
if self.wait_key == WAIT_KEY_NONE {
270+
self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
271+
} else {
272+
waiters[self.wait_key].register(cx.waker())
273+
}
274+
}
275+
276+
if let Some(guard) = lock.try_write() {
277+
lock.remove_waker(self.wait_key, false);
278+
self.lock = None;
279+
return Poll::Ready(guard);
280+
}
281+
282+
Poll::Pending
283+
}
284+
}
285+
286+
unsafe impl<T: Send> Send for RwLock<T> {}
287+
unsafe impl<T: Sync> Sync for RwLock<T> {}
288+
289+
unsafe impl<T: Send> Send for RwLockReadFuture<'_, T> {}
290+
unsafe impl<T: Send> Sync for RwLockReadFuture<'_, T> {}
291+
292+
unsafe impl<T: Send> Send for RwLockWriteFuture<'_, T> {}
293+
unsafe impl<T: Send> Sync for RwLockWriteFuture<'_, T> {}
294+
295+
unsafe impl<T: Send> Send for RwLockReadGuard<'_, T> {}
296+
unsafe impl<T: Sync> Sync for RwLockReadGuard<'_, T> {}
297+
298+
unsafe impl<T: Send> Send for RwLockWriteGuard<'_, T> {}
299+
unsafe impl<T: Sync> Sync for RwLockWriteGuard<'_, T> {}
300+
301+
unsafe impl<T> StableDeref for RwLockReadGuard<'_, T> {}
302+
unsafe impl<T> StableDeref for RwLockWriteGuard<'_, T> {}

‎src/lib.rs

+959
Large diffs are not rendered by default.

‎src/util.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::{mem, ptr};
2+
3+
#[inline]
4+
pub const fn ptr_size_bits() -> usize {
5+
mem::size_of::<usize>() * 8
6+
}
7+
8+
/// Must not panic
9+
#[inline]
10+
pub unsafe fn map_in_place<T>(r: &mut T, f: impl FnOnce(T) -> T) {
11+
ptr::write(r, f(ptr::read(r)));
12+
}

0 commit comments

Comments
 (0)
Please sign in to comment.