1/* @title: Per-NUMA Node dynamic objects */
2#pragma once
3#include <compiler.h>
4#include <linker/symbols.h>
5#include <mem/numa.h>
6#include <stddef.h>
7#include <stdint.h>
8
9struct pernode_descriptor;
10typedef void (*pernode_descriptor_constructor)(void *, size_t);
11
12struct pernode_descriptor {
13 const char *name;
14 size_t size;
15 size_t align;
16 void **pernode_ptrs;
17 pernode_descriptor_constructor constructor;
18};
19
20LINKER_SECTION_DEFINE(struct pernode_descriptor, pernode_desc);
21
22#define PERNODE_DECLARE(__n, __type, __ctor) \
23 extern __type __pernode_##__n; \
24 static void __pernode_ctor_##__n(void *inst, size_t cpu) { \
25 if ((__ctor) != NULL) \
26 __ctor((__type *) inst, cpu); \
27 } \
28 LINKER_SECTION_OBJECT(struct pernode_descriptor, pernode_desc) \
29 __pernode_desc_##__n = { \
30 .name = #__n, \
31 .size = sizeof(__type), \
32 .align = _Alignof(__type), \
33 .pernode_ptrs = NULL, \
34 .constructor = __pernode_ctor_##__n, \
35 }; \
36 __type __pernode_##__n
37
38void pernode_obj_init(void);
39
40#define PERNODE_PTR_FOR_NODE(name, d) \
41 ((typeof(__pernode_##name) *) __pernode_desc_##name.pernode_ptrs[d])
42#define PERNODE_READ_FOR_NODE(name, d) \
43 (*((typeof(__pernode_##name) *) PERNODE_PTR_FOR_NODE(name, d)))
44
45#define PERNODE_PTR(name) PERNODE_PTR_FOR_NODE(name, node_local_id())
46#define PERNODE_READ(name) (*((typeof(__pernode_##name) *) PERNODE_PTR(name)))
47
48#define PERNODE_WRITE(name, val) (PERNODE_READ(name) = (val))
49