1 //! Tests copied from Go and manually rewritten in Rust.
4 //! - https://github.com/golang/go
6 //! Copyright & License:
7 //! - Copyright (c) 2009 The Go Authors
8 //! - https://golang.org/AUTHORS
9 //! - https://golang.org/LICENSE
10 //! - https://golang.org/PATENTS
12 #![allow(clippy::mutex_atomic, clippy::redundant_clone)]
14 use std
::alloc
::{GlobalAlloc, Layout, System}
;
17 use std
::collections
::HashMap
;
18 use std
::sync
::atomic
::{AtomicUsize, Ordering::SeqCst}
;
19 use std
::sync
::{Arc, Condvar, Mutex}
;
21 use std
::time
::Duration
;
23 use crossbeam_channel
::{bounded, select, tick, unbounded, Receiver, Select, Sender}
;
25 fn ms(ms
: u64) -> Duration
{
26 Duration
::from_millis(ms
)
30 inner
: Arc
<Mutex
<ChanInner
<T
>>>,
38 impl<T
> Clone
for Chan
<T
> {
39 fn clone(&self) -> Chan
<T
> {
41 inner
: self.inner
.clone(),
47 fn send(&self, msg
: T
) {
54 .expect("sending into closed channel")
59 fn try_recv(&self) -> Option
<T
> {
60 let r
= self.inner
.lock().unwrap().r
.clone();
64 fn recv(&self) -> Option
<T
> {
65 let r
= self.inner
.lock().unwrap().r
.clone();
75 .expect("channel already closed");
78 fn rx(&self) -> Receiver
<T
> {
79 self.inner
.lock().unwrap().r
.clone()
82 fn tx(&self) -> Sender
<T
> {
83 match self.inner
.lock().unwrap().s
.as_ref() {
85 let (s
, r
) = bounded(0);
94 impl<T
> Iterator
for Chan
<T
> {
97 fn next(&mut self) -> Option
<Self::Item
> {
102 impl<'a
, T
> IntoIterator
for &'a Chan
<T
> {
104 type IntoIter
= Chan
<T
>;
106 fn into_iter(self) -> Self::IntoIter
{
111 fn make
<T
>(cap
: usize) -> Chan
<T
> {
112 let (s
, r
) = bounded(cap
);
114 inner
: Arc
::new(Mutex
::new(ChanInner { s: Some(s), r }
)),
118 fn make_unbounded
<T
>() -> Chan
<T
> {
119 let (s
, r
) = unbounded();
121 inner
: Arc
::new(Mutex
::new(ChanInner { s: Some(s), r }
)),
125 struct WaitGroup(Arc
<WaitGroupInner
>);
127 struct WaitGroupInner
{
133 fn new() -> WaitGroup
{
134 WaitGroup(Arc
::new(WaitGroupInner
{
135 cond
: Condvar
::new(),
136 count
: Mutex
::new(0),
140 fn add(&self, delta
: i32) {
141 let mut count
= self.0.count
.lock().unwrap();
143 assert
!(*count
>= 0);
144 self.0.cond
.notify_all();
152 let mut count
= self.0.count
.lock().unwrap();
154 count
= self.0.cond
.wait(count
).unwrap();
159 struct Defer
<F
: FnOnce()> {
163 impl<F
: FnOnce()> Drop
for Defer
<F
> {
165 let f
= self.f
.take().unwrap();
167 let mut f
= move || f
.take().unwrap()();
174 static ALLOCATED
: AtomicUsize
= AtomicUsize
::new(0);
175 unsafe impl GlobalAlloc
for Counter
{
176 unsafe fn alloc(&self, layout
: Layout
) -> *mut u8 {
177 let ret
= System
.alloc(layout
);
179 ALLOCATED
.fetch_add(layout
.size(), SeqCst
);
184 unsafe fn dealloc(&self, ptr
: *mut u8, layout
: Layout
) {
185 System
.dealloc(ptr
, layout
);
186 ALLOCATED
.fetch_sub(layout
.size(), SeqCst
);
191 static A
: Counter
= Counter
;
196 f
: Some(Box
::new(|| $body
)),
202 (@parse
ref $v
:ident
, $
($tail
:tt
)*) => {{
204 go
!(@parse $
($tail
)*)
206 (@parse
move $v
:ident
, $
($tail
:tt
)*) => {{
208 go
!(@parse $
($tail
)*)
210 (@parse $v
:ident
, $
($tail
:tt
)*) => {{
212 go
!(@parse $
($tail
)*)
214 (@parse $body
:expr
) => {
215 ::std
::thread
::spawn(move || {
216 let res
= ::std
::panic
::catch_unwind(::std
::panic
::AssertUnwindSafe(|| {
220 eprintln
!("goroutine panicked: {:?}", res
);
221 ::std
::process
::abort();
225 (@parse $
($tail
:tt
)*) => {
226 compile_error
!("invalid `go!` syntax")
229 go
!(@parse $
($tail
)*)
233 // https://github.com/golang/go/blob/master/test/chan/doubleselect.go
238 const ITERATIONS
: i32 = 100;
240 const ITERATIONS
: i32 = 10_000;
242 fn sender(n
: i32, c1
: Chan
<i32>, c2
: Chan
<i32>, c3
: Chan
<i32>, c4
: Chan
<i32>) {
243 defer
! { c1.close() }
244 defer
! { c2.close() }
245 defer
! { c3.close() }
246 defer
! { c4.close() }
250 send(c1
.tx(), i
) -> _
=> {}
251 send(c2
.tx(), i
) -> _
=> {}
252 send(c3
.tx(), i
) -> _
=> {}
253 send(c4
.tx(), i
) -> _
=> {}
258 fn mux(out
: Chan
<i32>, inp
: Chan
<i32>, done
: Chan
<bool
>) {
265 fn recver(inp
: Chan
<i32>) {
266 let mut seen
= HashMap
::new();
269 if seen
.contains_key(&v
) {
270 panic
!("got duplicate value for {}", v
);
272 seen
.insert(v
, true);
278 let c1
= make
::<i32>(0);
279 let c2
= make
::<i32>(0);
280 let c3
= make
::<i32>(0);
281 let c4
= make
::<i32>(0);
282 let done
= make
::<bool
>(0);
283 let cmux
= make
::<i32>(0);
285 go
!(c1
, c2
, c3
, c4
, sender(ITERATIONS
, c1
, c2
, c3
, c4
));
286 go
!(cmux
, c1
, done
, mux(cmux
, c1
, done
));
287 go
!(cmux
, c2
, done
, mux(cmux
, c2
, done
));
288 go
!(cmux
, c3
, done
, mux(cmux
, c3
, done
));
289 go
!(cmux
, c4
, done
, mux(cmux
, c4
, done
));
301 // https://github.com/golang/go/blob/master/test/chan/fifo.go
309 let ch
= make
::<i32>(N
as usize);
314 if ch
.recv() != Some(i
) {
315 panic
!("bad receive");
320 fn chain(ch
: Chan
<i32>, val
: i32, inp
: Chan
<i32>, out
: Chan
<i32>) {
322 if ch
.recv() != Some(val
) {
330 let ch
= make
::<i32>(0);
331 let mut inp
= make
::<i32>(0);
332 let start
= inp
.clone();
335 let out
= make
::<i32>(0);
336 go
!(ch
, i
, inp
, out
, chain(ch
, i
, inp
, out
));
348 // https://github.com/golang/go/blob/master/test/chan/goroutines.go
352 fn f(left
: Chan
<i32>, right
: Chan
<i32>) {
353 left
.send(right
.recv().unwrap());
360 let leftmost
= make
::<i32>(0);
361 let mut right
= leftmost
.clone();
362 let mut left
= leftmost
.clone();
365 right
= make
::<i32>(0);
366 go
!(left
, right
, f(left
, right
));
367 left
= right
.clone();
370 go
!(right
, right
.send(1));
371 leftmost
.recv().unwrap();
375 // https://github.com/golang/go/blob/master/test/chan/nonblock.go
379 fn i32receiver(c
: Chan
<i32>, strobe
: Chan
<bool
>) {
380 if c
.recv().unwrap() != 123 {
386 fn i32sender(c
: Chan
<i32>, strobe
: Chan
<bool
>) {
391 fn i64receiver(c
: Chan
<i64>, strobe
: Chan
<bool
>) {
392 if c
.recv().unwrap() != 123456 {
398 fn i64sender(c
: Chan
<i64>, strobe
: Chan
<bool
>) {
403 fn breceiver(c
: Chan
<bool
>, strobe
: Chan
<bool
>) {
404 if !c
.recv().unwrap() {
410 fn bsender(c
: Chan
<bool
>, strobe
: Chan
<bool
>) {
415 fn sreceiver(c
: Chan
<String
>, strobe
: Chan
<bool
>) {
416 if c
.recv().unwrap() != "hello" {
422 fn ssender(c
: Chan
<String
>, strobe
: Chan
<bool
>) {
423 c
.send("hello again".to_string());
427 const MAX_TRIES
: usize = 10000; // Up to 100ms per test.
431 let ticker
= tick(Duration
::new(0, 10_000)); // 10 us
433 ticker
.recv().unwrap();
434 ticker
.recv().unwrap();
440 let sync
= make
::<bool
>(0);
443 let c32
= make
::<i32>(buffer
);
444 let c64
= make
::<i64>(buffer
);
445 let cb
= make
::<bool
>(buffer
);
446 let cs
= make
::<String
>(buffer
);
449 recv(c32
.rx()) -> _
=> panic
!("blocked i32sender"),
454 recv(c64
.rx()) -> _
=> panic
!("blocked i64sender"),
459 recv(cb
.rx()) -> _
=> panic
!("blocked bsender"),
464 recv(cs
.rx()) -> _
=> panic
!("blocked ssender"),
468 go
!(c32
, sync
, i32receiver(c32
, sync
));
472 send(c32
.tx(), 123) -> _
=> break,
475 if r
#try > MAX_TRIES {
476 println
!("i32receiver buffer={}", buffer
);
484 go
!(c32
, sync
, i32sender(c32
, sync
));
491 recv(c32
.rx()) -> v
=> {
493 panic
!("i32sender value");
499 if r
#try > MAX_TRIES {
500 println
!("i32sender buffer={}", buffer
);
511 go
!(c64
, sync
, i64receiver(c64
, sync
));
515 send(c64
.tx(), 123456) -> _
=> break,
518 if r
#try > MAX_TRIES {
519 println
!("i64receiver buffer={}", buffer
);
527 go
!(c64
, sync
, i64sender(c64
, sync
));
534 recv(c64
.rx()) -> v
=> {
536 panic
!("i64sender value");
542 if r
#try > MAX_TRIES {
543 println
!("i64sender buffer={}", buffer
);
554 go
!(cb
, sync
, breceiver(cb
, sync
));
558 send(cb
.tx(), true) -> _
=> break,
561 if r
#try > MAX_TRIES {
562 println
!("breceiver buffer={}", buffer
);
570 go
!(cb
, sync
, bsender(cb
, sync
));
577 recv(cb
.rx()) -> v
=> {
579 panic
!("bsender value");
585 if r
#try > MAX_TRIES {
586 println
!("bsender buffer={}", buffer
);
597 go
!(cs
, sync
, sreceiver(cs
, sync
));
601 send(cs
.tx(), "hello".to_string()) -> _
=> break,
604 if r
#try > MAX_TRIES {
605 println
!("sreceiver buffer={}", buffer
);
613 go
!(cs
, sync
, ssender(cs
, sync
));
620 recv(cs
.rx()) -> v
=> {
621 if v
!= Ok("hello again".to_string()) {
622 panic
!("ssender value");
628 if r
#try > MAX_TRIES {
629 println
!("ssender buffer={}", buffer
);
643 // https://github.com/golang/go/blob/master/test/chan/select.go
649 let shift
= Cell
::new(0);
650 let counter
= Cell
::new(0);
653 counter
.set(counter
.get() + 1);
657 let send
= |mut a
: Option
<&Chan
<u32>>, mut b
: Option
<&Chan
<u32>>| {
659 let never
= make
::<u32>(0);
661 let nil1
= never
.tx();
662 let nil2
= never
.tx();
663 let v1
= get_value();
664 let v2
= get_value();
666 send(a
.map(|c
| c
.tx()).unwrap_or(nil1
), v1
) -> _
=> {
670 send(b
.map(|c
| c
.tx()).unwrap_or(nil2
), v2
) -> _
=> {
676 shift
.set(shift
.get() + 1);
681 let a
= make
::<u32>(1);
682 let b
= make
::<u32>(1);
684 assert_eq
!(send(Some(&a
), Some(&b
)), 2);
686 let av
= a
.recv().unwrap();
687 let bv
= b
.recv().unwrap();
688 assert_eq
!(av
| bv
, 3);
690 assert_eq
!(send(Some(&a
), None
), 1);
691 assert_eq
!(counter
.get(), 10);
695 // https://github.com/golang/go/blob/master/test/chan/select2.go
702 const N
: i32 = 100000;
706 fn sender(c
: &Chan
<i32>, n
: i32) {
712 fn receiver(c
: &Chan
<i32>, dummy
: &Chan
<i32>, n
: i32) {
715 recv(c
.rx()) -> _
=> {}
716 recv(dummy
.rx()) -> _
=> {
723 let c
= make_unbounded
::<i32>();
724 let dummy
= make_unbounded
::<i32>();
726 ALLOCATED
.store(0, SeqCst
);
728 go
!(c
, sender(&c
, N
));
729 receiver(&c
, &dummy
, N
);
731 let alloc
= ALLOCATED
.load(SeqCst
);
733 go
!(c
, sender(&c
, N
));
734 receiver(&c
, &dummy
, N
);
737 !(ALLOCATED
.load(SeqCst
) > alloc
738 && (ALLOCATED
.load(SeqCst
) - alloc
) > (N
as usize + 10000))
743 // https://github.com/golang/go/blob/master/test/chan/select3.go
748 // https://github.com/golang/go/blob/master/test/chan/select4.go
754 let c
= make
::<i32>(1);
755 let c1
= make
::<i32>(0);
758 recv(c1
.rx()) -> _
=> panic
!("BUG"),
759 recv(c
.rx()) -> v
=> assert_eq
!(v
, Ok(42)),
764 // https://github.com/golang/go/blob/master/test/chan/select6.go
770 let c1
= make
::<bool
>(0);
771 let c2
= make
::<bool
>(0);
772 let c3
= make
::<bool
>(0);
777 recv(c1
.rx()) -> _
=> panic
!("dummy"),
778 recv(c2
.rx()) -> _
=> c3
.send(true),
782 go
!(c2
, c2
.send(true));
790 // https://github.com/golang/go/blob/master/test/chan/select7.go
794 fn recv1(c
: Chan
<i32>) {
798 fn recv2(c
: Chan
<i32>) {
800 recv(c
.rx()) -> _
=> ()
804 fn recv3(c
: Chan
<i32>) {
805 let c2
= make
::<i32>(1);
807 recv(c
.rx()) -> _
=> (),
808 recv(c2
.rx()) -> _
=> ()
812 fn send1(recv
: fn(Chan
<i32>)) {
813 let c
= make
::<i32>(1);
819 fn send2(recv
: fn(Chan
<i32>)) {
820 let c
= make
::<i32>(1);
824 send(c
.tx(), 1) -> _
=> ()
828 fn send3(recv
: fn(Chan
<i32>)) {
829 let c
= make
::<i32>(1);
832 let c2
= make
::<i32>(1);
834 send(c
.tx(), 1) -> _
=> (),
835 send(c2
.tx(), 1) -> _
=> ()
853 // https://github.com/golang/go/blob/master/test/chan/sieve1.go
857 fn generate(ch
: Chan
<i32>) {
865 fn filter(in_ch
: Chan
<i32>, out_ch
: Chan
<i32>, prime
: i32) {
873 fn sieve(primes
: Chan
<i32>) {
874 let mut ch
= make
::<i32>(1);
875 go
!(ch
, generate(ch
));
877 let prime
= ch
.recv().unwrap();
880 let ch1
= make
::<i32>(1);
881 go
!(ch
, ch1
, prime
, filter(ch
, ch1
, prime
));
888 let primes
= make
::<i32>(1);
889 go
!(primes
, sieve(primes
));
892 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
895 for item
in a
.iter() {
896 let x
= primes
.recv().unwrap();
898 println
!("{} != {}", x
, item
);
905 // https://github.com/golang/go/blob/master/test/chan/zerosize.go
910 fn zero_size_struct() {
912 let _
= make
::<ZeroSize
>(0);
916 fn zero_size_array() {
917 let _
= make
::<[u8; 0]>(0);
921 // https://github.com/golang/go/blob/master/src/runtime/chan_test.go
934 // Ensure that receive from empty chan blocks.
935 let c
= make
::<i32>(cap
as usize);
937 let recv1
= Arc
::new(Mutex
::new(false));
940 *recv1
.lock().unwrap() = true;
943 let recv2
= Arc
::new(Mutex
::new(false));
946 *recv2
.lock().unwrap() = true;
949 thread
::sleep(ms(1));
951 if *recv1
.lock().unwrap() || *recv2
.lock().unwrap() {
955 // Ensure that non-blocking receive does not block.
957 recv(c
.rx()) -> _
=> panic
!(),
961 recv(c
.rx()) -> _
=> panic
!(),
970 // Ensure that send to full chan blocks.
971 let c
= make
::<i32>(cap
as usize);
976 let sent
= Arc
::new(Mutex
::new(0));
979 *sent
.lock().unwrap() = 1;
982 thread
::sleep(ms(1));
984 if *sent
.lock().unwrap() != 0 {
988 // Ensure that non-blocking send does not block.
990 send(c
.tx(), 0) -> _
=> panic
!(),
997 // Ensure that we receive 0 from closed chan.
998 let c
= make
::<i32>(cap
as usize);
1011 if c
.recv() != None
{
1014 if c
.try_recv() != None
{
1020 // Ensure that close unblocks receive.
1021 let c
= make
::<i32>(cap
as usize);
1022 let done
= make
::<bool
>(0);
1025 let v
= c
.try_recv();
1026 done
.send(v
.is_none());
1029 thread
::sleep(ms(1));
1032 if !done
.recv().unwrap() {
1038 // Send 100 integers,
1039 // ensure that we receive them non-corrupted in FIFO order.
1040 let c
= make
::<i32>(cap
as usize);
1047 if c
.recv() != Some(i
) {
1052 // Same, but using recv2.
1059 if c
.recv() != Some(i
) {
1068 fn test_nonblock_recv_race() {
1070 const N
: usize = 100;
1072 const N
: usize = 1000;
1075 let c
= make
::<i32>(1);
1080 recv(c
.rx()) -> _
=> {}
1081 default => panic
!("chan is not ready"),
1092 fn test_nonblock_select_race() {
1094 const N
: usize = 100;
1096 const N
: usize = 1000;
1098 let done
= make
::<bool
>(1);
1100 let c1
= make
::<i32>(1);
1101 let c2
= make
::<i32>(1);
1106 recv(c1
.rx()) -> _
=> {}
1107 recv(c2
.rx()) -> _
=> {}
1118 recv(c1
.rx()) -> _
=> {}
1121 if !done
.recv().unwrap() {
1122 panic
!("no chan is ready");
1128 fn test_nonblock_select_race2() {
1130 const N
: usize = 100;
1132 const N
: usize = 1000;
1134 let done
= make
::<bool
>(1);
1136 let c1
= make
::<i32>(1);
1137 let c2
= make
::<i32>(0);
1142 recv(c1
.rx()) -> _
=> {}
1143 recv(c2
.rx()) -> _
=> {}
1154 recv(c1
.rx()) -> _
=> {}
1157 if !done
.recv().unwrap() {
1158 panic
!("no chan is ready");
1164 fn test_self_select() {
1165 // Ensure that send/recv on the same chan in select
1166 // does not crash nor deadlock.
1169 const N
: usize = 100;
1171 const N
: usize = 1000;
1173 for &cap
in &[0, 10] {
1174 let wg
= WaitGroup
::new();
1176 let c
= make
::<i32>(cap
);
1181 defer
! { wg.done() }
1183 if p
== 0 || i
% 2 == 0 {
1185 send(c
.tx(), p
) -> _
=> {}
1186 recv(c
.rx()) -> v
=> {
1187 if cap
== 0 && v
.ok() == Some(p
) {
1188 panic
!("self receive");
1194 recv(c
.rx()) -> v
=> {
1195 if cap
== 0 && v
.ok() == Some(p
) {
1196 panic
!("self receive");
1199 send(c
.tx(), p
) -> _
=> {}
1210 fn test_select_stress() {
1212 const N
: usize = 100;
1214 const N
: usize = 10000;
1223 // There are 4 goroutines that send N values on each of the chans,
1224 // + 4 goroutines that receive N values on each of the chans,
1225 // + 1 goroutine that sends N values on each of the chans in a single select,
1226 // + 1 goroutine that receives N values on each of the chans in a single select.
1227 // All these sends, receives and selects interact chaotically at runtime,
1228 // but we are careful that this whole construct does not deadlock.
1229 let wg
= WaitGroup
::new();
1249 let mut c1
= c
.iter().map(|c
| Some(c
.rx().clone())).collect
::<Vec
<_
>>();
1253 let mut sel
= Select
::new();
1254 let mut opers
= [!0; 4];
1255 for &i
in &[3, 2, 0, 1] {
1256 if let Some(c
) = &c1
[i
] {
1257 opers
[i
] = sel
.recv(c
);
1261 let oper
= sel
.select();
1264 if opers
[i
] == oper
.index() {
1266 let _
= oper
.recv(c1
[i
].as_ref().unwrap());
1283 let mut c1
= c
.iter().map(|c
| Some(c
.tx().clone())).collect
::<Vec
<_
>>();
1287 let mut sel
= Select
::new();
1288 let mut opers
= [!0; 4];
1289 for &i
in &[0, 1, 2, 3] {
1290 if let Some(c
) = &c1
[i
] {
1291 opers
[i
] = sel
.send(c
);
1295 let oper
= sel
.select();
1298 if opers
[i
] == oper
.index() {
1300 let _
= oper
.send(c1
[i
].as_ref().unwrap(), 0);
1319 fn test_select_fairness() {
1321 const TRIALS
: usize = 100;
1323 const TRIALS
: usize = 10000;
1325 let c1
= make
::<u8>(TRIALS
+ 1);
1326 let c2
= make
::<u8>(TRIALS
+ 1);
1328 for _
in 0..TRIALS
+ 1 {
1333 let c3
= make
::<u8>(0);
1334 let c4
= make
::<u8>(0);
1335 let out
= make
::<u8>(0);
1336 let done
= make
::<u8>(0);
1337 let wg
= WaitGroup
::new();
1340 go
!(wg
, c1
, c2
, c3
, c4
, out
, done
, {
1341 defer
! { wg.done() }
;
1345 recv(c3
.rx()) -> m
=> b
= m
.unwrap(),
1346 recv(c4
.rx()) -> m
=> b
= m
.unwrap(),
1347 recv(c1
.rx()) -> m
=> b
= m
.unwrap(),
1348 recv(c2
.rx()) -> m
=> b
= m
.unwrap(),
1351 send(out
.tx(), b
) -> _
=> {}
1352 recv(done
.rx()) -> _
=> return,
1357 let (mut cnt1
, mut cnt2
) = (0, 0);
1358 for _
in 0..TRIALS
{
1360 Some(1) => cnt1
+= 1,
1361 Some(2) => cnt2
+= 1,
1362 b
=> panic
!("unexpected value {:?} on channel", b
),
1366 // If the select in the goroutine is fair,
1367 // cnt1 and cnt2 should be about the same value.
1368 // With 10,000 trials, the expected margin of error at
1369 // a confidence level of five nines is 4.4172 / (2 * Sqrt(10000)).
1371 let r
= cnt1
as f64 / TRIALS
as f64;
1372 let e
= (r
- 0.5).abs();
1374 if e
> 4.4172 / (2.0 * (TRIALS
as f64).sqrt()) {
1376 "unfair select: in {} trials, results were {}, {}",
1386 fn test_chan_send_interface() {
1389 let c
= make
::<Box
<dyn Any
>>(1);
1390 c
.send(Box
::new(Mt
));
1393 send(c
.tx(), Box
::new(Mt
)) -> _
=> {}
1398 send(c
.tx(), Box
::new(Mt
)) -> _
=> {}
1399 send(c
.tx(), Box
::new(Mt
)) -> _
=> {}
1405 fn test_pseudo_random_send() {
1407 const N
: usize = 20;
1409 const N
: usize = 100;
1412 let c
= make
::<i32>(cap
);
1413 let l
= Arc
::new(Mutex
::new(vec
![0i32; N
]));
1414 let done
= make
::<bool
>(0);
1417 let mut l
= l
.lock().unwrap();
1419 thread
::yield_now();
1420 l
[i
] = c
.recv().unwrap();
1427 send(c
.tx(), 1) -> _
=> {}
1428 send(c
.tx(), 0) -> _
=> {}
1435 for &i
in l
.lock().unwrap().iter() {
1440 if n0
<= N
as i32 / 10 || n1
<= N
as i32 / 10 {
1442 "Want pseudorandom, got {} zeros and {} ones (chan cap {})",
1450 fn test_multi_consumer() {
1451 const NWORK
: usize = 23;
1453 const NITER
: usize = 100;
1455 const NITER
: usize = 271828;
1457 let pn
= [2, 3, 7, 11, 13, 17, 19, 23, 27, 31];
1459 let q
= make
::<i32>(NWORK
* 3);
1460 let r
= make
::<i32>(NWORK
* 3);
1462 let wg
= WaitGroup
::new();
1468 if pn
[w
% pn
.len()] == v
{
1469 thread
::yield_now();
1477 let expect
= Arc
::new(Mutex
::new(0));
1478 go
!(q
, r
, expect
, wg
, pn
, {
1480 let v
= pn
[i
% pn
.len()];
1481 *expect
.lock().unwrap() += v
;
1496 if n
!= NITER
|| s
!= *expect
.lock().unwrap() {
1502 fn test_select_duplicate_channel() {
1503 // This test makes sure we can queue a G on
1504 // the same channel multiple times.
1505 let c
= make
::<i32>(0);
1506 let d
= make
::<i32>(0);
1507 let e
= make
::<i32>(0);
1511 recv(c
.rx()) -> _
=> {}
1512 recv(d
.rx()) -> _
=> {}
1513 recv(e
.rx()) -> _
=> {}
1517 thread
::sleep(ms(1));
1520 thread
::sleep(ms(1));
1528 // https://github.com/golang/go/blob/master/test/closedchan.go
1533 // https://github.com/golang/go/blob/master/src/runtime/chanbarrier_test.go
1534 mod chanbarrier_test
{
1538 // https://github.com/golang/go/blob/master/src/runtime/race/testdata/chan_test.go
1539 mod race_chan_test
{
1543 // https://github.com/golang/go/blob/master/test/ken/chan.go
1548 // https://github.com/golang/go/blob/master/test/ken/chan1.go
1554 const N
: usize = 100;
1556 const N
: usize = 1000;
1557 // receiving "goroutines"
1558 const M
: usize = 10;
1559 // channel buffering
1562 fn r(c
: Chan
<usize>, m
: usize, h
: Arc
<Mutex
<[usize; N
]>>) {
1565 recv(c
.rx()) -> rr
=> {
1566 let r
= rr
.unwrap();
1567 let mut data
= h
.lock().unwrap();
1569 println
!("r\nm={}\nr={}\nh={}\n", m
, r
, data
[r
]);
1578 fn s(c
: Chan
<usize>, h
: Arc
<Mutex
<[usize; N
]>>) {
1581 let mut data
= h
.lock().unwrap();
1587 // https://github.com/crossbeam-rs/crossbeam/pull/615#discussion_r550281094
1595 let h
= Arc
::new(Mutex
::new([0usize
; N
]));
1596 let c
= make
::<usize>(W
);
1601 thread
::yield_now();
1603 thread
::yield_now();
1604 thread
::yield_now();