135 lines
4.3 KiB
C++
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
|