// Reduced benchmark body from "When a sleeping spinlock beats an atomic".
// The production harness adds calibrated repetitions, affinity verification,
// barriers, deadlines, raw-sample recording, and result validation.

#include <stdatomic.h>
#include <stdint.h>

typedef void (*increment_fn)(_Atomic uint64_t *);
typedef void (*lock_fn)(_Atomic uint32_t *);

typedef struct {
  _Alignas(64) _Atomic uint64_t atomic_counter;
  _Alignas(64) _Atomic uint32_t lock;
  _Alignas(64) uint64_t locked_counter;
  uint64_t iterations_per_worker;
} shared_state;

void run_atomic_worker(shared_state *state, increment_fn increment) {
  for (uint64_t i = 0; i < state->iterations_per_worker; ++i) {
    increment(&state->atomic_counter);
  }
}

void run_locked_worker(shared_state *state, lock_fn lock, lock_fn unlock) {
  for (uint64_t i = 0; i < state->iterations_per_worker; ++i) {
    lock(&state->lock);
    ++state->locked_counter;
    unlock(&state->lock);
  }
}

double effective_ns_per_increment(
    uint64_t elapsed_ns,
    uint64_t iterations_per_worker,
    uint32_t workers) {
  const uint64_t completed =
      iterations_per_worker * (uint64_t)workers;
  return (double)elapsed_ns / (double)completed;
}
