[package]
name = "takeaway"
authors = ["arya dradjica <uhe8ob7m71igsl1d@bal-e.org>"]
description = "An efficient work-stealing task queue with prioritization and batching."
license = "MIT OR Apache-2.0"

version = "0.1.1"
edition = "2024"
rust-version = "1.91.0"

homepage = "https://codeberg.org/bal-e/takeaway"
repository = "https://codeberg.org/bal-e/takeaway"
keywords = ["task-scheduling", "work-stealing", "data-structures"]
categories = ["concurrency", "data-structures", "no-std"]

[package.metadata.docs.rs]
all-features = true

[features]
default = ["std"]

# Enable dependence on the Rust standard library.
std = ["crossbeam-utils?/std"]

# Depend on 'crossbeam-utils' instead of using the copied 'Backoff' and
# 'CachePadded' implementations.  This should be selected if 'crossbeam-utils'
# is already present in the dependency graph.
crossbeam-utils = ["dep:crossbeam-utils"]

# - 'takeaway' needs to pad atomic variables to cache lines for efficiency.
# - 'takeaway' needs to use exponential backoff when waiting on some concurrent
#   operations on other threads to occur.
#
# 'crossbeam-utils' provides 'CachePadded' and 'Backoff' for these purposes.
# It provides a lot of additional functionality that 'takeaway' doesn't need, so
# the required code was copied into 'takeaway' to eliminate the dependency.  If
# the 'crossbeam-utils' feature is enabled, the dependency will be used anyway.
#
# All crates that can serve this role:
#
# - 'cache_padded': has been deprecated in favor of 'crossbeam_utils'.
#
# - 'backoff' is noted on 'lib.rs' as being unmaintained.
#
# - 'exponential_backoff' is intended for backing off from network operations,
#   not atomic operations, and adds more dependencies.
#
# - 'amity' serves a similar role to 'crossbeam_utils', but doesn't currently
#   see significant use (2025-06-22) and adds more dependencies.
#
# - 'crossbeam_utils' is a dependency-free, no-std crate providing the necessary
#   types, along with several other common concurrency needs.
#   
#   'crossbeam' is a popular crate and it is reasonable to assume it will be
#   maintained for the forseeable future.  It has existed since 2017 or before
#   and 'crossbeam-utils' sees ~15M downloads per month (2025-06-21).  It still
#   uses unstable version numbering and occasionally sees breaking changes; but
#   given the massive usage base, breaking changes should not be likely.
#
# Current decision: copy the required code into 'takeaway', but allow (via a
# feature flag) 'crossbeam-utils' to be used directly.
[dependencies.crossbeam-utils]
version = "0.8"
optional = true
default-features = false
features = []

# 'atomig' provides an 'Atom' trait, representing types that can be encoded as
# primitive atomic variables.  'takeaway' needs this for constraining the types
# of priorities user-provided tasks can have, as they will be used atomically in
# the global data structure.
#
# All crates that can serve this role:
# 
# - 'crossbeam_utils::AtomicCell': It would be possible to replace `<T: Atom>`
#   with `<T>` and `const { assert!(<AtomicCell<T>>::is_lock_free()) }`.  It's
#   a bit less ergonomic, but it's a valid replacement.
#
#   'crossbeam' is a popular crate and it is reasonable to assume it will be
#   maintained for the forseeable future.  It has existed since 2017 or before
#   and 'crossbeam-utils' sees ~15M downloads per month (2025-06-21).  It still
#   uses unstable version numbering and occasionally sees breaking changes; but
#   given the massive usage base, breaking changes should not be likely.
#
#   As per #315 [^1], padding bytes in an 'AtomicCell' might cause UB.  It is
#   unclear whether this was fixed, but it appears 'atomic-maybe-uninit' was
#   developed in response to this problem.
#
#   [^1]: https://github.com/crossbeam-rs/crossbeam/issues/315
#
# - 'atomic_maybe_uninit::AtomicMaybeUninit' is generic and is bounded by a
#   'raw::Primitive' trait that could be used in place of 'Atom'.  It is less
#   flexible but good enough for our use case.
#
#   'atomic_maybe_uninit' is maintained by ~taki-e.  They are a well-known Rust
#   developer and have written many essential crates for the Rust ecosystem, for
#   example 'pin-project'.  They do not appear to be looking for funding, but
#   'atomic_maybe_uninit' sees very little use, and they might prioritize more
#   popular and important crates over it.  While it has seen recent development
#   (2025-06-21), it has seen (almost) no external contribution.  It has not yet
#   reached a stable version number.
#
# - 'portable_atomic' does not provide any traits to fill this use case, and the
#   additional functionality it offers over 'std' does not appear relevant to
#   this use case.
#
# - 'atomig::Atom' fits the required use case, and offers additional flexibility
#   (that does benefit the use case) by allowing user-defined conversions to and
#   from the underlying atomic representation.
#
#   'atomig' is maintained by 'Lukaskalbertodt'.  They are a 'rust-lang' team
#   member, and manage some other interesting Rust crates.  They do not appear
#   to be looking for funding, and in fact are sponsporing some developers.
#   'atomig' sees ~30K downloads per month, but is used in very few crates; the
#   most prominent is 'rav1d'.  'atomig' has not yet reached a stable version,
#   and has been in development since 2020.  However, its API does not appear
#   to have changed significantly over its development.
# 
[dependencies.atomig]
version = "0.4.3"
default-features = false
features = []

# 'atomic-wait' is a portable generalization of Linux's futexes, allowing a
# thread to block on an atomic 32-bit value to change.  This is important for
# manually implementing concurrent data structures that are not (currently)
# lock-free, like the task queue.
#
# - 'rustix' provides a decent API over Linux-specific functionality, including
#   system calls.  It provides futexes on Linux, but does not support equivalent
#   functionality for Windows.  It also quite a large crate.
#
# - 'atomic-wait' is portable, and provides a cross-section of functionality
#   that is suitable for the task queue implementation here.  It is a small,
#   no-std crate, and only 150 lines of code.
#
#   'atomic-wait' is maintained by Mara Bos.  She is a major Rust contributor,
#   and is currently the head of the library team.  The project has seen some
#   contributions from others, and appears to be kept relatively up-to-date.
#   Even if there were concerns about its maintenance, it would be trivial to
#   fork and maintain, given its limited scope and code size.
#
[dependencies.atomic-wait]
version = "1.0"

[dev-dependencies]
rand = "0.9.1"
crossbeam-deque = "0.8.6"
criterion = "0.7.0"

[[bench]]
name = "manual"
harness = false

[[bench]]
name = "criterion"
harness = false
