jepsen.generator.context

Generators work with an immutable context that tells them what time it is, what processes are available, what process is executing which thread and vice versa, and so on. We need an efficient, high-performance data structure to track this information. This namespace provides that data structure, and functions to alter it.

Contexts are intended not only for managing generator-relevant state about active threads and so on; they also can store arbitrary contextual information for generators. For instance, generators may thread state between invocations or layers of the generator stack. To do this, contexts also behave like Clojure maps. They have a single special key, :time; all other keys are available for your use.

all-but

(all-but x)

One thing we do often, and which is expensive, is stripping out the nemesis from the set of active threads using (complement #{:nemesis}). This type encapsulates that notion of “all but x”, and allows us to specialize some expensive functions for speed.

all-processes

(all-processes ctx)

Given a context, returns a Bifurcan ISet of all processes currently belonging to some thread.

all-thread-count

(all-thread-count ctx)

How many threads are in the given context, total?

all-threads

(all-threads ctx)

Given a context, returns a Bifurcan ISet of all threads in it.

busy-thread

(busy-thread this time thread)

Returns context with the given time, and the given thread no longer free.

context

(context test)

Constructs a fresh Context for a test. Its initial time is 0. Its threads are the integers from 0 to (:concurrency test), plus a :nemesis). Every thread is free. Each initially runs itself as a process.

free-processes

(free-processes ctx)

Given a context, returns a collection of processes which are not actively processing an invocation.

free-thread

(free-thread this time thread)

Returns context with the given time, and the given thread free.

free-thread-count

(free-thread-count ctx)

How many threads are free in the given context?

free-threads

(free-threads ctx)

Given a context, returns a Bifurcan ISet of threads which are not actively processing an invocation.

intersect-bitsets

(intersect-bitsets a b)

Intersects one bitset with another, immutably.

make-thread-filter

(make-thread-filter pred)(make-thread-filter pred ctx)

We often want to restrict a context to a specific subset of threads matching some predicate. We want to do this a lot. To make this fast, we can pre-compute a function which does this restriction more efficiently than doing it at runtime.

Call this with a context and a predicate, and it’ll construct a function which restricts any version of that context (e.g. one with the same threads, but maybe a different time or busy state) to just threads matching the given predicate.

Don’t have a context handy? Pass this just a predicate, and it’ll construct a filter which lazily compiles itself on first invocation, and is fast thereafter.

process->thread

(process->thread ctx process)

Given a process, looks up which thread is executing it.

some-free-process

(some-free-process ctx)

Given a context, returns a random free process, or nil if all are busy.

thread->process

(thread->process ctx thread)

Given a thread, looks up which process it’s executing.

thread-free?

(thread-free? ctx thread)

Is the given thread free?

with-next-process

(with-next-process ctx thread)

Replaces a thread’s process with a new one.