#ifndef TINY_REMOTE_H #define TINY_REMOTE_H #include #include struct SuperSlab; struct TinySlabMeta; extern int g_remote_side_enable; void tiny_remote_side_init_from_env(void); void tiny_remote_side_set(struct SuperSlab* ss, int slab_idx, void* node, uintptr_t next); uintptr_t tiny_remote_side_get(struct SuperSlab* ss, int slab_idx, void* node); void tiny_remote_side_clear(struct SuperSlab* ss, int slab_idx, void* node); int tiny_remote_side_contains(struct SuperSlab* ss, int slab_idx, void* node); void tiny_remote_sentinel_set(void* node); int tiny_remote_sentinel_ok(void* node); void tiny_remote_watch_mark(void* node, const char* stage, uint32_t tid); int tiny_remote_watch_is(void* node); void tiny_remote_watch_clear(void* node); void tiny_remote_watch_note(const char* stage, struct SuperSlab* ss, int slab_idx, void* node, uint32_t code, uint32_t tid, int fatal); #ifdef __GNUC__ #include #endif #define TINY_REMOTE_SENTINEL ((uintptr_t)0xBADA55BADA55BADAULL) static inline uintptr_t tiny_remote_pack_diag(uint32_t code, uintptr_t base, size_t ss_size, uintptr_t ptr) { uintptr_t aux = (uintptr_t)code; uint32_t slab = 0xFFFFu; uintptr_t low = ptr & 0xFFFFu; if (ptr >= base && ptr < base + ss_size) { uintptr_t delta = ptr - base; slab = (uint32_t)(delta >> 16); low = delta & 0xFFFFu; } aux |= ((uintptr_t)low << 16); aux |= ((uintptr_t)slab << 32); return aux; } void tiny_remote_report_corruption(const char* stage, void* node, uintptr_t observed); #if !defined(HAKMEM_BUILD_RELEASE) enum tiny_remote_track_state { TINY_REMOTE_TRACK_NONE = 0, TINY_REMOTE_TRACK_ALLOC = 1, TINY_REMOTE_TRACK_REMOTE = 2, TINY_REMOTE_TRACK_FREELIST = 3, }; void tiny_remote_track_on_alloc(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); void tiny_remote_track_on_remote_push(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); void tiny_remote_track_on_remote_drain(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); void tiny_remote_track_on_local_free(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); void tiny_remote_track_expect_alloc(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); void tiny_remote_assert_not_remote(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid); int tiny_remote_guard_allow_local_push(struct SuperSlab* ss, int slab_idx, struct TinySlabMeta* meta, void* node, const char* stage, uint32_t self_tid); #else static inline void tiny_remote_track_on_alloc(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline void tiny_remote_track_on_remote_push(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline void tiny_remote_track_on_remote_drain(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline void tiny_remote_track_on_local_free(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline void tiny_remote_track_expect_alloc(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline void tiny_remote_assert_not_remote(struct SuperSlab* ss, int slab_idx, void* node, const char* stage, uint32_t tid) { (void)ss; (void)slab_idx; (void)node; (void)stage; (void)tid; } static inline int tiny_remote_guard_allow_local_push(struct SuperSlab* ss, int slab_idx, struct TinySlabMeta* meta, void* node, const char* stage, uint32_t self_tid) { (void)ss; (void)slab_idx; (void)meta; (void)node; (void)stage; (void)self_tid; return 1; } #endif #endif