Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function pushpop!(
while true
y = nothing
for _ in 1:nspins
y = trypopfirst!(q)
y = maybepopfirst!(q)
y === nothing || break
end
y === nothing || break
Expand Down
6 changes: 3 additions & 3 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ LinkedConcurrentRingQueue
ConcurrentQueue
ConcurrentStack
WorkStealingDeque
trypop!
trypopfirst!
maybepop!
maybepopfirst!
```

## Hash table

```@docs
ConcurrentDict
modify!
tryget
maybeget
Keep
Delete
```
18 changes: 9 additions & 9 deletions src/ConcurrentCollections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export
length_upper_bound,
length_upper_bound,
modify!,
tryget,
trypop!,
trypopfirst!
maybeget,
maybepop!,
maybepopfirst!

import Base

Expand All @@ -31,9 +31,9 @@ end
abstract type ConcurrentDict{Key,Value} <: Base.AbstractDict{Key,Value} end

function modify! end
function trypop! end
function trypopfirst! end
function tryget end
function maybepop! end
function maybepopfirst! end
function maybeget end
function length_lower_bound end
function length_upper_bound end

Expand All @@ -54,9 +54,9 @@ using ..ConcurrentCollections:
length_lower_bound,
length_upper_bound,
modify!,
tryget,
trypop!,
trypopfirst!
maybeget,
maybepop!,
maybepopfirst!

include("UnsafeAtomics.jl")
using .UnsafeAtomics: acq_rel, acquire, monotonic, release, seq_cst, unordered
Expand Down
2 changes: 1 addition & 1 deletion src/cache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function ThreadLocalCache{T}(; size::Integer = 4) where {T}
return ThreadLocalCache(cache, size)
end

function maybepop!(cache::ThreadLocalCache)
function _maybepop!(cache::ThreadLocalCache)
buffer = cache.cache[Threads.threadid()]
if isempty(buffer)
return nothing
Expand Down
12 changes: 6 additions & 6 deletions src/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ end
@inline Base.getindex(ref::ValueRef) = ref.value

function Base.getindex(d::LinearProbingDict{Key}, key) where {Key}
y = tryget(d, key)
y = maybeget(d, key)
if y === nothing
throw(KeyError(key))
else
Expand All @@ -129,9 +129,9 @@ function Base.haskey(d::LinearProbingDict, key)
end

Base.get(d::LinearProbingDict, key, default) =
something(ConcurrentCollections.tryget(d, key), default)
something(ConcurrentCollections.maybeget(d, key), default)

function ConcurrentCollections.tryget(d::LinearProbingDict{<:Any,V}, key) where {V}
function ConcurrentCollections.maybeget(d::LinearProbingDict{<:Any,V}, key) where {V}
@inline f(::Nothing) = nothing
@inline f(x) = Keep(x[])
y = modify!(f, d, key)
Expand All @@ -149,14 +149,14 @@ function Base.setindex!(d::LinearProbingDict{Key,Value}, v, k) where {Key,Value}
return d
end

Base.pop!(d::LinearProbingDict, key, default) = something(trypop!(d, key), default)
Base.pop!(d::LinearProbingDict, key, default) = something(maybepop!(d, key), default)
function Base.pop!(d::LinearProbingDict, key)
value = trypop!(d, key)
value = maybepop!(d, key)
value === nothing && throw(KeyError(key))
return something(value)
end

function ConcurrentCollections.trypop!(d::LinearProbingDict, key)
function ConcurrentCollections.maybepop!(d::LinearProbingDict, key)
@inline f(::Nothing) = nothing
@inline f(ref) = Delete(ref[])
y = modify!(f, d, key)
Expand Down
4 changes: 2 additions & 2 deletions src/dlcrq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ function Base.push!(lcrq::DualLinkedConcurrentRingQueue{T}, x) where {T}
end

function Base.popfirst!(lcrq::DualLinkedConcurrentRingQueue{T}) where {T}
w = let cached = maybepop!(lcrq.waitercache)
w = let cached = _maybepop!(lcrq.waitercache)
if cached === nothing
Waiter{eltype(lcrq)}()
else
Expand Down Expand Up @@ -600,7 +600,7 @@ function denqueue!(lcrq::DualLinkedConcurrentRingQueue{T}, x::Union{T,Waiter{T}}
end

function make_newcrq!(lcrq::DualLinkedConcurrentRingQueue, crq)
oldcrq = maybepop!(lcrq.crqcache)
oldcrq = _maybepop!(lcrq.crqcache)
if oldcrq === nothing
return similar(crq)
else
Expand Down
6 changes: 3 additions & 3 deletions src/docs/ConcurrentQueue.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Concurrent queue of objects of type `T`.

Use `push!` to insert an element at the tail and [`trypopfirst!`](@ref) to
Use `push!` to insert an element at the tail and [`maybepopfirst!`](@ref) to
retrieve and remove an element at the head.

Implementation detail: It implements the Michael and Scott queue.
Expand All @@ -21,8 +21,8 @@ julia> push!(queue, 2);
julia> popfirst!(queue)
1

julia> trypopfirst!(queue)
julia> maybepopfirst!(queue)
Some(2)

julia> trypopfirst!(queue) # returns nothing
julia> maybepopfirst!(queue) # returns nothing
```
6 changes: 3 additions & 3 deletions src/docs/ConcurrentStack.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Concurrent stack of objects of type `T`.

Use `push!` to insert an element and [`trypop!`](@ref) to retrieve and remove an
Use `push!` to insert an element and [`maybepop!`](@ref) to retrieve and remove an
element.

It implements the Treiber stack.
Expand All @@ -21,8 +21,8 @@ julia> push!(stack, 2);
julia> pop!(stack)
2

julia> trypop!(stack)
julia> maybepop!(stack)
Some(1)

julia> trypop!(stack) # returns nothing
julia> maybepop!(stack) # returns nothing
```
8 changes: 4 additions & 4 deletions src/docs/LinkedConcurrentRingQueue.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
LinkedConcurrentRingQueue{T}()

A concurrent queue with nonblocking `push!` and [`trypopfirst!`](@ref).
A concurrent queue with nonblocking `push!` and [`maybepopfirst!`](@ref).

See also: [`DualLinkedConcurrentRingQueue`](@ref)

Expand All @@ -14,13 +14,13 @@ julia> push!(q, 111);

julia> push!(q, 222);

julia> trypopfirst!(q) # first-in first-out
julia> maybepopfirst!(q) # first-in first-out
Some(111)

julia> trypopfirst!(q)
julia> maybepopfirst!(q)
Some(222)

julia> trypopfirst!(q) === nothing # queue is empty
julia> maybepopfirst!(q) === nothing # queue is empty
true
```

Expand Down
10 changes: 5 additions & 5 deletions src/docs/WorkStealingDeque.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Concurrent work-stealing "deque" of objects of type `T`.

This is not a full deque in the sense that:

* `push!` and [`trypop!`](@ref) operating at the tail of the collection can
* `push!` and [`maybepop!`](@ref) operating at the tail of the collection can
only be executed by a single task.
* [`trypopfirst!`](@ref) (aka steal) for retrieving and removing an element at
* [`maybepopfirst!`](@ref) (aka steal) for retrieving and removing an element at
the head can be invoked from any tasks. However, there is no `pushfirst!`.

Implementation detail: It implements the dynamic circular work-stealing deque by
Expand All @@ -25,14 +25,14 @@ julia> push!(deque, 2);

julia> push!(deque, 3);

julia> trypop!(deque)
julia> maybepop!(deque)
Some(3)

julia> fetch(Threads.@spawn trypopfirst!(deque))
julia> fetch(Threads.@spawn maybepopfirst!(deque))
Some(1)

julia> fetch(Threads.@spawn popfirst!(deque))
2

julia> trypopfirst!(deque) # returns nothing
julia> maybepopfirst!(deque) # returns nothing
```
2 changes: 2 additions & 0 deletions src/docs/maybeget.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
maybeget(dict::ConcurrentDict{K,V}, key) -> Some(value::T) or nothing

6 changes: 3 additions & 3 deletions src/docs/trypop!.md → src/docs/maybepop!.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
trypop!(collection) -> Some(value::T) or nothing
maybepop!(collection) -> Some(value::T) or nothing

Try to pop a `value` from the tail of `collection`. Return `Some(value)` if it
is non-empty. Return `nothing` if empty.
Expand All @@ -12,8 +12,8 @@ julia> stack = ConcurrentStack{Int}();

julia> push!(stack, 1);

julia> trypop!(stack)
julia> maybepop!(stack)
Some(1)

julia> trypop!(stack) # returns nothing
julia> maybepop!(stack) # returns nothing
```
6 changes: 3 additions & 3 deletions src/docs/trypopfirst!.md → src/docs/maybepopfirst!.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
trypopfirst!(collection) -> Some(value::T) or nothing
maybepopfirst!(collection) -> Some(value::T) or nothing


Try to pop a `value` from the head of `collection`. Return `Some(value)` if it
Expand All @@ -13,8 +13,8 @@ julia> queue = ConcurrentQueue{Int}();

julia> push!(queue, 1);

julia> trypopfirst!(queue)
julia> maybepopfirst!(queue)
Some(1)

julia> trypopfirst!(queue) # returns nothing
julia> maybepopfirst!(queue) # returns nothing
```
2 changes: 0 additions & 2 deletions src/docs/tryget.md

This file was deleted.

8 changes: 4 additions & 4 deletions src/lcrq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function trypush!(crq::IndirectConcurrentRingQueueNode, x)
end
end

function ConcurrentCollections.trypopfirst!(crq::IndirectConcurrentRingQueueNode)
function ConcurrentCollections.maybepopfirst!(crq::IndirectConcurrentRingQueueNode)
while true
h = (@atomic crq.head += true) - true
itemindex = mod1(h, crq.length) # TODO: shift
Expand Down Expand Up @@ -261,15 +261,15 @@ function Base.push!(lcrq::LinkedConcurrentRingQueue{T}, x) where {T}
end
end

function ConcurrentCollections.trypopfirst!(lcrq::LinkedConcurrentRingQueue)
function ConcurrentCollections.maybepopfirst!(lcrq::LinkedConcurrentRingQueue)
while true
crq = @atomic lcrq.head
x = trypopfirst!(crq)
x = maybepopfirst!(crq)
x === nothing || return x
next = @atomic crq.next
next === nothing && return nothing

x = trypopfirst!(crq)
x = maybepopfirst!(crq)
x === nothing || return x
@atomicreplace lcrq.head crq => next
end
Expand Down
2 changes: 1 addition & 1 deletion src/misc.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function ConcurrentCollections.trypopfirst!(ch::Channel)
function ConcurrentCollections.maybepopfirst!(ch::Channel)
y = iterate(ch)
y === nothing && return nothing
return Some(first(y))
Expand Down
4 changes: 2 additions & 2 deletions src/msqueue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function Base.push!(queue::ConcurrentQueue{T}, v) where {T}
end
end

function ConcurrentCollections.trypopfirst!(queue::ConcurrentQueue)
function ConcurrentCollections.maybepopfirst!(queue::ConcurrentQueue)
head = @atomic queue.head
tail = @atomic queue.tail
while true
Expand Down Expand Up @@ -71,7 +71,7 @@ function ConcurrentCollections.trypopfirst!(queue::ConcurrentQueue)
end

function Base.popfirst!(queue::ConcurrentQueue)
r = trypopfirst!(queue)
r = maybepopfirst!(queue)
if r === nothing
error("queue is empty")
else
Expand Down
4 changes: 2 additions & 2 deletions src/stack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function Base.push!(stack::ConcurrentStack{T}, v) where {T}
return stack
end

function ConcurrentCollections.trypop!(stack::ConcurrentStack)
function ConcurrentCollections.maybepop!(stack::ConcurrentStack)
while true
node = @atomic stack.next
node === nothing && return nothing
Expand All @@ -39,7 +39,7 @@ function ConcurrentCollections.trypop!(stack::ConcurrentStack)
end

function Base.pop!(stack::ConcurrentStack)
r = trypop!(stack)
r = maybepop!(stack)
if r === nothing
error("stack is empty")
else
Expand Down
8 changes: 4 additions & 4 deletions src/workstealing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function Base.push!(deque::WorkStealingDeque, v)
return deque
end

function ConcurrentCollections.trypop!(deque::WorkStealingDeque)
function ConcurrentCollections.maybepop!(deque::WorkStealingDeque)
bottom = @atomic deque.bottom
buffer = @atomic deque.buffer
bottom -= 1
Expand All @@ -142,7 +142,7 @@ function ConcurrentCollections.trypop!(deque::WorkStealingDeque)
return r
end

function ConcurrentCollections.trypopfirst!(deque::WorkStealingDeque{T}) where {T}
function ConcurrentCollections.maybepopfirst!(deque::WorkStealingDeque{T}) where {T}
top = @atomic deque.top
bottom = @atomic deque.bottom
buffer = @atomic deque.buffer
Expand Down Expand Up @@ -187,7 +187,7 @@ end
# Atomics](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0690r1.html)

function Base.pop!(deque::WorkStealingDeque)
r = trypop!(deque)
r = maybepop!(deque)
if r === nothing
error("deque is empty")
else
Expand All @@ -196,7 +196,7 @@ function Base.pop!(deque::WorkStealingDeque)
end

function Base.popfirst!(deque::WorkStealingDeque)
r = trypopfirst!(deque)
r = maybepopfirst!(deque)
if r === nothing
error("deque is empty")
else
Expand Down
6 changes: 3 additions & 3 deletions test/ConcurrentCollectionsTests/src/test_crq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ function concurrent_denqueue!(
local ys_nb = Int[]
local ys_b = Int[]
while true
local y = trypopfirst!(crq)
local y = maybepopfirst!(crq)
if y === nothing
if activesenders[] == 0
y = trypopfirst!(crq)
y = maybepopfirst!(crq)
if y === nothing # Confirm that CRQ is empty
return y
end
# Reaching here means that there were some enqueues
# between our `trypopfirst!(crq) === nothing` and
# between our `maybepopfirst!(crq) === nothing` and
# `activesenders[] == 0`.
else
poll()
Expand Down
Loading