*/
#define atomic_int64_t _Atomic(int64_t)
#define atomic_uint32_t _Atomic(uint32_t)
+#define atomic_uint64_t _Atomic(uint64_t)
#define cas_incr(_store, _var) atomic_compare_exchange_strong_explicit(&_store, &_var, _var + 1, memory_order_release, memory_order_relaxed)
#define cas_decr(_store, _var) atomic_compare_exchange_strong_explicit(&_store, &_var, _var - 1, memory_order_release, memory_order_relaxed)
#include <freeradius-devel/unlang/interpret.h>
#include <freeradius-devel/util/dlist.h>
+#include <stdalign.h>
+
#ifdef WITH_VERIFY_PTR
static void worker_verify(fr_worker_t *worker);
#define WORKER_VERIFY worker_verify(worker)
static _Thread_local fr_worker_t *thread_local_worker;
+#define CACHE_LINE_SIZE 64
+static alignas(CACHE_LINE_SIZE) atomic_uint64_t request_number = 0;
+
/**
* A worker which takes packets from a master, and processes them.
*/
fr_event_list_t *el; //!< our event list
- uint64_t number; //!< Per worker request id.
-
int num_channels; //!< actual number of channels
fr_heap_t *runnable; //!< current runnable requests which we've spent time processing
*/
static void worker_request_init(fr_worker_t *worker, request_t *request, fr_time_t now)
{
+ uint64_t number;
+
request->el = worker->el;
request->backlog = worker->runnable;
MEM(request->packet = fr_radius_alloc(request, false));
request->reply = fr_radius_alloc(request, false);
fr_assert(request->reply != NULL);
- request->number = worker->number++;
+ /*
+ * Keep loading the number until we successfully
+ * increment it in-place.
+ */
+ do {
+ number = load(request_number);
+ } while (!cas_incr(request_number, number));
+
+ request->number = number;
request->name = itoa_internal(request, request->number);
request->async = talloc_zero(request, fr_async_t);