Ensō 0.4.6
Software API reference
Loading...
Searching...
No Matches
helpers.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022, Carnegie Mellon University
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted (subject to the limitations in the disclaimer
6 * below) provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * * Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
20 * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
21 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
22 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 */
31
39#ifndef SOFTWARE_INCLUDE_ENSO_HELPERS_H_
40#define SOFTWARE_INCLUDE_ENSO_HELPERS_H_
41
42#include <endian.h>
43#include <enso/consts.h>
44#include <enso/internals.h>
45#include <enso/ixy_helpers.h>
46#include <immintrin.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>
52#include <pthread.h>
53
54#include <cassert>
55#include <cstdint>
56#include <cstdio>
57#include <cstring>
58#include <iostream>
59#include <string>
60#include <thread>
61#include <vector>
62
63namespace enso {
64
65#ifndef likely
66#define likely(x) __builtin_expect((x), 1)
67#endif
68
69#ifndef unlikely
70#define unlikely(x) __builtin_expect((x), 0)
71#endif
72
73#define _enso_compiler_memory_barrier() \
74 do { \
75 asm volatile("" : : : "memory"); \
76 } while (0)
77
78#define _enso_always_inline __attribute__((always_inline)) inline
79
80struct alignas(kCacheLineSize) stats_t {
81 uint64_t recv_bytes;
82 uint64_t nb_batches;
83 uint64_t nb_pkts;
84};
85
99inline uint32_t get_pkt_rtt(
100 const uint8_t* pkt, const uint8_t rtt_offset = kDefaultRttOffset) {
101 uint32_t rtt = *((uint32_t*)(pkt + rtt_offset));
102 return be32toh(rtt);
103}
104
105constexpr uint16_t be_to_le_16(const uint16_t le) {
106 return ((le & (uint16_t)0x00ff) << 8) | ((le & (uint16_t)0xff00) >> 8);
107}
108
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);
113
114 return total_len;
115}
116
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;
121}
122
123uint16_t get_bdf_from_pcie_addr(const std::string& pcie_addr);
124
125void print_ip(uint32_t ip);
126
127void print_pkt_ips(uint8_t* pkt);
128
129void print_pkt_header(uint8_t* pkt);
130
131void print_buf(void* buf, const uint32_t nb_cache_lines);
132
133int set_core_id(std::thread& thread, int core_id);
134
135void show_stats(const std::vector<stats_t>& thread_stats,
136 volatile bool* keep_running);
137
138// Adapted from DPDK's rte_mov64() and rte_memcpy() functions.
139_enso_always_inline void mov64(uint8_t* dst, const uint8_t* src) {
140#if defined __AVX512F__
141 __m512i zmm0;
142 zmm0 = _mm512_loadu_si512((const void*)src);
143 _mm512_storeu_si512((void*)dst, zmm0);
144#elif defined __AVX2__
145 __m256i ymm0, ymm1;
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);
160#else
161 memcpy(dst, src, 64);
162#endif
163}
164
172_enso_always_inline void memcpy_64_align(void* dst, const void* src, size_t n) {
173 // Check that it is aligned to 64 bytes.
174 assert(((uint64_t)dst & 0x3f) == 0);
175
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;
180 }
181}
182
183} // namespace enso
184
185#endif // SOFTWARE_INCLUDE_ENSO_HELPERS_H_
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.
Definition: helpers.h:172
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.
Definition: helpers.h:99
Definitions that are internal to Enso. They should not be exposed to applications.
Helper functions adapted from the ixy driver