1
1
//! Internal data structures used in single-producer queues.
2
+ //!
3
+ //! TODO: move
4
+ //!
5
+ //! Concurrent single-producer queues based on circular buffer.
6
+ //!
7
+ //! [`CircBuf`] is a circular buffer, which is basically a fixed-sized array that has two ends: tx
8
+ //! and rx. A [`CircBuf`] can [`send`] values into the tx end and [`CircBuf::try_recv`] values from
9
+ //! the rx end. A [`CircBuf`] doesn't implement `Sync` so it cannot be shared among multiple
10
+ //! threads. However, it can create [`Receiver`]s, and those can be easily cloned, shared, and sent
11
+ //! to other threads. [`Receiver`]s can only [`Receiver::try_recv`] values from the rx end.
12
+ //!
13
+ //! Here's a visualization of a [`CircBuf`] of capacity 4, consisting of 2 values `a` and `b`.
14
+ //!
15
+ //! ```text
16
+ //! ___
17
+ //! | a | <- rx (CircBuf::try_recv, Receiver::try_recv)
18
+ //! | b |
19
+ //! | | <- tx (CircBuf::send)
20
+ //! | |
21
+ //! ¯¯¯
22
+ //! ```
23
+ //!
24
+ //! [`DynamicCircBuf`] is a dynamically growable and shrinkable circular buffer. Internally,
25
+ //! [`DynamicCircBuf`] has a [`CircBuf`] and resizes it when necessary.
26
+ //!
27
+ //!
28
+ //! # Usage: fair work-stealing schedulers
29
+ //!
30
+ //! This data structure can be used in fair work-stealing schedulers for multiple threads as
31
+ //! follows.
32
+ //!
33
+ //! Each thread owns a [`CircBuf`] (or [`DynamicCircBuf`]) and creates a [`Receiver`] that is shared
34
+ //! among all other threads (or creates one [`Receiver`] for each of the other threads).
35
+ //!
36
+ //! Each thread is executing a loop in which it attempts to [`CircBuf::try_recv`] some task from its
37
+ //! own [`CircBuf`] and perform it. If the buffer is empty, it attempts to [`Receiver::try_recv`]
38
+ //! work from other threads instead. When performing a task, a thread may produce more tasks by
39
+ //! [`send`]ing them to its buffer.
40
+ //!
41
+ //! It is worth noting that it is discouraged to use work-stealing deque for fair schedulers,
42
+ //! because its `pop()` may return a task that is just `push()`ed, effectively scheduling the same
43
+ //! work repeatedly.
44
+ //!
45
+ //! [`CircBuf`]: struct.CircBuf.html
46
+ //! [`DynamicCircBuf`]: struct.DynamicCircBuf.html
47
+ //! [`Receiver`]: struct.Receiver.html
48
+ //! [`send`]: struct.CircBuf.html#method.send
49
+ //! [`CircBuf::try_recv`]: struct.CircBuf.html#method.try_recv
50
+ //! [`Receiver::try_recv`]: struct.Receiver.html#method.try_recv
2
51
3
52
use std:: cell:: Cell ;
4
53
use std:: fmt;
@@ -104,7 +153,7 @@ impl<T> CircBuf<T> {
104
153
/// # Examples
105
154
///
106
155
/// ```
107
- /// use crossbeam_circbuf::sp::internal ::CircBuf;
156
+ /// use crossbeam_circbuf::sp_inner ::CircBuf;
108
157
///
109
158
/// // The capacity will be rounded up to 1024.
110
159
/// let cb = CircBuf::<i32>::new(1000);
@@ -128,7 +177,7 @@ impl<T> CircBuf<T> {
128
177
/// # Examples
129
178
///
130
179
/// ```
131
- /// use crossbeam_circbuf::sp::internal ::CircBuf;
180
+ /// use crossbeam_circbuf::sp_inner ::CircBuf;
132
181
///
133
182
/// let cb = CircBuf::new(16);
134
183
/// cb.send(1).unwrap();
@@ -147,7 +196,7 @@ impl<T> CircBuf<T> {
147
196
/// # Examples
148
197
///
149
198
/// ```
150
- /// use crossbeam_circbuf::sp::internal ::{CircBuf, TryRecv};
199
+ /// use crossbeam_circbuf::sp_inner ::{CircBuf, TryRecv};
151
200
///
152
201
/// let cb = CircBuf::new(16);
153
202
/// cb.send(1).unwrap();
@@ -268,7 +317,7 @@ impl<T> CircBuf<T> {
268
317
/// # Examples
269
318
///
270
319
/// ```
271
- /// use crossbeam_circbuf::sp::internal ::{CircBuf, TryRecv};
320
+ /// use crossbeam_circbuf::sp_inner ::{CircBuf, TryRecv};
272
321
/// use std::thread;
273
322
///
274
323
/// let cb = CircBuf::new(16);
@@ -351,7 +400,7 @@ impl<T> DynamicCircBuf<T> {
351
400
/// # Examples
352
401
///
353
402
/// ```
354
- /// use crossbeam_circbuf::sp::internal ::DynamicCircBuf;
403
+ /// use crossbeam_circbuf::sp_inner ::DynamicCircBuf;
355
404
///
356
405
/// let cb = DynamicCircBuf::<i32>::new();
357
406
/// ```
@@ -367,7 +416,7 @@ impl<T> DynamicCircBuf<T> {
367
416
/// # Examples
368
417
///
369
418
/// ```
370
- /// use crossbeam_circbuf::sp::internal ::DynamicCircBuf;
419
+ /// use crossbeam_circbuf::sp_inner ::DynamicCircBuf;
371
420
///
372
421
/// // The minimum capacity will be rounded up to 1024.
373
422
/// let cb = DynamicCircBuf::<i32>::with_min_capacity(1000);
@@ -391,7 +440,7 @@ impl<T> DynamicCircBuf<T> {
391
440
/// # Examples
392
441
///
393
442
/// ```
394
- /// use crossbeam_circbuf::sp::internal ::DynamicCircBuf;
443
+ /// use crossbeam_circbuf::sp_inner ::DynamicCircBuf;
395
444
///
396
445
/// let cb = DynamicCircBuf::new();
397
446
/// cb.send(1);
@@ -430,7 +479,7 @@ impl<T> DynamicCircBuf<T> {
430
479
/// # Examples
431
480
///
432
481
/// ```
433
- /// use crossbeam_circbuf::sp::internal ::{DynamicCircBuf, TryRecv};
482
+ /// use crossbeam_circbuf::sp_inner ::{DynamicCircBuf, TryRecv};
434
483
///
435
484
/// let cb = DynamicCircBuf::new();
436
485
/// cb.send(1);
@@ -464,7 +513,7 @@ impl<T> DynamicCircBuf<T> {
464
513
/// # Examples
465
514
///
466
515
/// ```
467
- /// use crossbeam_circbuf::sp::internal ::{DynamicCircBuf, TryRecv};
516
+ /// use crossbeam_circbuf::sp_inner ::{DynamicCircBuf, TryRecv};
468
517
/// use std::thread;
469
518
///
470
519
/// let cb = DynamicCircBuf::new();
@@ -558,7 +607,7 @@ impl<T> Receiver<T> {
558
607
/// # Examples
559
608
///
560
609
/// ```
561
- /// use crossbeam_circbuf::sp::internal ::{DynamicCircBuf, TryRecv};
610
+ /// use crossbeam_circbuf::sp_inner ::{DynamicCircBuf, TryRecv};
562
611
///
563
612
/// let cb = DynamicCircBuf::new();
564
613
/// let r = cb.receiver();
@@ -615,7 +664,7 @@ impl<T> Receiver<T> {
615
664
/// # Examples
616
665
///
617
666
/// ```
618
- /// use crossbeam_circbuf::sp::internal ::{DynamicCircBuf, TryRecv};
667
+ /// use crossbeam_circbuf::sp_inner ::{DynamicCircBuf, TryRecv};
619
668
///
620
669
/// let cb = DynamicCircBuf::new();
621
670
/// let r = cb.receiver();
@@ -706,7 +755,7 @@ impl<T> Receiver<T> {
706
755
/// # Examples
707
756
///
708
757
/// ```
709
- /// use crossbeam_circbuf::sp::internal ::{DynamicCircBuf, TryRecv};
758
+ /// use crossbeam_circbuf::sp_inner ::{DynamicCircBuf, TryRecv};
710
759
///
711
760
/// let cb = DynamicCircBuf::new();
712
761
/// let r = cb.receiver();
0 commit comments