Skip to content

Commit 035a706

Browse files
committed
Update homework to 2024 edition.
1 parent 39cc955 commit 035a706

25 files changed

+94
-89
lines changed

homework/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "cs431-homework"
33
version = "0.1.0"
44
authors = ["Jeehoon Kang <[email protected]>"]
5-
edition = "2021"
5+
edition = "2024"
66

77
[[bin]]
88
name = "hello_server"

homework/src/arc.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ use std::marker::PhantomData;
66
use std::ops::Deref;
77
use std::ptr::NonNull;
88
#[cfg(not(feature = "check-loom"))]
9-
use std::sync::atomic::{fence, AtomicUsize, Ordering};
9+
use std::sync::atomic::{AtomicUsize, Ordering, fence};
1010
use std::{fmt, mem};
1111

1212
#[cfg(feature = "check-loom")]
13-
use loom::sync::atomic::{fence, AtomicUsize, Ordering};
13+
use loom::sync::atomic::{AtomicUsize, Ordering, fence};
1414

1515
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
1616

@@ -237,10 +237,9 @@ impl<T> Arc<T> {
237237
/// }
238238
/// assert_eq!(*x, "foo");
239239
/// ```
240-
#[allow(clippy::needless_pass_by_ref_mut)]
241240
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
242241
// We are careful to *not* create a reference covering the "count" fields, as
243-
// this would alias with concurrent access to the reference counts.
242+
// this would alias with concurrent access to the reference counts (e.g. by `Weak`).
244243
unsafe { &mut (*this.ptr.as_ptr()).data }
245244
}
246245

homework/src/bin/hello_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::io;
2-
use std::sync::mpsc::{channel, sync_channel};
32
use std::sync::Arc;
3+
use std::sync::mpsc::{channel, sync_channel};
44

55
use cs431_homework::hello_server::{CancellableTcpListener, Handler, Statistics, ThreadPool};
66

homework/src/boc.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::sync::Arc;
1313
///
1414
/// # Safety
1515
///
16-
/// `last()` should actually return the last request for the corresponding cown.
16+
/// `last` should actually return the last request for the corresponding cown.
1717
unsafe trait CownBase: Send {
1818
/// Return a pointer to the tail of this cown's request queue.
1919
fn last(&self) -> &AtomicPtr<Request>;
@@ -309,16 +309,16 @@ macro_rules! tuple_list {
309309
($i:ident, $($e:ident),*,) => ( ($i, $crate::tuple_list!($($e),*)) );
310310

311311
// handling complex expressions
312-
($i:expr) => ( ($i, ()) );
313-
($i:expr,) => ( ($i, ()) );
314-
($i:expr, $($e:expr),*) => ( ($i, $crate::tuple_list!($($e),*)) );
315-
($i:expr, $($e:expr),*,) => ( ($i, $crate::tuple_list!($($e),*)) );
312+
($i:expr_2021) => ( ($i, ()) );
313+
($i:expr_2021,) => ( ($i, ()) );
314+
($i:expr_2021, $($e:expr_2021),*) => ( ($i, $crate::tuple_list!($($e),*)) );
315+
($i:expr_2021, $($e:expr_2021),*,) => ( ($i, $crate::tuple_list!($($e),*)) );
316316
}
317317

318318
/// "When" block.
319319
#[macro_export]
320320
macro_rules! when {
321-
( $( $cs:ident ),* ; $( $gs:ident ),* ; $thunk:expr ) => {{
321+
( $( $cs:ident ),* ; $( $gs:ident ),* ; $thunk:expr_2021 ) => {{
322322
run_when(tuple_list!($($cs.clone()),*), move |tuple_list!($($gs),*)| $thunk);
323323
}};
324324
}

homework/src/elim_stack/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ use core::mem::ManuallyDrop;
33
use core::ops::Deref;
44
use std::time;
55

6-
use crossbeam_epoch::{pin, Atomic, Guard, Owned};
7-
use rand::{thread_rng, Rng};
6+
use crossbeam_epoch::{Atomic, Guard, Owned, pin};
7+
use rand::{Rng, thread_rng};
88

99
pub(crate) const ELIM_SIZE: usize = 16;
1010
pub(crate) const ELIM_DELAY: time::Duration = time::Duration::from_millis(10);
1111

1212
#[inline]
1313
pub(crate) fn get_random_elim_index() -> usize {
14-
thread_rng().gen::<usize>() % ELIM_SIZE
14+
thread_rng().r#gen::<usize>() % ELIM_SIZE
1515
}
1616

1717
/// Concurrent stack types.

homework/src/elim_stack/elim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::thread;
66

77
use crossbeam_epoch::{Guard, Owned, Shared};
88

9-
use super::base::{get_random_elim_index, ElimStack, Stack, ELIM_DELAY};
9+
use super::base::{ELIM_DELAY, ElimStack, Stack, get_random_elim_index};
1010

1111
impl<T, S: Stack<T>> Stack<T> for ElimStack<T, S> {
1212
type PushReq = S::PushReq;

homework/src/hash_table/growable_array.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use core::fmt::Debug;
44
use core::mem::{self, ManuallyDrop};
55
use core::sync::atomic::Ordering::*;
6+
67
use crossbeam_epoch::{Atomic, Guard, Owned, Shared};
78

89
/// Growable array of `Atomic<T>`.
@@ -138,9 +139,9 @@ const SEGMENT_LOGSIZE: usize = 10;
138139
/// pointers to `T`. This is determined by the height of this segment in the main array, which one
139140
/// needs to track separately. For example, use the main array root's tag.
140141
///
141-
/// Since destructing `Segment<T>` requires its height information, it is not recommended to
142-
/// implement `Drop` for this union. Rather, have a custom deallocate method that accounts for the
143-
/// height of the segment.
142+
/// Since destructing segments requires its height information, it is not recommended to
143+
/// implement [`Drop`]. Rather, implement and use the custom [`Segment::deallocate`] method that
144+
/// accounts for the height of the segment.
144145
union Segment<T> {
145146
children: ManuallyDrop<[Atomic<Segment<T>>; 1 << SEGMENT_LOGSIZE]>,
146147
elements: ManuallyDrop<[Atomic<T>; 1 << SEGMENT_LOGSIZE]>,
@@ -156,6 +157,15 @@ impl<T> Segment<T> {
156157
unsafe { mem::zeroed() },
157158
)
158159
}
160+
161+
/// Deallocates a segment of `height`.
162+
///
163+
/// # Safety
164+
///
165+
/// `self` must actually have height `height`.
166+
unsafe fn deallocate(self, height: usize) {
167+
todo!()
168+
}
159169
}
160170

161171
impl<T> Debug for Segment<T> {

homework/src/hash_table/split_ordered_list.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! Split-ordered linked list.
22
33
use core::mem::{self, MaybeUninit};
4-
use core::sync::atomic::{AtomicUsize, Ordering::*};
4+
use core::sync::atomic::AtomicUsize;
5+
use core::sync::atomic::Ordering::*;
6+
57
use crossbeam_epoch::{Guard, Owned};
68
use cs431::lockfree::list::{Cursor, List, Node};
79

@@ -73,16 +75,19 @@ impl<V> SplitOrderedList<V> {
7375
impl<V> ConcurrentMap<usize, V> for SplitOrderedList<V> {
7476
fn lookup<'a>(&'a self, key: &usize, guard: &'a Guard) -> Option<&'a V> {
7577
Self::assert_valid_key(*key);
78+
7679
todo!()
7780
}
7881

7982
fn insert(&self, key: usize, value: V, guard: &Guard) -> Result<(), V> {
8083
Self::assert_valid_key(key);
84+
8185
todo!()
8286
}
8387

8488
fn delete<'a>(&'a self, key: &usize, guard: &'a Guard) -> Result<&'a V, ()> {
8589
Self::assert_valid_key(*key);
90+
8691
todo!()
8792
}
8893
}

homework/src/hazard_pointer/hazard.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use core::ptr::{self, NonNull};
22
#[cfg(not(feature = "check-loom"))]
3-
use core::sync::atomic::{fence, AtomicBool, AtomicPtr, AtomicUsize, Ordering};
3+
use core::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering, fence};
44
use std::collections::HashSet;
55
use std::fmt;
66

77
#[cfg(feature = "check-loom")]
8-
use loom::sync::atomic::{fence, AtomicBool, AtomicPtr, AtomicUsize, Ordering};
8+
use loom::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering, fence};
99

1010
use super::HAZARDS;
1111

@@ -98,7 +98,7 @@ struct HazardSlot {
9898
// Whether this slot is occupied by a `Shield`.
9999
active: AtomicBool,
100100
// Machine representation of the hazard pointer.
101-
hazard: AtomicUsize,
101+
hazard: AtomicPtr<()>,
102102
// Immutable pointer to the next slot in the bag.
103103
next: *const HazardSlot,
104104
}
@@ -138,7 +138,7 @@ impl HazardBag {
138138
}
139139

140140
/// Returns all the hazards in the set.
141-
pub fn all_hazards(&self) -> HashSet<usize> {
141+
pub fn all_hazards(&self) -> HashSet<*mut ()> {
142142
todo!()
143143
}
144144
}
@@ -163,8 +163,8 @@ unsafe impl Sync for HazardSlot {}
163163
mod tests {
164164
use std::collections::HashSet;
165165
use std::ops::Range;
166-
use std::sync::atomic::AtomicPtr;
167166
use std::sync::Arc;
167+
use std::sync::atomic::AtomicPtr;
168168
use std::{mem, thread};
169169

170170
use super::{HazardBag, Shield};
@@ -193,7 +193,7 @@ mod tests {
193193
.into_iter()
194194
.for_each(|th| th.join().unwrap());
195195
let all = hazard_bag.all_hazards();
196-
let values = VALUES.collect();
196+
let values = VALUES.map(|data| data as *mut ()).collect();
197197
assert!(all.is_superset(&values))
198198
}
199199

@@ -216,7 +216,7 @@ mod tests {
216216
.into_iter()
217217
.for_each(|th| th.join().unwrap());
218218
let all = hazard_bag.all_hazards();
219-
let values = VALUES.collect();
219+
let values = VALUES.map(|data| data as *mut ()).collect();
220220
let intersection: HashSet<_> = all.intersection(&values).collect();
221221
assert!(intersection.is_empty())
222222
}

homework/src/hazard_pointer/retire.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
use core::marker::PhantomData;
22
#[cfg(not(feature = "check-loom"))]
3-
use core::sync::atomic::{fence, Ordering};
3+
use core::sync::atomic::{Ordering, fence};
44

55
#[cfg(feature = "check-loom")]
6-
use loom::sync::atomic::{fence, Ordering};
6+
use loom::sync::atomic::{Ordering, fence};
77

8-
use super::{HazardBag, HAZARDS};
8+
use super::{HAZARDS, HazardBag};
9+
10+
type Retired = (*mut (), unsafe fn(*mut ()));
911

1012
/// Thread-local list of retired pointers.
1113
#[derive(Debug)]
1214
pub struct RetiredSet<'s> {
1315
hazards: &'s HazardBag,
1416
/// The first element of the pair is the machine representation of the pointer and the second
1517
/// is the function pointer to `free::<T>` where `T` is the type of the object.
16-
inner: Vec<(usize, unsafe fn(usize))>,
18+
inner: Vec<Retired>,
1719
_marker: PhantomData<*const ()>, // !Send + !Sync
1820
}
1921

@@ -52,8 +54,8 @@ impl<'s> RetiredSet<'s> {
5254
/// unique ownership to `data`.
5355
///
5456
/// [`Box::from_raw`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw
55-
unsafe fn free<T>(data: usize) {
56-
drop(unsafe { Box::from_raw(data as *mut T) })
57+
unsafe fn free<T>(data: *mut ()) {
58+
drop(unsafe { Box::from_raw(data.cast::<T>()) })
5759
}
5860

5961
todo!()

0 commit comments

Comments
 (0)