Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
FP
ghostcell
Commits
2bd6f359
Commit
2bd6f359
authored
Mar 02, 2021
by
Hai Dang
Browse files
remove linked list examples and benchmark
parent
e1cc0c20
Pipeline
#42808
passed with stage
in 22 minutes and 54 seconds
Changes
11
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
ghostcell/Cargo.toml
View file @
2bd6f359
...
...
@@ -10,10 +10,6 @@ edition = "2018"
name
=
"dlist"
harness
=
false
[[bench]]
name
=
"linked_list"
harness
=
false
[dependencies]
typed-arena
=
"2.0.1"
...
...
ghostcell/benches/linked_list.rs
deleted
100644 → 0
View file @
e1cc0c20
This diff is collapsed.
Click to expand it.
ghostcell/examples/linked_list_arc_ghostcell.rs
deleted
100644 → 0
View file @
e1cc0c20
use
ghostcell
::{
GhostCell
,
GhostToken
};
use
std
::{
fmt
,
sync
::
Arc
,
sync
::
RwLock
,
mem
,
ops
::
Deref
,
ops
::
DerefMut
,
};
use
rayon
;
/// The Arc<GhostCell> Example from §4 of the paper.
/// Run from the `./ghostcell-examples` directory, with the command
/// `cargo run --example linked_list_arc_ghostcell`.
struct
Node
<
'id
,
T
>
{
data
:
T
,
next
:
Option
<
Arc
<
GhostCell
<
'id
,
Node
<
'id
,
T
>>>>
,
}
type
NodePtr
<
'id
,
T
>
=
Arc
<
GhostCell
<
'id
,
Node
<
'id
,
T
>>>
;
fn
reverse
<
'id
,
T
>
(
mut
list
:
NodePtr
<
'id
,
T
>
,
token
:
&
mut
GhostToken
<
'id
>
)
->
NodePtr
<
'id
,
T
>
{
let
mut
reversed
:
Option
<
NodePtr
<
'id
,
T
>>
=
None
;
loop
{
let
inner
:
&
mut
Node
<
'id
,
T
>
=
list
.borrow_mut
(
token
);
let
old_next
:
Option
<
NodePtr
<
'id
,
T
>>
=
mem
::
replace
(
&
mut
inner
.next
,
reversed
);
reversed
=
Some
(
list
);
if
let
Some
(
old_next
)
=
old_next
{
list
=
old_next
;
}
else
{
return
reversed
.unwrap
();
// We know the reversed list will end up nonempty.
}
}
}
fn
iterate
<
'id
,
B
,
T
>
(
list
:
&
NodePtr
<
'id
,
T
>
,
token
:
&
GhostToken
<
'id
>
,
mut
acc
:
B
,
f
:
fn
(
B
,
&
T
)
->
B
)
->
B
{
let
mut
cur
:
Option
<&
GhostCell
<
'id
,
Node
<
'id
,
T
>>>
=
Some
(
&*
list
);
while
let
Some
(
node
)
=
cur
{
let
inner
:
&
Node
<
'id
,
T
>
=
node
.borrow
(
token
);
// immutably borrow `node` with `token`
acc
=
f
(
acc
,
&
inner
.data
);
cur
=
inner
.next
.as_deref
();
}
acc
}
fn
init
<
'id
>
(
list_size
:
u32
)
->
Arc
<
GhostCell
<
'id
,
Node
<
'id
,
u32
>>>
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
};
for
i
in
1
..
list_size
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
Arc
::
new
(
GhostCell
::
new
(
numbers
))),
};
}
Arc
::
new
(
GhostCell
::
new
(
numbers
))
}
#[allow(unused)]
fn
cons
<
'id
,
T
>
(
head
:
T
,
tail
:
&
NodePtr
<
'id
,
T
>
)
->
NodePtr
<
'id
,
T
>
{
Arc
::
new
(
GhostCell
::
new
(
Node
{
data
:
head
,
next
:
Some
(
Arc
::
clone
(
tail
))
}))
}
fn
print_list
<
'id
,
T
:
fmt
::
Debug
>
(
list
:
&
NodePtr
<
'id
,
T
>
,
token
:
&
GhostToken
<
'id
>
)
{
print!
(
"["
);
iterate
(
list
,
token
,
0
,
|
acc
,
d
|{
print!
(
"{:?}, "
,
d
)
;
acc
});
print!
(
"]"
);
}
fn
full_par_ghostcell
(
list_size
:
u32
)
{
GhostToken
::
new
(|
mut
token
|
{
let
list
:
Arc
<
GhostCell
<
Node
<
u32
>>>
=
init
(
list_size
);
let
(
sum
,
len
)
=
rayon
::
join
(
||
iterate
(
&
list
,
&
token
,
0
,
|
acc
,
x
|
acc
+
x
),
||
iterate
(
&
list
,
&
token
,
0
,
|
acc
,
_
|
acc
+
1
)
);
let
reversed
=
reverse
(
list
,
&
mut
token
);
println!
(
"Sum: {:}, Len: {:}"
,
sum
,
len
);
print_list
(
&
reversed
,
&
token
);
});
}
fn
full_rwlock_ghost_token
(
list_size
:
u32
)
{
GhostToken
::
new
(|
token
|
{
let
wlist
:
Arc
<
GhostCell
<
Node
<
u32
>>>
=
init
(
list_size
);
let
rlist
=
wlist
.clone
();
let
lock
=
RwLock
::
new
(
token
);
let
_
=
rayon
::
join
(
||
{
let
mut
guard
=
lock
.write
()
.unwrap
();
let
reversed
=
reverse
(
wlist
,
guard
.deref_mut
());
print_list
(
&
reversed
,
guard
.deref
());
},
||
{
let
guard
=
lock
.read
()
.unwrap
();
let
sum
=
iterate
(
&
rlist
,
guard
.deref
(),
0
,
|
acc
,
x
|
acc
+
x
);
println!
(
"Sum: {:}"
,
sum
);
}
);
});
}
pub
fn
main
()
{
full_par_ghostcell
(
10
);
full_rwlock_ghost_token
(
10
);
}
ghostcell/examples/linked_list_arc_rwlock.rs
deleted
100644 → 0
View file @
e1cc0c20
use
std
::{
fmt
,
sync
::
Arc
,
sync
::
RwLock
,
sync
::
RwLockWriteGuard
,
sync
::
RwLockReadGuard
,
mem
,
ops
::
Deref
,
ops
::
DerefMut
,
};
use
rayon
;
/// The Arc<RwLock> Example from §3 and §4.3 of the paper.
/// Run from the `./ghostcell-examples` directory, with the command
/// `cargo run --example linked_list_arc_rwlock`.
struct
Node
<
T
>
{
data
:
T
,
next
:
Option
<
Arc
<
RwLock
<
Node
<
T
>>>>
}
type
NodePtr
<
T
>
=
Arc
<
RwLock
<
Node
<
T
>>>
;
fn
init
(
list_size
:
u32
)
->
NodePtr
<
u32
>
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
};
for
i
in
1
..
list_size
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
Arc
::
new
(
RwLock
::
new
(
numbers
))),
};
}
Arc
::
new
(
RwLock
::
new
(
numbers
))
}
// List cons (not consuming the tail).
#[allow(unused)]
fn
cons
<
T
>
(
head
:
T
,
tail
:
&
NodePtr
<
T
>
)
->
NodePtr
<
T
>
{
Arc
::
new
(
RwLock
::
new
(
Node
{
data
:
head
,
next
:
Some
(
Arc
::
clone
(
tail
))
}))
}
fn
reverse
<
T
>
(
mut
list
:
NodePtr
<
T
>
)
->
NodePtr
<
T
>
{
let
mut
reversed
:
Option
<
NodePtr
<
T
>>
=
None
;
loop
{
let
old_next
:
Option
<
NodePtr
<
T
>>
=
{
// tie the mutable borrow of the current node to `guard`
let
mut
guard
:
RwLockWriteGuard
<
Node
<
T
>>
=
list
.deref
()
.write
()
.unwrap
();
mem
::
replace
(
&
mut
guard
.deref_mut
()
.next
,
reversed
)
};
// the mutable borrow ends here as `guard` goes out of scope
reversed
=
Some
(
list
);
if
let
Some
(
old_next
)
=
old_next
{
list
=
old_next
;
}
else
{
return
reversed
.unwrap
();
// We know the reversed list will end up nonempty.
}
}
}
fn
iterate
<
B
,
T
>
(
list
:
&
NodePtr
<
T
>
,
mut
acc
:
B
,
f
:
fn
(
B
,
&
T
)
->
B
)
->
B
{
let
mut
cur
:
Option
<
NodePtr
<
T
>>
=
Some
(
list
.clone
());
while
let
Some
(
node
)
=
cur
{
let
guard
:
RwLockReadGuard
<
Node
<
T
>>
=
node
.deref
()
.read
()
.unwrap
();
acc
=
f
(
acc
,
&
guard
.deref
()
.data
);
cur
=
guard
.deref
()
.next
.clone
();
}
acc
}
fn
print_list
<
T
:
fmt
::
Debug
>
(
list
:
&
NodePtr
<
T
>
)
{
print!
(
"["
);
iterate
(
list
,
0
,
|
acc
,
d
|{
print!
(
"{:?}, "
,
d
)
;
acc
});
print!
(
"]"
);
}
fn
full_par_rwlock
(
list_size
:
u32
)
{
let
list
:
Arc
<
RwLock
<
Node
<
u32
>>>
=
init
(
list_size
);
let
(
sum
,
len
)
=
rayon
::
join
(
||
iterate
(
&
list
,
0
,
|
acc
,
x
|
acc
+
x
),
||
iterate
(
&
list
,
0
,
|
acc
,
_
|
acc
+
1
)
);
let
reversed
=
reverse
(
list
);
println!
(
"Sum: {:}, Len: {:}"
,
sum
,
len
);
print_list
(
&
reversed
);
}
pub
fn
main
()
{
full_par_rwlock
(
10
);
}
ghostcell/examples/linked_list_arena.rs
deleted
100644 → 0
View file @
e1cc0c20
use
ghostcell
::{
GhostCell
,
GhostToken
};
use
std
::{
fmt
,
mem
};
use
typed_arena
::
Arena
as
TypedArena
;
#[derive(Clone,
Copy)]
struct
Node
<
'arena
,
'id
,
T
>
{
data
:
T
,
next
:
Option
<&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
}
pub
fn
main
()
{
GhostToken
::
new
(|
mut
token
|
{
// let mut arena = Arena::with_capacity(10 * mem::size_of::<Node<u32>>());
// let mut arena = arena.allocator();
let
arena
=
TypedArena
::
with_capacity
(
10
);
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
,
};
// Create a linked list segment.
for
i
in
1
..
10
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
GhostCell
::
from_mut
(
arena
.alloc
(
numbers
))),
};
}
let
mut
list
=
&
GhostCell
::
new
(
numbers
);
print!
(
"Numbers: "
);
print_list
(
Some
(
&*
list
),
&
token
);
// Reverse the list.
let
mut
reversed
=
None
;
loop
{
let
next
=
{
let
node
=
list
.borrow_mut
(
&
mut
token
);
mem
::
replace
(
&
mut
node
.next
,
reversed
)
};
reversed
=
Some
(
list
);
if
let
Some
(
next
)
=
next
{
list
=
next
;
}
else
{
break
;
}
}
print!
(
"Reverse: "
);
print_list
(
reversed
,
&
token
);
});
}
fn
print_list
<
'arena
,
'id
,
T
:
fmt
::
Debug
>
(
mut
list
:
Option
<&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
token
:
&
GhostToken
<
'id
>
,
)
{
print!
(
"["
);
while
let
Some
(
node
)
=
list
{
let
node
=
node
.borrow
(
token
);
print!
(
"{:?}, "
,
node
.data
);
list
=
node
.next
;
}
println!
(
"]"
);
}
ghostcell/examples/linked_list_arena_2.rs
deleted
100644 → 0
View file @
e1cc0c20
use
std
::{
fmt
,
mem
,
};
use
typed_arena
::
Arena
as
TypedArena
;
use
ghostcell
::{
GhostCell
,
GhostToken
};
struct
Node
<
'arena
,
'id
,
T
>
{
data
:
T
,
next
:
Option
<&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
}
fn
reverse
<
'arena
,
'id
,
T
>
(
mut
list
:
&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
,
token
:
&
mut
GhostToken
<
'id
>
)
->
&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
{
let
mut
reversed
:
Option
<&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
=
None
;
loop
{
let
old_next
:
Option
<&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
=
{
let
guard
:
&
mut
Node
<
'arena
,
'id
,
T
>
=
list
.borrow_mut
(
token
);
mem
::
replace
(
&
mut
guard
.next
,
reversed
)
};
reversed
=
Some
(
list
);
if
let
Some
(
old_next
)
=
old_next
{
list
=
old_next
;
}
else
{
return
reversed
.unwrap
();
// We know the reversed list will end up nonempty.
}
}
}
fn
fold_list
<
'arena
,
'id
,
B
,
T
>
(
list
:
&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
,
token
:
&
GhostToken
<
'id
>
,
mut
acc
:
B
,
mut
f
:
impl
FnMut
(
B
,
&
T
)
->
B
)
->
B
{
let
mut
cur
:
Option
<&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
=
Some
(
list
);
while
let
Some
(
node
)
=
cur
{
let
guard
:
&
Node
<
'arena
,
'id
,
T
>
=
node
.borrow
(
token
);
acc
=
f
(
acc
,
&
guard
.data
);
cur
=
guard
.next
;
}
acc
}
fn
do_list
<
'arena
,
'id
,
T
>
(
list
:
&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
,
token
:
&
GhostToken
<
'id
>
,
f
:
fn
(
&
T
))
{
let
mut
cur
:
Option
<&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
=
Some
(
list
);
while
let
Some
(
node
)
=
cur
{
let
guard
:
&
Node
<
'arena
,
'id
,
T
>
=
node
.borrow
(
token
);
// immutably borrow `node` with `token`
f
(
&
guard
.data
);
cur
=
guard
.next
;
}
}
fn
print_list
<
'arena
,
'id
,
T
:
fmt
::
Debug
>
(
list
:
&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>
,
token
:
&
GhostToken
<
'id
>
)
{
print!
(
"["
);
do_list
(
list
,
token
,
|
d
|{
print!
(
"{:?}, "
,
d
)
});
print!
(
"]"
);
}
fn
init
<
'arena
,
'id
>
(
arena
:
&
'arena
TypedArena
<
Node
<
'arena
,
'id
,
u32
>>
,
list_size
:
u32
)
->
&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
u32
>>
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
};
for
i
in
1
..
list_size
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
GhostCell
::
from_mut
(
arena
.alloc
(
numbers
))),
};
}
GhostCell
::
from_mut
(
arena
.alloc
(
numbers
))
}
fn
main
()
{
GhostToken
::
new
(|
mut
token
|
{
let
list_size
=
10
;
let
arena
=
TypedArena
::
with_capacity
(
list_size
as
usize
);
// Create a linked list segment.
let
list
=
init
(
&
arena
,
list_size
);
print!
(
"Numbers: "
);
print_list
(
&
list
,
&
token
);
let
sum
=
fold_list
(
list
,
&
token
,
0
,
|
acc
,
n
|
acc
+
n
);
println!
(
"Sum {:?}"
,
sum
);
let
reversed
=
reverse
(
list
,
&
mut
token
);
let
len
=
fold_list
(
reversed
,
&
token
,
0
,
|
acc
,
_
|
acc
+
1
);
println!
(
"Len {:?}"
,
len
);
});
}
ghostcell/examples/linked_list_best_phases.rs
deleted
100644 → 0
View file @
e1cc0c20
use
ghostcell
::{
GhostCell
,
GhostToken
};
use
std
::{
fmt
,
mem
};
use
typed_arena
::
Arena
as
TypedArena
;
#[derive(Clone,
Copy)]
struct
Node
<
'arena
,
'id
,
T
>
{
data
:
T
,
next
:
Option
<&
'arena
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
}
pub
fn
main
()
{
GhostToken
::
new
(|
mut
token
|
{
//let mut arena = Arena::with_capacity(10 * mem::size_of::<Node<u32>>());
// let mut arena = arena.allocator();
let
arena
=
TypedArena
::
with_capacity
(
10
);
let
mut
numbers
=
Node
{
data
:
1
,
next
:
None
,
};
// Create a linked list segment.
for
i
in
2
..
11
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
GhostCell
::
from_mut
(
arena
.alloc
(
numbers
))),
};
}
let
mut
list
=
&
GhostCell
::
new
(
numbers
);
print!
(
"Numbers: "
);
print_list
(
Some
(
&*
list
),
&
token
);
let
(
sum
,
len
)
=
rayon
::
join
(
||
fold_list
(
Some
(
&*
list
),
&
token
,
0
,
|
acc
,
x
|
acc
+
x
),
||
fold_list
(
Some
(
&*
list
),
&
token
,
0
,
|
acc
,
_
|
acc
+
1
),
);
println!
(
"Sum: {:?}, Product: {:?}"
,
sum
,
len
);
// Reverse the list.
let
mut
reversed
=
None
;
loop
{
let
next
=
{
let
node
=
list
.borrow_mut
(
&
mut
token
);
mem
::
replace
(
&
mut
node
.next
,
reversed
)
};
reversed
=
Some
(
list
);
if
let
Some
(
next
)
=
next
{
list
=
next
;
}
else
{
break
;
}
}
print!
(
"Reverse: "
);
print_list
(
reversed
,
&
token
);
});
}
fn
fold_list
<
'arena
,
'id
,
T
,
B
>
(
mut
list
:
Option
<&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
token
:
&
GhostToken
<
'id
>
,
init
:
B
,
mut
reduce
:
impl
FnMut
(
B
,
&
T
)
->
B
,
)
->
B
{
let
mut
acc
=
init
;
while
let
Some
(
node
)
=
list
{
let
node
=
node
.borrow
(
token
);
acc
=
reduce
(
acc
,
&
node
.data
);
list
=
node
.next
;
}
acc
}
fn
print_list
<
'arena
,
'id
,
T
:
fmt
::
Debug
>
(
mut
list
:
Option
<&
GhostCell
<
'id
,
Node
<
'arena
,
'id
,
T
>>>
,
token
:
&
GhostToken
<
'id
>
,
)
{
print!
(
"["
);
while
let
Some
(
node
)
=
list
{
let
node
=
node
.borrow
(
token
);
print!
(
"{:?}, "
,
node
.data
);
list
=
node
.next
;
}
println!
(
"]"
);
}
ghostcell/examples/linked_list_box.rs
deleted
100644 → 0
View file @
e1cc0c20
use
std
::{
borrow
::
BorrowMut
,
fmt
,
mem
};
struct
Node
<
T
>
{
data
:
T
,
next
:
Option
<
Box
<
Node
<
T
>>>
,
}
pub
fn
main
()
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
,
};
// Create a linked list segment.
for
i
in
1
..
10
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
Box
::
new
(
numbers
)),
};
}
let
mut
list
=
Box
::
new
(
numbers
);
print!
(
"Numbers: "
);
print_list
(
Some
(
&*
list
));
// Reverse the list.
let
mut
reversed
=
None
;
loop
{
let
next
=
{
let
node
:
&
mut
Node
<
_
>
=
list
.borrow_mut
();
mem
::
replace
(
&
mut
node
.next
,
reversed
)
};
reversed
=
Some
(
list
);
if
let
Some
(
next
)
=
next
{
list
=
next
;
}
else
{
break
;
}
}
print!
(
"Reverse: "
);
print_list
(
reversed
.as_deref
());
}
fn
print_list
<
T
:
fmt
::
Debug
>
(
mut
list
:
Option
<&
Node
<
T
>>
)
{
print!
(
"["
);
while
let
Some
(
node
)
=
list
{
print!
(
"{:?}, "
,
node
.data
);
list
=
node
.next
.as_deref
();
}
println!
(
"]"
);
}
ghostcell/examples/linked_list_immut.rs
deleted
100644 → 0
View file @
e1cc0c20
use
std
::{
fmt
,
rc
::
Rc
};
struct
Node
<
T
>
{
data
:
T
,
next
:
Option
<
Rc
<
Node
<
T
>>>
,
}
pub
fn
main
()
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
,
};
// Create a linked list segment.
for
i
in
1
..
10
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
Rc
::
new
(
numbers
)),
};
}
let
list
=
Rc
::
new
(
numbers
);
print!
(
"Numbers: "
);
print_list
(
Some
(
&*
list
));
}
fn
print_list
<
T
:
fmt
::
Debug
>
(
mut
list
:
Option
<&
Node
<
T
>>
)
{
print!
(
"["
);
while
let
Some
(
node
)
=
list
{
print!
(
"{:?}, "
,
node
.data
);
list
=
node
.next
.as_deref
();
}
println!
(
"]"
);
}
ghostcell/examples/linked_list_rc_ghostcell.rs
deleted
100644 → 0
View file @
e1cc0c20
use
ghostcell
::{
GhostCell
,
GhostToken
};
use
std
::{
fmt
,
mem
,
rc
::
Rc
};
struct
Node
<
'id
,
T
>
{
data
:
T
,
next
:
Option
<
Rc
<
GhostCell
<
'id
,
Node
<
'id
,
T
>>>>
,
}
pub
fn
main
()
{
GhostToken
::
new
(|
mut
token
|
{
let
mut
numbers
=
Node
{
data
:
0
,
next
:
None
,
};
// Create a linked list segment.
for
i
in
1
..
10
{
numbers
=
Node
{
data
:
i
,
next
:
Some
(
Rc
::
new
(
GhostCell
::
new
(
numbers
))),
};
}
let
mut
list
=
Rc
::
new
(
GhostCell
::
new
(
numbers
));
print!
(
"Numbers: "
);
print_list
(
Some
(
&*
list
),
&
token
);
// Reverse the list.
let
mut
reversed
=
None
;
loop
{
let
next
=
{
let
node
=
list
.borrow_mut
(
&
mut
token
);
mem
::
replace
(
&
mut
node
.next
,
reversed
)
};
reversed
=
Some
(
list
);
if
let
Some
(
next
)
=
next
{
list
=
next
;
}
else
{
break
;
}
}