Skip to content

Commit

Permalink
Port select2.go test to Rust (#567)
Browse files Browse the repository at this point in the history
* Port select2.go test to Rust

* Run cargo fmt

* Move #[global_allocator] to outside of submodule
  • Loading branch information
Bernardo Yusti committed Sep 13, 2020
1 parent 22d905b commit e97836c
Showing 1 changed file with 68 additions and 2 deletions.
70 changes: 68 additions & 2 deletions crossbeam-channel/tests/golang.rs
Expand Up @@ -9,14 +9,16 @@
//! - https://golang.org/LICENSE
//! - https://golang.org/PATENTS

use std::alloc::{GlobalAlloc, Layout, System};
use std::any::Any;
use std::cell::Cell;
use std::collections::HashMap;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
use std::time::Duration;

use crossbeam_channel::{bounded, select, tick, Receiver, Select, Sender};
use crossbeam_channel::{bounded, select, tick, unbounded, Receiver, Select, Sender};

fn ms(ms: u64) -> Duration {
Duration::from_millis(ms)
Expand Down Expand Up @@ -111,6 +113,12 @@ fn make<T>(cap: usize) -> Chan<T> {
}
}

fn make_unbounded<T>() -> Chan<T> {
let (s, r) = unbounded();
Chan {
inner: Arc::new(Mutex::new(ChanInner { s: Some(s), r })),
}
}
#[derive(Clone)]
struct WaitGroup(Arc<WaitGroupInner>);

Expand Down Expand Up @@ -159,6 +167,27 @@ impl<F: FnOnce()> Drop for Defer<F> {
}
}

struct Counter;

static ALLOCATED: AtomicUsize = AtomicUsize::new(0);
unsafe impl GlobalAlloc for Counter {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ret = System.alloc(layout);
if !ret.is_null() {
ALLOCATED.fetch_add(layout.size(), SeqCst);
}
return ret;
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
System.dealloc(ptr, layout);
ALLOCATED.fetch_sub(layout.size(), SeqCst);
}
}

#[global_allocator]
static A: Counter = Counter;

macro_rules! defer {
($body:expr) => {
let _defer = Defer {
Expand Down Expand Up @@ -660,7 +689,44 @@ mod select {

// https://github.com/golang/go/blob/master/test/chan/select2.go
mod select2 {
// TODO
use super::*;

#[test]
fn main() {
fn sender(c: &Chan<i32>, n: i32) {
for _ in 0..n {
c.send(1);
}
}

fn receiver(c: &Chan<i32>, dummy: &Chan<i32>, n: i32) {
for _ in 0..n {
select! {
recv(c.rx()) -> _ => {
()
}
recv(dummy.rx()) -> _ => {
panic!("dummy");
}
}
}
}

let c = make_unbounded::<i32>();
let dummy = make_unbounded::<i32>();

ALLOCATED.store(0, SeqCst);

go!(c, sender(&c, 100000));
receiver(&c, &dummy, 100000);

let alloc = ALLOCATED.load(SeqCst);

go!(c, sender(&c, 100000));
receiver(&c, &dummy, 100000);

assert!(!(ALLOCATED.load(SeqCst) > alloc && (ALLOCATED.load(SeqCst) - alloc) > 110000))
}
}

// https://github.com/golang/go/blob/master/test/chan/select3.go
Expand Down

0 comments on commit e97836c

Please sign in to comment.