Files
calculet-npu-research-archive/source/baseline-expanded/calrt-sdk-0.7.6/usr/local/include/calrt/protocol.hpp
T

135 lines
4.3 KiB
C++

/**
* @file protocol.hpp
* @brief IPC protocol
*
* payload layout: [direction | RegionKey | Region]
* IPC data share protocol layout : [ShMemhdr | large data]
* Overall layout: [Payload | ShMemhdr | large data]
*
* device management layout: [ShmHdr | ShmCtx ...]
*
* @version 0.1
* @date 2025-10-29
*
* @copyright Copyright (c) 2025
*
*/
#pragma once
// #include <sys/mman.h> // For mmap and munmap
#include <cstring>
#include <pthread.h>
#include <cstdint>
#include <atomic>
// #ifdef __cplusplus
// #include <atomic>
// #define ALIGNAS(x) alignas(x)
// #define ATOMIC_UINT32 std::atomic<uint32_t>
// #else
// #include <stdatomic.h>
// #define ALIGNAS(x) _Alignas(x)
// #define ATOMIC_UINT32 _Atomic uint32_t
// #endif
namespace calrt
{
extern const char* kSockPath;
extern const char* kShMemCreatePath;
extern const char* kShMemRepairPath;
// inline constexpr const char* kSockPath = "/home/patrickyang/uds_epoll_demo.sock";
inline constexpr const char* kShMem = "/shm_calculet_device";
// inline constexpr const char* kShMemCreatePath = "/run/create_lck.lock";
// inline constexpr const char* kShMemRepairPath = "/run/repair.lock";
// inline constexpr const char* kShMemRepairPathBak = "/tmp/calrt/repair.lock";
// -------------------------------------- IPC large data transfer --------------------------------------
//
/**
* @brief each region key coresponse to one req or many if there are related. just tell the offset and size with same region id.
*
*/
struct RegionKey
{
int32_t id;
bool operator==(const RegionKey &other) const noexcept
{
return id == other.id;
}
};
struct Region
{
int32_t fd = -1; // don't init in client side
int32_t prot; // = PROT_READ | PROT_WRITE; // protection flag for kernel. tell how process can access the mapped memory region
int32_t flag; // = MAP_SHARED;
std::atomic<uint32_t> counter{0}; // counter if this region is still accessed
uint64_t offset = 0; // temp represent memory address.
uint64_t size = 0;
void *map = nullptr;
};
struct ShMemhdr
{
std::atomic<uint32_t> ready = 0; // 0: not ready, 1: ready
};
struct Payload
{
uint8_t direction; // 0: host-to-device. 1: device-to-host
RegionKey key;
Region region;
};
// -------------------------------------- end --------------------------------------
// -------------------------------------- helper --------------------------------------
inline uint64_t now_ns()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<uint64_t>(ts.tv_sec) * 1000000000ull + ts.tv_nsec;
}
template<typename T>
void encode_impl(std::vector<unsigned char> &meta, T data, size_t len = 0)
{
size_t n = meta.size();
size_t tSize = len == 0? sizeof(T) : len;
meta.resize(n+tSize);
std::memcpy(&meta[n], &data, tSize);
}
/**
* @brief [id | prot | flag | size]
*
* @param meta
* @param regionK
* @param region
*/
inline void encode_socket(std::vector<unsigned char> &meta, Payload &msgHdr)
{
encode_impl(meta, msgHdr.direction);
encode_impl(meta, msgHdr.key.id);
encode_impl(meta, msgHdr.region.prot);
encode_impl(meta, msgHdr.region.flag);
encode_impl(meta, msgHdr.region.size);
encode_impl(meta, msgHdr.region.offset);
}
inline void decode_socket(const unsigned char* meta, Payload &out)
{
std::memcpy(&out.direction, meta, sizeof(out.direction));
size_t stride = sizeof(out.direction);
std::memcpy(&out.key.id, meta+stride, sizeof(out.key.id));
stride += sizeof(out.key.id);
std::memcpy(&out.region.prot, meta+stride, sizeof(out.region.prot));
stride += sizeof(out.region.prot);
std::memcpy(&out.region.flag, meta+stride, sizeof(out.region.flag));
stride += sizeof(out.region.flag);
std::memcpy(&out.region.size, meta+stride, sizeof(out.region.size));
stride += sizeof(out.region.size);
std::memcpy(&out.region.offset, meta+stride, sizeof(out.region.offset));
}
} //namespace calrt