diff --git a/docs/src/index.md b/docs/src/index.md index c79bcf5..b365082 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -6,6 +6,8 @@ ## Queue/stack ```@docs +DualLinkedConcurrentRingQueue +LinkedConcurrentRingQueue ConcurrentQueue ConcurrentStack WorkStealingDeque diff --git a/src/docs/DualLinkedConcurrentRingQueue.md b/src/docs/DualLinkedConcurrentRingQueue.md new file mode 100644 index 0000000..9ddd8f7 --- /dev/null +++ b/src/docs/DualLinkedConcurrentRingQueue.md @@ -0,0 +1,41 @@ + DualLinkedConcurrentRingQueue{T}() + +A concurrent queue with "almost" nonblocking `push!` and `popfirst!`. Calling +`popfirst!` on an empty queue waits for a `push!` in another task. + +See also: [`LinkedConcurrentRingQueue`](@ref) + +# Examples +```julia +julia> using ConcurrentCollections + +julia> q = DualLinkedConcurrentRingQueue{Int}(); + +julia> push!(q, 111); + +julia> push!(q, 222); + +julia> popfirst!(q) # first-in first-out +111 + +julia> popfirst!(q) +222 +``` + +# Extended help + +Since `popfirst!` blocks when called on an empty queue, a +`DualLinkedConcurrentRingQueue` acts almost like an unbounded `Base.Channel`. +However, `DualLinkedConcurrentRingQueue` does not support `close` or blocking on +`push!` when exceeding a bound. + +`DualLinkedConcurrentRingQueue` performs very well compared to other concurrent +queue implementations. However, since it is based on linked fixed-size buffers, +it has relatively large memory overhead. + +`DualLinkedConcurrentRingQueue` is based on the linked multi-polarity dual ring +queue by Izraelevitz and Scott (2017): + +> Izraelevitz, Joseph, and Michael L. Scott. “Generality and Speed in +> Nonblocking Dual Containers.” ACM Transactions on Parallel Computing 3, no. 4 +> (March 23, 2017): 22:1–22:37. . diff --git a/src/docs/LinkedConcurrentRingQueue.md b/src/docs/LinkedConcurrentRingQueue.md new file mode 100644 index 0000000..2ab1b3f --- /dev/null +++ b/src/docs/LinkedConcurrentRingQueue.md @@ -0,0 +1,37 @@ + LinkedConcurrentRingQueue{T}() + +A concurrent queue with nonblocking `push!` and [`trypopfirst!`](@ref). + +See also: [`DualLinkedConcurrentRingQueue`](@ref) + +# Examples +```julia +julia> using ConcurrentCollections + +julia> q = LinkedConcurrentRingQueue{Int}(); + +julia> push!(q, 111); + +julia> push!(q, 222); + +julia> trypopfirst!(q) # first-in first-out +Some(111) + +julia> trypopfirst!(q) +Some(222) + +julia> trypopfirst!(q) === nothing # queue is empty +true +``` + +# Extended help + +`LinkedConcurrentRingQueue` is based on Linked Concurrent Ring Queue (or List of +Concurrent Ring Queues; LCRQ) by Morrison and Afek (2013): + +> Morrison, Adam, and Yehuda Afek. “Fast Concurrent Queues for X86 Processors.” +> In Proceedings of the 18th ACM SIGPLAN Symposium on Principles and Practice of +> Parallel Programming, 103–112. PPoPP ’13. New York, NY, USA: Association for +> Computing Machinery, 2013. . +> (Revised version: +> )