39#ifndef SOFTWARE_INCLUDE_ENSO_HELPERS_H_
40#define SOFTWARE_INCLUDE_ENSO_HELPERS_H_
47#include <netinet/ether.h>
48#include <netinet/in.h>
49#include <netinet/ip.h>
50#include <netinet/tcp.h>
51#include <netinet/udp.h>
66#define likely(x) __builtin_expect((x), 1)
70#define unlikely(x) __builtin_expect((x), 0)
73#define _enso_compiler_memory_barrier() \
75 asm volatile("" : : : "memory"); \
78#define _enso_always_inline __attribute__((always_inline)) inline
100 const uint8_t* pkt,
const uint8_t rtt_offset = kDefaultRttOffset) {
101 uint32_t rtt = *((uint32_t*)(pkt + rtt_offset));
105constexpr uint16_t be_to_le_16(
const uint16_t le) {
106 return ((le & (uint16_t)0x00ff) << 8) | ((le & (uint16_t)0xff00) >> 8);
109_enso_always_inline uint16_t get_pkt_len(
const uint8_t* addr) {
110 const struct ether_header* l2_hdr = (
struct ether_header*)addr;
111 const struct iphdr* l3_hdr = (
struct iphdr*)(l2_hdr + 1);
112 const uint16_t total_len = be_to_le_16(l3_hdr->tot_len) +
sizeof(*l2_hdr);
117_enso_always_inline uint8_t* get_next_pkt(uint8_t* pkt) {
118 uint16_t pkt_len = get_pkt_len(pkt);
119 uint16_t nb_flits = (pkt_len - 1) / 64 + 1;
120 return pkt + nb_flits * 64;
123uint16_t get_bdf_from_pcie_addr(
const std::string& pcie_addr);
125void print_ip(uint32_t ip);
127void print_pkt_ips(uint8_t* pkt);
129void print_pkt_header(uint8_t* pkt);
131void print_buf(
void* buf,
const uint32_t nb_cache_lines);
133int set_core_id(std::thread& thread,
int core_id);
135void show_stats(
const std::vector<stats_t>& thread_stats,
136 volatile bool* keep_running);
139_enso_always_inline
void mov64(uint8_t* dst,
const uint8_t* src) {
140#if defined __AVX512F__
142 zmm0 = _mm512_loadu_si512((
const void*)src);
143 _mm512_storeu_si512((
void*)dst, zmm0);
144#elif defined __AVX2__
146 ymm0 = _mm256_loadu_si256((
const __m256i*)(
const void*)src);
147 ymm1 = _mm256_loadu_si256((
const __m256i*)(
const void*)(src + 32));
148 _mm256_storeu_si256((__m256i*)(
void*)dst, ymm0);
149 _mm256_storeu_si256((__m256i*)(
void*)(dst + 32), ymm1);
150#elif defined __SSE2__
151 __m128i xmm0, xmm1, xmm2, xmm3;
152 xmm0 = _mm_loadu_si128((
const __m128i*)(
const void*)src);
153 xmm1 = _mm_loadu_si128((
const __m128i*)(
const void*)(src + 16));
154 xmm2 = _mm_loadu_si128((
const __m128i*)(
const void*)(src + 32));
155 xmm3 = _mm_loadu_si128((
const __m128i*)(
const void*)(src + 48));
156 _mm_storeu_si128((__m128i*)(
void*)dst, xmm0);
157 _mm_storeu_si128((__m128i*)(
void*)(dst + 16), xmm1);
158 _mm_storeu_si128((__m128i*)(
void*)(dst + 32), xmm2);
159 _mm_storeu_si128((__m128i*)(
void*)(dst + 48), xmm3);
161 memcpy(dst, src, 64);
174 assert(((uint64_t)dst & 0x3f) == 0);
176 for (; n >= 64; n -= 64) {
177 mov64((uint8_t*)dst, (
const uint8_t*)src);
178 dst = (uint8_t*)dst + 64;
179 src = (
const uint8_t*)src + 64;
Constants used throughout the codebase. Some of these constants need to be kept in sync with the hard...
_enso_always_inline void memcpy_64_align(void *dst, const void *src, size_t n)
Copies data from src to dst.
uint32_t get_pkt_rtt(const uint8_t *pkt, const uint8_t rtt_offset=kDefaultRttOffset)
Returns RTT, in number of cycles, for a given packet.
Definitions that are internal to Enso. They should not be exposed to applications.
Helper functions adapted from the ixy driver