(std stm counter)

Reference

Overview

Striped transactional counter that minimizes write conflicts across processor cores.

(import (std stm))
(import (std stm counter))

(def requests (make-tcounter 0L))

;; Per-request addition: stripes writes by CPU to avoid transaction conflicts
(atomically (fun (tx) (tcounter-add! tx requests 1L)))

;; Periodic read: sums across all stripes
(atomically (fun (tx) (tcounter-ref tx requests)))

(TCounter T) stores a numeric counter of type T (implementing Num, such as int, long, or double). Its value is partitioned across multiple per-CPU striped locations. Add operations write only to the stripe corresponding to the executing CPU, allowing concurrent transactions on different cores to commit without conflicts.

Read vs write trade-offs. tcounter-ref inspects all stripes to compute the total sum, conflicting with concurrent writes. Use this counter when additions are frequent and reads are infrequent (e.g. request and error metrics). If a value is read as often as it is written, a standard Loc is preferred.

Overflow. Fixed-width integers wrap on overflow using two’s complement arithmetic across stripes.

Credits. Based on the Accumulator design in kcas_data (https://github.com/ocaml-multicore/kcas).

See also: TCounter, tcounter-add!, tcounter-ref

Reference

Types

Functions

Types

TCounter

record ↑ Types

Striped transactional counter holding a numeric value of type %a.

%a
The numeric type (must implement Num).

See also: make-tcounter

Functions

make-tcounter

function ↑ Functions

(: make-tcounter (-> %a (TCounter %a)))
(make-tcounter initial)

Creates a new striped counter initialized with a value.

initial
Initial value (e.g. 0L for a long counter).
returns
A new striped transactional counter.

Allocates one stripe per CPU core, rounded up to the nearest power of two.

tcounter-add!

function ↑ Functions

(: tcounter-add! (-> Tx (TCounter %a) %a void))
(tcounter-add! tx c n)

Adds n to the counter within a transaction.

tx
The transaction log context.
c
The counter.
n
The value to add.

Updates only the stripe assigned to the current CPU core and reads no other stripes. Does not return the updated total; call tcounter-ref to read the full sum.

tcounter-sub!

function ↑ Functions

(: tcounter-sub! (-> Tx (TCounter %a) %a void))
(tcounter-sub! tx c n)

Subtracts n from the counter within a transaction.

tx
The transaction log context.
c
The counter.
n
The value to subtract.

tcounter-ref

function ↑ Functions

(: tcounter-ref (-> Tx (TCounter %a) %a))
(tcounter-ref tx c)

Computes the total sum across all stripes within a transaction.

tx
The transaction log context.
c
The counter.
returns
The aggregate sum of all stripes.

Reads all stripes, causing conflicts with any concurrent transactions performing additions.

tcounter-set!

function ↑ Functions

(: tcounter-set! (-> Tx (TCounter %a) %a void))
(tcounter-set! tx c value)

Overwrites all counter stripes with a new value within a transaction.

tx
The transaction log context.
c
The counter.
value
The new value to assign.

Writes to all stripes, conflicting with concurrent transactions that add to the counter.