Skip to content

Commit fac5348

Browse files
committed
loom index out of bounds
1 parent a7cb406 commit fac5348

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

homework/loom.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
# $ cargo version --verbose
3+
# cargo 1.87.0-nightly (6cf826701 2025-03-14)
4+
# release: 1.87.0-nightly
5+
# commit-hash: 6cf8267012570f63d6b86e85a2ae5627de52df9e
6+
# commit-date: 2025-03-14
7+
# host: x86_64-unknown-linux-gnu
8+
# libgit2: 1.9.0 (sys:0.20.0 vendored)
9+
# libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.4.1)
10+
# ssl: OpenSSL 3.4.1 11 Feb 2025
11+
# os: Ubuntu 24.4.0 (noble) [64-bit]
12+
LOOM_CHECKPOINT_INTERVAL=1 LOOM_CHECKPOINT_FILE=my_test.json cargo test --features check-loom,loom/checkpoint --test arc --release -- correctness::count_sync --nocapture --test-threads 1

homework/my_test.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"preemption_bound":null,"pos":0,"branches":{"entries":[{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Disabled","Disabled","Disabled","Disabled"],"prev":null,"exploring":true}},{"Load":{"values":[0,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Disabled","Disabled","Disabled","Disabled"],"prev":{"index":0,"_p":null},"exploring":true}},{"Load":{"values":[0,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Skip","Disabled","Disabled","Disabled"],"prev":{"index":2,"_p":null},"exploring":true}},{"Load":{"values":[1,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Skip","Disabled","Disabled","Disabled"],"prev":{"index":4,"_p":null},"exploring":true}},{"Load":{"values":[1,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Skip","Disabled","Disabled","Disabled"],"prev":{"index":6,"_p":null},"exploring":true}},{"Load":{"values":[2,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Active","Skip","Disabled","Disabled","Disabled"],"prev":{"index":8,"_p":null},"exploring":true}},{"Load":{"values":[1,0,0,0,0,0,0],"pos":0,"len":1,"exploring":true}},{"Schedule":{"preemptions":0,"initial_active":0,"threads":["Visited","Active","Disabled","Disabled","Disabled"],"prev":{"index":10,"_p":null},"exploring":true}}]},"exploring":true,"skipping":false,"exploring_on_start":true}

homework/src/arc.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ struct ArcInner<T> {
174174
data: T,
175175
}
176176

177+
// count and data are both sync/send
177178
unsafe impl<T: Sync + Send> Send for ArcInner<T> {}
178179
unsafe impl<T: Sync + Send> Sync for ArcInner<T> {}
179180

@@ -208,14 +209,18 @@ impl<T> Arc<T> {
208209
/// ```
209210
#[inline]
210211
pub fn get_mut(this: &mut Self) -> Option<&mut T> {
211-
todo!()
212+
if this.inner().count.load(Ordering::Acquire) == 1 {
213+
Some(unsafe { Self::get_mut_unchecked(this) })
214+
} else {
215+
None
216+
}
212217
}
213218

214219
// Used in `get_mut` and `make_mut` to check if the given `Arc` is the unique reference to the
215220
// underlying data.
216221
#[inline]
217222
fn is_unique(&mut self) -> bool {
218-
todo!()
223+
self.inner().count.load(Ordering::Acquire) == 1
219224
}
220225

221226
/// Returns a mutable reference into the given `Arc` without any check.
@@ -266,7 +271,7 @@ impl<T> Arc<T> {
266271
/// ```
267272
#[inline]
268273
pub fn count(this: &Self) -> usize {
269-
todo!()
274+
this.inner().count.load(Ordering::Acquire)
270275
}
271276

272277
#[inline]
@@ -317,7 +322,13 @@ impl<T> Arc<T> {
317322
/// ```
318323
#[inline]
319324
pub fn try_unwrap(this: Self) -> Result<T, Self> {
320-
todo!()
325+
if Self::count(&this) == 1 {
326+
let res = Ok(unsafe { Box::from_raw(this.ptr.as_ptr()).data });
327+
mem::forget(this);
328+
res
329+
} else {
330+
Err(this)
331+
}
321332
}
322333
}
323334

@@ -349,7 +360,26 @@ impl<T: Clone> Arc<T> {
349360
/// ```
350361
#[inline]
351362
pub fn make_mut(this: &mut Self) -> &mut T {
352-
todo!()
363+
/*
364+
pub struct Arc<T> {
365+
ptr: NonNull<ArcInner<T>>,
366+
phantom: PhantomData<ArcInner<T>>,
367+
}
368+
struct ArcInner<T> {
369+
count: AtomicUsize,
370+
data: T,
371+
}
372+
*/
373+
if !this.is_unique() {
374+
*this = Self::from_inner(
375+
NonNull::new(Box::into_raw(Box::new(ArcInner {
376+
count: AtomicUsize::new(1),
377+
data: this.inner().data.clone(),
378+
})))
379+
.unwrap(),
380+
);
381+
}
382+
unsafe { Self::get_mut_unchecked(this) }
353383
}
354384
}
355385

@@ -374,7 +404,8 @@ impl<T> Clone for Arc<T> {
374404
/// ```
375405
#[inline]
376406
fn clone(&self) -> Arc<T> {
377-
todo!()
407+
self.inner().count.fetch_add(1, Ordering::AcqRel);
408+
Self::from_inner(self.ptr)
378409
}
379410
}
380411

@@ -413,7 +444,14 @@ impl<T> Drop for Arc<T> {
413444
/// drop(foo2); // Prints "dropped!"
414445
/// ```
415446
fn drop(&mut self) {
416-
todo!()
447+
self.inner().count.fetch_sub(1, Ordering::AcqRel);
448+
if self.inner().count.load(Ordering::Acquire) == 0 {
449+
unsafe {
450+
// drop the inner value
451+
drop(Box::from_raw(self.ptr.as_ptr()));
452+
println!("dropped!")
453+
}
454+
}
417455
}
418456
}
419457

0 commit comments

Comments
 (0)