Liking cljdoc? Tell your friends :D

clj-ebpf.refs

Idiomatic Clojure references for BPF data structures.

This namespace provides Clojure reference types that implement standard protocols (IDeref, IBlockingDeref, IAtom, ITransientCollection), enabling natural use of @, deref, reset!, swap!, and conj! with BPF maps.

== Read-Only References ==

  1. RingBufRef - Blocking reads from ring buffers @ref ; blocks until event available (deref ref 1000 nil) ; 1s timeout

  2. QueueRef/StackRef - Blocking pops from queue/stack maps @ref ; blocks until item available

  3. MapWatcher - Watch for a key to appear/change @ref ; blocks until key exists

== Writable References ==

  1. MapEntryRef - Atom-like access to map entries @ref ; read value (reset! ref val) ; write value (swap! ref inc) ; read-modify-write

  2. QueueWriter/StackWriter - Push to queues/stacks (conj! ref val) ; push value @ref ; peek (non-blocking)

  3. QueueChannel/StackChannel - Bidirectional access (conj! ref val) ; push @ref ; blocking pop

Idiomatic Clojure references for BPF data structures.

This namespace provides Clojure reference types that implement standard
protocols (IDeref, IBlockingDeref, IAtom, ITransientCollection), enabling
natural use of @, deref, reset!, swap!, and conj! with BPF maps.

== Read-Only References ==

1. RingBufRef - Blocking reads from ring buffers
   @ref                    ; blocks until event available
   (deref ref 1000 nil)    ; 1s timeout

2. QueueRef/StackRef - Blocking pops from queue/stack maps
   @ref                    ; blocks until item available

3. MapWatcher - Watch for a key to appear/change
   @ref                    ; blocks until key exists

== Writable References ==

4. MapEntryRef - Atom-like access to map entries
   @ref                    ; read value
   (reset! ref val)        ; write value
   (swap! ref inc)         ; read-modify-write

5. QueueWriter/StackWriter - Push to queues/stacks
   (conj! ref val)         ; push value
   @ref                    ; peek (non-blocking)

6. QueueChannel/StackChannel - Bidirectional access
   (conj! ref val)         ; push
   @ref                    ; blocking pop
raw docstring

map-entry-refclj

(map-entry-ref bpf-map key & {:keys [validator]})

Create an atom-like reference to a specific key in a BPF map.

Supports standard Clojure atom operations:

  • @ref / (deref ref) - read current value
  • (reset! ref val) - set new value
  • (swap! ref f) - read-modify-write
  • (compare-and-set! ref old new) - conditional update

Note: swap! and compare-and-set! are NOT truly atomic at the kernel level for hash maps. For true atomicity with concurrent BPF programs, use atomic BPF map operations within the BPF program itself.

Options:

  • :validator - Function to validate new values (throws on invalid)

Example: (let [counter (map-entry-ref stats-map :packet-count)] ;; Read (println "Count:" @counter)

;; Write
(reset! counter 0)

;; Read-modify-write
(swap! counter inc)
(swap! counter + 10)

(.close counter))
Create an atom-like reference to a specific key in a BPF map.

Supports standard Clojure atom operations:
- @ref / (deref ref) - read current value
- (reset! ref val) - set new value
- (swap! ref f) - read-modify-write
- (compare-and-set! ref old new) - conditional update

Note: swap! and compare-and-set! are NOT truly atomic at the kernel level
for hash maps. For true atomicity with concurrent BPF programs, use
atomic BPF map operations within the BPF program itself.

Options:
- :validator - Function to validate new values (throws on invalid)

Example:
  (let [counter (map-entry-ref stats-map :packet-count)]
    ;; Read
    (println "Count:" @counter)

    ;; Write
    (reset! counter 0)

    ;; Read-modify-write
    (swap! counter inc)
    (swap! counter + 10)

    (.close counter))
sourceraw docstring

map-watchclj

(map-watch bpf-map key & {:keys [poll-interval-ms] :or {poll-interval-ms 10}})

Create a deref-able watcher for a specific key in a BPF map.

The returned reference blocks until the key has a value:

@ref ; blocks until key exists in map (deref ref 1000 nil) ; waits up to 1000ms, returns nil on timeout

Options:

  • :poll-interval-ms - How often to check the map (default: 10ms)

Example: ;; Wait for a counter to be initialized (let [watcher (map-watch stats-map :packet-count)] (try (let [initial-count (deref watcher 5000 0)] (println "Initial count:" initial-count)) (finally (.close watcher))))

Create a deref-able watcher for a specific key in a BPF map.

The returned reference blocks until the key has a value:

  @ref                    ; blocks until key exists in map
  (deref ref 1000 nil)    ; waits up to 1000ms, returns nil on timeout

Options:
- :poll-interval-ms - How often to check the map (default: 10ms)

Example:
  ;; Wait for a counter to be initialized
  (let [watcher (map-watch stats-map :packet-count)]
    (try
      (let [initial-count (deref watcher 5000 0)]
        (println "Initial count:" initial-count))
      (finally
        (.close watcher))))
sourceraw docstring

map-watch-changesclj

(map-watch-changes bpf-map
                   key
                   &
                   {:keys [poll-interval-ms initial-value]
                    :or {poll-interval-ms 10 initial-value nil}})

Create a watcher that blocks until a map value changes.

Unlike map-watch which returns when any value exists, this watcher only returns when the value differs from the last observed value.

@ref ; blocks until value changes (deref ref 1000 nil) ; waits up to 1000ms for change

Options:

  • :poll-interval-ms - How often to check the map (default: 10ms)
  • :initial-value - Consider this the 'last' value initially

Example: ;; Watch for counter updates (let [watcher (map-watch-changes stats-map :counter)] (try (loop [count 0] (when (< count 10) (let [new-val @watcher] (println "Counter changed to:" new-val) (recur (inc count))))) (finally (.close watcher))))

Create a watcher that blocks until a map value changes.

Unlike map-watch which returns when any value exists, this watcher
only returns when the value differs from the last observed value.

  @ref                    ; blocks until value changes
  (deref ref 1000 nil)    ; waits up to 1000ms for change

Options:
- :poll-interval-ms - How often to check the map (default: 10ms)
- :initial-value - Consider this the 'last' value initially

Example:
  ;; Watch for counter updates
  (let [watcher (map-watch-changes stats-map :counter)]
    (try
      (loop [count 0]
        (when (< count 10)
          (let [new-val @watcher]
            (println "Counter changed to:" new-val)
            (recur (inc count)))))
      (finally
        (.close watcher))))
sourceraw docstring

queue-channelclj

(queue-channel bpf-map & {:keys [poll-interval-ms] :or {poll-interval-ms 10}})

Create a bidirectional channel-like reference to a BPF queue.

Combines reading and writing:

  • @ref / (deref ref timeout val) - blocking pop (FIFO)
  • (conj! ref val) - push to queue

This is useful for producer-consumer patterns where userspace both reads and writes to the same queue.

Options:

  • :poll-interval-ms - How often to poll when waiting (default: 10ms)

Example: (let [ch (queue-channel work-queue)] ;; Producer thread (future (dotimes [i 100] (conj! ch {:task i})))

;; Consumer thread
(future
  (loop []
    (when-let [task (deref ch 5000 nil)]
      (process task)
      (recur))))

(.close ch))
Create a bidirectional channel-like reference to a BPF queue.

Combines reading and writing:
- @ref / (deref ref timeout val) - blocking pop (FIFO)
- (conj! ref val) - push to queue

This is useful for producer-consumer patterns where userspace
both reads and writes to the same queue.

Options:
- :poll-interval-ms - How often to poll when waiting (default: 10ms)

Example:
  (let [ch (queue-channel work-queue)]
    ;; Producer thread
    (future
      (dotimes [i 100]
        (conj! ch {:task i})))

    ;; Consumer thread
    (future
      (loop []
        (when-let [task (deref ch 5000 nil)]
          (process task)
          (recur))))

    (.close ch))
sourceraw docstring

queue-refclj

(queue-ref bpf-map & {:keys [poll-interval-ms] :or {poll-interval-ms 10}})

Create a deref-able reference to a queue map.

The returned reference supports blocking pop operations via deref:

@ref ; blocks until item available (FIFO pop) (deref ref 1000 nil) ; waits up to 1000ms, returns nil on timeout

Options:

  • :poll-interval-ms - How often to check for items (default: 10ms)

Example: (let [ref (queue-ref my-queue)] (try (loop [] (when-let [item @ref] (process item) (recur))) (finally (.close ref))))

Create a deref-able reference to a queue map.

The returned reference supports blocking pop operations via deref:

  @ref                    ; blocks until item available (FIFO pop)
  (deref ref 1000 nil)    ; waits up to 1000ms, returns nil on timeout

Options:
- :poll-interval-ms - How often to check for items (default: 10ms)

Example:
  (let [ref (queue-ref my-queue)]
    (try
      (loop []
        (when-let [item @ref]
          (process item)
          (recur)))
      (finally
        (.close ref))))
sourceraw docstring

queue-seqclj

(queue-seq ref
           &
           {:keys [timeout-ms timeout-val]
            :or {timeout-ms Long/MAX_VALUE timeout-val :clj-ebpf.refs/timeout}})

Returns a lazy sequence that pops items from a queue.

Each element retrieval blocks until an item is available.

Options:

  • :timeout-ms - Timeout for each pop (default: infinite)
  • :timeout-val - Value returned on timeout (stops sequence if ::timeout)

Example: (let [ref (queue-ref my-queue)] (try (doseq [item (take 50 (queue-seq ref))] (process item)) (finally (.close ref))))

Returns a lazy sequence that pops items from a queue.

Each element retrieval blocks until an item is available.

Options:
- :timeout-ms - Timeout for each pop (default: infinite)
- :timeout-val - Value returned on timeout (stops sequence if ::timeout)

Example:
  (let [ref (queue-ref my-queue)]
    (try
      (doseq [item (take 50 (queue-seq ref))]
        (process item))
      (finally
        (.close ref))))
sourceraw docstring

queue-writerclj

(queue-writer bpf-map)

Create a writable reference to a BPF queue map.

Supports conj! for adding items:

  • (conj! ref val) - push value to queue (enqueue)
  • @ref - peek at front value without removing

For blocking pop, use queue-ref instead.

Example: (let [q (queue-writer my-queue)] ;; Add items (-> q (conj! {:event :start}) (conj! {:event :data :value 42}) (conj! {:event :end}))

;; Peek (non-blocking)
(println "Front:" @q)

(.close q))
Create a writable reference to a BPF queue map.

Supports conj! for adding items:
- (conj! ref val) - push value to queue (enqueue)
- @ref - peek at front value without removing

For blocking pop, use queue-ref instead.

Example:
  (let [q (queue-writer my-queue)]
    ;; Add items
    (-> q
        (conj! {:event :start})
        (conj! {:event :data :value 42})
        (conj! {:event :end}))

    ;; Peek (non-blocking)
    (println "Front:" @q)

    (.close q))
sourceraw docstring

ringbuf-refclj

(ringbuf-ref ringbuf-map & {:keys [deserializer] :or {deserializer identity}})

Create a deref-able reference to a ring buffer.

The returned reference supports the @ reader macro for blocking reads:

@ref ; blocks indefinitely until event available (deref ref 1000 nil) ; waits up to 1000ms, returns nil on timeout

Options:

  • :deserializer - Function to transform raw event bytes (default: identity)

The reference must be closed when done to release resources:

(.close ref)

Example: (let [ref (ringbuf-ref my-ringbuf :deserializer parse-event)] (try (loop [] (when-let [event (deref ref 5000 nil)] (process event) (recur))) (finally (.close ref))))

Create a deref-able reference to a ring buffer.

The returned reference supports the @ reader macro for blocking reads:

  @ref                    ; blocks indefinitely until event available
  (deref ref 1000 nil)    ; waits up to 1000ms, returns nil on timeout

Options:
- :deserializer - Function to transform raw event bytes (default: identity)

The reference must be closed when done to release resources:

  (.close ref)

Example:
  (let [ref (ringbuf-ref my-ringbuf :deserializer parse-event)]
    (try
      (loop []
        (when-let [event (deref ref 5000 nil)]
          (process event)
          (recur)))
      (finally
        (.close ref))))
sourceraw docstring

ringbuf-seqclj

(ringbuf-seq ref
             &
             {:keys [timeout-ms timeout-val]
              :or {timeout-ms Long/MAX_VALUE
                   timeout-val :clj-ebpf.refs/timeout}})

Returns a lazy sequence of ring buffer events.

Each call to the sequence blocks until an event is available. The sequence is infinite - use take or other limiting functions.

Options:

  • :deserializer - Function to transform raw event bytes
  • :timeout-ms - Timeout for each read (default: infinite)
  • :timeout-val - Value returned on timeout (stops sequence if nil)

Example: ;; Process 100 events (let [ref (ringbuf-ref my-ringbuf)] (try (doseq [event (take 100 (ringbuf-seq ref))] (process event)) (finally (.close ref))))

;; With timeout - sequence ends on timeout (doseq [event (ringbuf-seq ref :timeout-ms 5000)] (process event))

Returns a lazy sequence of ring buffer events.

Each call to the sequence blocks until an event is available.
The sequence is infinite - use take or other limiting functions.

Options:
- :deserializer - Function to transform raw event bytes
- :timeout-ms - Timeout for each read (default: infinite)
- :timeout-val - Value returned on timeout (stops sequence if nil)

Example:
  ;; Process 100 events
  (let [ref (ringbuf-ref my-ringbuf)]
    (try
      (doseq [event (take 100 (ringbuf-seq ref))]
        (process event))
      (finally
        (.close ref))))

  ;; With timeout - sequence ends on timeout
  (doseq [event (ringbuf-seq ref :timeout-ms 5000)]
    (process event))
sourceraw docstring

stack-channelclj

(stack-channel bpf-map & {:keys [poll-interval-ms] :or {poll-interval-ms 10}})

Create a bidirectional channel-like reference to a BPF stack.

Combines reading and writing:

  • @ref / (deref ref timeout val) - blocking pop (LIFO)
  • (conj! ref val) - push to stack

Options:

  • :poll-interval-ms - How often to poll when waiting (default: 10ms)

Example: (let [ch (stack-channel undo-stack)] ;; Push operations (conj! ch {:action :insert :pos 0 :text "Hello"}) (conj! ch {:action :insert :pos 5 :text " World"})

;; Pop to undo (LIFO)
(let [last-op @ch]
  (undo last-op))

(.close ch))
Create a bidirectional channel-like reference to a BPF stack.

Combines reading and writing:
- @ref / (deref ref timeout val) - blocking pop (LIFO)
- (conj! ref val) - push to stack

Options:
- :poll-interval-ms - How often to poll when waiting (default: 10ms)

Example:
  (let [ch (stack-channel undo-stack)]
    ;; Push operations
    (conj! ch {:action :insert :pos 0 :text "Hello"})
    (conj! ch {:action :insert :pos 5 :text " World"})

    ;; Pop to undo (LIFO)
    (let [last-op @ch]
      (undo last-op))

    (.close ch))
sourceraw docstring

stack-refclj

(stack-ref bpf-map & {:keys [poll-interval-ms] :or {poll-interval-ms 10}})

Create a deref-able reference to a stack map.

The returned reference supports blocking pop operations via deref:

@ref ; blocks until item available (LIFO pop) (deref ref 1000 nil) ; waits up to 1000ms, returns nil on timeout

Options:

  • :poll-interval-ms - How often to check for items (default: 10ms)

Example: (let [ref (stack-ref my-stack)] (try (when-let [item (deref ref 5000 :empty)] (process item)) (finally (.close ref))))

Create a deref-able reference to a stack map.

The returned reference supports blocking pop operations via deref:

  @ref                    ; blocks until item available (LIFO pop)
  (deref ref 1000 nil)    ; waits up to 1000ms, returns nil on timeout

Options:
- :poll-interval-ms - How often to check for items (default: 10ms)

Example:
  (let [ref (stack-ref my-stack)]
    (try
      (when-let [item (deref ref 5000 :empty)]
        (process item))
      (finally
        (.close ref))))
sourceraw docstring

stack-writerclj

(stack-writer bpf-map)

Create a writable reference to a BPF stack map.

Supports conj! for adding items:

  • (conj! ref val) - push value to stack
  • @ref - peek at top value without removing

For blocking pop, use stack-ref instead.

Example: (let [s (stack-writer my-stack)] ;; Push items (conj! s :first) (conj! s :second) (conj! s :third)

;; Peek (non-blocking)
(println "Top:" @s)  ; => :third

(.close s))
Create a writable reference to a BPF stack map.

Supports conj! for adding items:
- (conj! ref val) - push value to stack
- @ref - peek at top value without removing

For blocking pop, use stack-ref instead.

Example:
  (let [s (stack-writer my-stack)]
    ;; Push items
    (conj! s :first)
    (conj! s :second)
    (conj! s :third)

    ;; Peek (non-blocking)
    (println "Top:" @s)  ; => :third

    (.close s))
sourceraw docstring

with-map-entry-refcljmacro

(with-map-entry-ref [binding bpf-map key & opts] & body)

Create a map entry reference with automatic cleanup.

Example: (with-map-entry-ref [counter stats-map :packet-count] (println "Before:" @counter) (swap! counter inc) (println "After:" @counter))

Create a map entry reference with automatic cleanup.

Example:
  (with-map-entry-ref [counter stats-map :packet-count]
    (println "Before:" @counter)
    (swap! counter inc)
    (println "After:" @counter))
sourceraw docstring

with-map-watchercljmacro

(with-map-watcher [binding bpf-map key & opts] & body)

Create a map watcher with automatic cleanup.

Example: (with-map-watcher [w stats-map :packet-count] (println "Packets:" @w))

Create a map watcher with automatic cleanup.

Example:
  (with-map-watcher [w stats-map :packet-count]
    (println "Packets:" @w))
sourceraw docstring

with-queue-channelcljmacro

(with-queue-channel [binding queue-map & opts] & body)

Create a queue channel with automatic cleanup.

Example: (with-queue-channel [ch work-queue] (conj! ch {:task :process}) (let [result @ch] (handle result)))

Create a queue channel with automatic cleanup.

Example:
  (with-queue-channel [ch work-queue]
    (conj! ch {:task :process})
    (let [result @ch]
      (handle result)))
sourceraw docstring

with-queue-refcljmacro

(with-queue-ref [binding queue-map & opts] & body)

Create a queue reference with automatic cleanup.

Example: (with-queue-ref [ref my-queue] (when-let [item (deref ref 5000 nil)] (process item)))

Create a queue reference with automatic cleanup.

Example:
  (with-queue-ref [ref my-queue]
    (when-let [item (deref ref 5000 nil)]
      (process item)))
sourceraw docstring

with-queue-writercljmacro

(with-queue-writer [binding queue-map] & body)

Create a queue writer with automatic cleanup.

Example: (with-queue-writer [q my-queue] (conj! q {:event :start}) (conj! q {:event :end}))

Create a queue writer with automatic cleanup.

Example:
  (with-queue-writer [q my-queue]
    (conj! q {:event :start})
    (conj! q {:event :end}))
sourceraw docstring

with-ringbuf-refcljmacro

(with-ringbuf-ref [binding ringbuf-map & opts] & body)

Create a ring buffer reference with automatic cleanup.

Example: (with-ringbuf-ref [ref my-ringbuf :deserializer parse-event] (dotimes [_ 10] (println @ref)))

Create a ring buffer reference with automatic cleanup.

Example:
  (with-ringbuf-ref [ref my-ringbuf :deserializer parse-event]
    (dotimes [_ 10]
      (println @ref)))
sourceraw docstring

with-stack-channelcljmacro

(with-stack-channel [binding stack-map & opts] & body)

Create a stack channel with automatic cleanup.

Example: (with-stack-channel [ch undo-stack] (conj! ch {:op :insert}) (when-let [op (deref ch 1000 nil)] (undo op)))

Create a stack channel with automatic cleanup.

Example:
  (with-stack-channel [ch undo-stack]
    (conj! ch {:op :insert})
    (when-let [op (deref ch 1000 nil)]
      (undo op)))
sourceraw docstring

with-stack-refcljmacro

(with-stack-ref [binding stack-map & opts] & body)

Create a stack reference with automatic cleanup.

Example: (with-stack-ref [ref my-stack] (when-let [item @ref] (process item)))

Create a stack reference with automatic cleanup.

Example:
  (with-stack-ref [ref my-stack]
    (when-let [item @ref]
      (process item)))
sourceraw docstring

with-stack-writercljmacro

(with-stack-writer [binding stack-map] & body)

Create a stack writer with automatic cleanup.

Example: (with-stack-writer [s my-stack] (conj! s :a) (conj! s :b))

Create a stack writer with automatic cleanup.

Example:
  (with-stack-writer [s my-stack]
    (conj! s :a)
    (conj! s :b))
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close