• Stars
    star
    282
  • Rank 146,549 (Top 3 %)
  • Language
    Rust
  • License
    MIT License
  • Created about 3 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

in-place allocation-reusing queues for Rust

thingbuf

"I'm at the buffer pool. I'm at the MPSC channel. I'm at the combination MPSC channel and buffer pool."

crates.io Documentation Documentation (HEAD) MIT licensed Test Status Sponsor @hawkw on GitHub Sponsors

What Is It?

thingbuf is a lock-free array-based concurrent ring buffer that allows access to slots in the buffer by reference. It's also asynchronous and blocking bounded MPSC channels implemented using the ring buffer.

When Should I Use It?

  • If you want a high-throughput bounded MPSC channel that allocates only on channel creation. Some MPSC channels have good throughput. Some other MPSC channels won't allocate memory per-waiter. thingbuf::mpsc has both. thingbuf::mpsc is a competitive choice for a general-purpose MPSC channel in most use cases.

    Both asynchronous and blocking MPSC channels are available, so thingbuf can be used in place of asynchronous channels like futures::channel::mpsc and blocking channels like std::sync::mpsc::sync_channel.

  • If you can't allocate or you need to build with #![no_std] because you're working on embedded systems or other bare-metal software. Thingbuf provides a statically-allocated MPSC channel and a statically-allocated lock-free queue. These can be placed in a static initializer and used without requiring any runtime allocations.

  • You want to use the same MPSC channel with and without std . Thingbuf's asynchronous MPSC channel provides an identical API and feature set regardless of whether or not the "std" feature flag is enabled. If you're writing a library that needs to conditionally support #![no_std], and you need an asynchronous MPSC channel, it might be easier to use thingbuf::mpsc in both cases, rather than switching between separate std and #![no_std] channel implementations.

When Shouldn't I Use It?

It's equally important to discuss when thingbuf should not be used. Here are some cases where you might be better off considering other options:

  • You need a really, really, absurdly high bound and you're not going to be near it most of the time. If you want to set a very, very high bound on a bounded MPSC channel, and the channel will typically never be anywhere near that full, thingbuf::mpsc might not be the best choice.

    Thingbuf's channels will allocate an array with length equal to the capacity as soon as they're constructed. This improves performance by avoiding additional allocations, but if you need to set very high bounds, you might prefer a channel implementation that only allocates memory for messages as it's needed (such as tokio::sync::mpsc).

  • You need a blocking channel with a select operation. I'm probably not going to implement it. I may accept a PR if you raise it.

    If you need a synchronous channel with this kind of functionality, crossbeam-channel is probably a good choice.

  • You want an unbounded channel. I'm not going to write an unbounded channel. Unbounded channels are evil.

Terminology

This crate's API and documentation makes a distinction between the terms "queue" and "channel". The term queue will refer to the queue abstract data type in general — any first-in, first-out data structure is a queue.

The term channel will refer to a subtype of concurrent queue that also functions as a synchronization primitive. A channel is a queue which can be shared between multiple threads or asynchronous tasks, and which allows those threads or tasks to wait for elements to be added or removed from the queue.

In the Rust standard library, the std::collections::VecDeque type is an example of a queue that is not a channel: it is a first-in, first-out data structure, but it cannot be concurrently enqueued to and dequeued from by multiple threads or tasks. In comparison, the types in the std::sync::mpsc module provide a prototypical example of channels, as they serve as synchronization primitives for cross-thread communication.

Usage

To get started using thingbuf, add the following to your Cargo.toml:

[dependencies]
thingbuf = "0.1"

By default, thingbuf depends on the Rust standard library, in order to implement APIs such as synchronous (blocking) channels. In #![no_std] projects, the std feature flag must be disabled:

[dependencies]
thingbuf = { version = "0.1", default-features = false }

With the std feature disabled, thingbuf will depend only on libcore. This means that APIs that require dynamic memory allocation will not be enabled. Statically allocated channels and queues are available for code without a memory allocator, if the static feature flag is enabled:

[dependencies]
thingbuf = { version = "0.1", default-features = false, features = ["static"] }

However, if a memory allocator is available, #![no_std] code can also enable the alloc feature flag to depend on liballoc:

[dependencies]
thingbuf = { version = "0.1", default-features = false, features = ["alloc"] }

Crate Feature Flags

  • std (Enabled by default): Enables features that require the Rust standard library, such as synchronous (blocking) channels. This implicitly enables the "alloc" feature flag.
  • alloc: Enables features that require liballoc (but not libstd). This enables thingbuf queues and asynchronous channels where the size of the channel is determined at runtime.
  • static (Disabled by default, requires Rust 1.59+): Enables the static (const-generic-based) thingbuf queues and channels. These can be used without dynamic memory allocation when the size of a queue or channel is known at compile-time.

Compiler Support

thingbuf is built against the latest stable release. The minimum supported version is Rust 1.57. The current thingbuf version is not guaranteed to build on Rust versions earlier than the minimum supported version.

Some feature flags may require newer Rust releases. For example, the "static" feature flag requries Rust 1.60+.

FAQs

  • Q: Why did you make this?

    A: For tracing, I wanted to be able to send formatted log lines to a dedicated worker thread that writes them to a file. Right now, we do this using crossbeam-channel. However, this has the sad disadvantage that we have to allocate Strings, send them through the channel to the writer, and immediately drop them. It would be nice to do this while reusing those allocations. Thus...StringBuf.

  • Q: Is it lock-free?

    A: Extremely.

  • Q: Why is there only a bounded variant?

    A: Because unbounded queues are of the Devil.

  • Q: Isn't this just a giant memory leak?

    A: If you use it wrong, yes.

  • Q: Why is it called that?

    A: Originally, I imagined it as a kind of ring buffer, so (as a pun on "ringbuf"), I called it "stringbuf". Then, I realized you could do this with more than just strings. In fact, it can be generalized to arbitrary...things. So, "thingbuf".

More Repositories

1

mycelium

🍄 an alleged 'operating system'
Rust
532
star
2

tinymetrics

a minimal, allocation-free Prometheus/OpenMetrics metrics implementation for `no-std` and embedded Rust.
Rust
300
star
3

sharded-slab

a lock-free concurrent slab (experimental)
Rust
268
star
4

seax

A VM-based runtime environment for functional programming languages
Rust
45
star
5

mnemosyne

A functional systems programming language with compile-time memory management
Rust
30
star
6

async-workshop

Rust
21
star
7

dotfiles

my dot files
Shell
19
star
8

decaf

like Java, but less so
Scala
17
star
9

tokio-trace-prototype

Rust
16
star
10

flake

eliza's entire computer: the git repo
Nix
16
star
11

eclss

Environmental Controls and Life Support Systems
Rust
14
star
12

matchers

Rust
11
star
13

seax_svm

Seax Virtual Machine
Rust
9
star
14

eliza_error

Rust
7
star
15

homebrew-x86_64-pc-elf

Homebrew formulae to install the x86_64-pc-elf cross compiler toolchain.
Ruby
7
star
16

multipass

yes, she knows it's a multipass. anyway, we're in love.
Rust
7
star
17

seax_scheme

Seax Scheme compiler
Rust
6
star
18

traverse

Doing science with filesystem traversal!
Python
6
star
19

tokio-trace

Rust
6
star
20

natatorium

"natatorium" is a fancy word for "swimming pool"
Rust
5
star
21

segvec

Rust
5
star
22

henrys_thing

a thing 4 henry
Rust
5
star
23

recipes

programs for making food!
4
star
24

async-cancel

fast, cheap, and out of control task cancelation
Rust
4
star
25

l-systems

L-Systems fun in Scala and Processing
Scala
3
star
26

hyper-compress

Compression middleware for Hyper
Rust
3
star
27

Orbit

Minimal SublimeText colorschemes intended for use with the Spacegray UI.
3
star
28

dtab.rs

a Rust library for parsing and constructing Finagle/Linkerd delegation tables
Rust
3
star
29

sqlviz

Quick SQL schema analysis & visualization in Python
Python
3
star
30

lin

Generic linear algebra in Rust
Rust
3
star
31

prologue

is_prolog(prologue) :- true
Rust
3
star
32

homebrew-grub

Homebrew tap for building GRUB
Ruby
3
star
33

grist

a simple Git web service in Rust
Rust
2
star
34

vupdaters

Streacom VU-Dials utilities
Rust
2
star
35

huffman.rs

A full-featured Huffman coding implementation in Rust
Rust
2
star
36

cargo-hell

hubris torment nexus
Rust
2
star
37

FitLine

FitBit analytics in PyLab
Python
2
star
38

tower-breaker

tower circuit-breaking experiments
Rust
2
star
39

advent-code

Haskell
2
star
40

seax_util

General purpose bits for compilers targeting the Seax platform
Rust
2
star
41

deebee

A tiny database
Scala
2
star
42

USL

USL is the Useless Stack Language - a toy stack-based language implemented by Hawk Weisman and Max Clive for Computer Science 420 at Allegheny College.
TeX
2
star
43

eclss-nostd

Environmental Control and Life Support Systems
Rust
2
star
44

floating-pointless

software floating-point arithmetic in Rust (for educational purposes only)
Rust
1
star
45

cordyceps

Rust intrusive collections library
1
star
46

snapmap

Rust
1
star
47

haskell-common

General-purpose Haskell code, mostly for practice
Haskell
1
star
48

rush

bad shell do not use
Rust
1
star
49

cs382-final

Final project for Computer Science 382: Visual Computing at Allegheny College.
Rust
1
star
50

CS111

CS111 junk
Java
1
star
51

weathergirl-rs

Rust
1
star
52

pyANOVA

Python command-line statistics tools, just for fun.
Python
1
star
53

unstable-macros

macros to reduce the boilerplate of conditionally supporting unstable Rust
Rust
1
star
54

cargo-loom

a Cargo command for running `loom` tests
Rust
1
star
55

old-dotfiles

my dot files
Python
1
star
56

tokio-fswatch

Rust
1
star
57

locality

Rust
1
star
58

CMPSC440

Computer Science 440 at Allegheny College
Java
1
star
59

JForthEngine

A simple Forth Virtual Machine in Java.
Java
1
star
60

hacktor

a secret thing
Rust
1
star
61

scala-common

General-purpose Scala code bits
Scala
1
star
62

DunGen

A quick 2D dungeon generator for roguelikes and such
Scala
1
star
63

ionesco

libraries for Scala and JavaScript interoperation
Scala
1
star
64

map_ext.rs

Extensions to Rust's std::collections::HashMap and std::collections::BTreeMap.
Rust
1
star
65

carrden

Carrden web app project
HTML
1
star
66

sen5x-rs

Rust
1
star
67

homebrew-cross

Ruby
1
star
68

routekicking

linkerd HTTPRoute policy tire-kicking
1
star
69

MIPSCodeGeneration

Experiments with code generation in C and MIPS. Currently targeting the MARSBot graphics turtle that ships with MARS4.4, may later add code generation for other applications.
Assembly
1
star
70

line-filter

a `tracing` filter for enabling individual events by line
Rust
1
star
71

weathergirl

a cute little arduino weather station
C++
1
star
72

breadplan

A simple Python script to generate baking plans for the recipes in Tartine Bread
Mathematica
1
star
73

senior-thesis

TeX
1
star
74

hawkw.github.io

CSS
1
star
75

thoughts

A place to collect notes and ideas.
1
star
76

scattergather

utilities to help make vectored IO easy
Rust
1
star
77

futures-log

A logging wrapper around Rust Futures and Streams, to help with debugging
Rust
1
star
78

lazy

Rust
1
star
79

Sieve

Contains an implementation of the Sieve of Eratosthenes in Java and C for CMPSC220 Lab 1
Java
1
star
80

tokio-buffer-repro

Rust
1
star