mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
Merge pull request #621 from VILLASframework/node-fpga
New VILLASfpga node-type
This commit is contained in:
commit
8a2818aa14
15 changed files with 281 additions and 656 deletions
|
@ -97,7 +97,7 @@ endif()
|
|||
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/local/share/pkgconfig:/usr/lib64/pkgconfig")
|
||||
|
||||
pkg_check_modules(JANSSON IMPORTED_TARGET REQUIRED jansson>=2.9)
|
||||
pkg_check_modules(JANSSON IMPORTED_TARGET REQUIRED jansson>=2.13)
|
||||
pkg_check_modules(LIBWEBSOCKETS IMPORTED_TARGET REQUIRED libwebsockets>=3.1.0)
|
||||
pkg_check_modules(PROTOBUF IMPORTED_TARGET protobuf>=2.6.0)
|
||||
pkg_check_modules(PROTOBUFC IMPORTED_TARGET libprotobuf-c>=1.1.0)
|
||||
|
@ -118,12 +118,11 @@ pkg_check_modules(UUID IMPORTED_TARGET REQUIRED uuid>=2.23)
|
|||
pkg_check_modules(CGRAPH IMPORTED_TARGET libcgraph>=2.30)
|
||||
pkg_check_modules(GVC IMPORTED_TARGET libgvc>=2.30)
|
||||
pkg_check_modules(LIBUSB IMPORTED_TARGET libusb-1.0>=1.0.23)
|
||||
pkg_check_modules(XIL IMPORTED_TARGET libxil)
|
||||
pkg_check_modules(NANOMSG IMPORTED_TARGET nanomsg)
|
||||
if(NOT NANOMSG_FOUND)
|
||||
pkg_check_modules(NANOMSG IMPORTED_TARGET libnanomsg>=1.0.0)
|
||||
endif()
|
||||
pkg_check_modules(RE IMPORTED_TARGET re>=0.5.6)
|
||||
pkg_check_modules(RE IMPORTED_TARGET re>=2.9.0)
|
||||
if(NOT RE_FOUND)
|
||||
pkg_check_modules(RE IMPORTED_TARGET libre>=0.5.6)
|
||||
endif()
|
||||
|
@ -156,7 +155,7 @@ cmake_dependent_option(WITH_API "Build with remote control API"
|
|||
cmake_dependent_option(WITH_CLIENTS "Build client applications" ON "TOPLEVEL_PROJECT" OFF)
|
||||
cmake_dependent_option(WITH_CONFIG "Build with support for libconfig configuration syntax" ON "LIBCONFIG_FOUND" OFF)
|
||||
cmake_dependent_option(WITH_DOC "Build documentation" ON "TOPLEVEL_PROJECT" OFF)
|
||||
cmake_dependent_option(WITH_FPGA "Build with support for VILLASfpga" ON "XIL_FOUND; FOUND_SUBMODULE_FPGA" OFF)
|
||||
cmake_dependent_option(WITH_FPGA "Build with support for VILLASfpga" ON "FOUND_SUBMODULE_FPGA" OFF)
|
||||
cmake_dependent_option(WITH_GO "Build with Go" ON "GO" OFF)
|
||||
cmake_dependent_option(WITH_GRAPHVIZ "Build with Graphviz" ON "CGRAPH_FOUND; GVC_FOUND" OFF)
|
||||
cmake_dependent_option(WITH_HOOKS "Build with support for processing hook plugins" ON "" OFF)
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 950857f1d792e2dad81d6e1f2e5b2d8cab60fd71
|
||||
Subproject commit 729b877a405b3bd80205fa1c54bfedbf2f030dc2
|
|
@ -4,18 +4,31 @@ logging = {
|
|||
|
||||
fpgas = {
|
||||
vc707 = {
|
||||
id = "10ee:7022"
|
||||
# Card identification
|
||||
id = "10ee:7021"
|
||||
# slot = "88:00.0"
|
||||
|
||||
do_reset = true
|
||||
|
||||
ips = "@include ../etc/examples/nodes/vc707_ips.conf"
|
||||
ips = "/global/projects/villas/fpga/software/etc/vc707-xbar-pcie/vc707-xbar-pcie.json"
|
||||
|
||||
paths = (
|
||||
{
|
||||
from = "aurora_8b10b_ch2"
|
||||
to = "aurora_8b10b_ch3"
|
||||
|
||||
reverse = true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
nodes = {
|
||||
dma_0 = {
|
||||
type = "fpga",
|
||||
fpga = "vc707"
|
||||
target = ""
|
||||
|
||||
card = "vc707"
|
||||
datamover = "dma_0"
|
||||
use_irqs = false
|
||||
}
|
||||
|
@ -24,10 +37,11 @@ nodes = {
|
|||
paths = (
|
||||
{
|
||||
in = "dma_0"
|
||||
out = [ ]
|
||||
|
||||
hooks = (
|
||||
{ type = "print" }
|
||||
{
|
||||
type = "print"
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,253 +0,0 @@
|
|||
{
|
||||
"timer_0_axi_timer_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_timer:2.0",
|
||||
"irqs": {
|
||||
"generateout0": "pcie_0_axi_pcie_intc_0:0"
|
||||
}
|
||||
},
|
||||
"hier_0_axis_data_fifo_1": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "master",
|
||||
"name": "AXIS",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S04_AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "AXIS",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M04_AXIS"
|
||||
}
|
||||
],
|
||||
"vlnv": "xilinx.com:ip:axis_data_fifo:2.0"
|
||||
},
|
||||
"hier_0_axis_interconnect_0_axis_interconnect_0_xbar": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S00_AXIS",
|
||||
"target": "hier_0_aurora_axis_0:m_axis"
|
||||
},
|
||||
{
|
||||
"role": "master",
|
||||
"name": "M00_AXIS",
|
||||
"target": "hier_0_aurora_axis_0:s_axis"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S01_AXIS",
|
||||
"target": "hier_0_axi_dma_axi_dma_0:MM2S"
|
||||
},
|
||||
{
|
||||
"role": "master",
|
||||
"name": "M01_AXIS",
|
||||
"target": "hier_0_axi_dma_axi_dma_0:S2MM"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S02_AXIS",
|
||||
"target": "hier_0_axi_fifo_mm_s_0:STR_TXD"
|
||||
},
|
||||
{
|
||||
"role": "master",
|
||||
"name": "M02_AXIS",
|
||||
"target": "hier_0_axi_fifo_mm_s_0:STR_RXD"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S03_AXIS",
|
||||
"target": "hier_0_axis_data_fifo_0:AXIS"
|
||||
},
|
||||
{
|
||||
"role": "master",
|
||||
"name": "M03_AXIS",
|
||||
"target": "hier_0_axis_data_fifo_0:AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S04_AXIS",
|
||||
"target": "hier_0_axis_data_fifo_1:AXIS"
|
||||
},
|
||||
{
|
||||
"role": "master",
|
||||
"name": "M04_AXIS",
|
||||
"target": "hier_0_axis_data_fifo_1:AXIS"
|
||||
}
|
||||
],
|
||||
"num_ports": 5,
|
||||
"vlnv": "xilinx.com:ip:axis_switch:1.1"
|
||||
},
|
||||
"hier_0_axis_data_fifo_0": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "master",
|
||||
"name": "AXIS",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S03_AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "AXIS",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M03_AXIS"
|
||||
}
|
||||
],
|
||||
"vlnv": "xilinx.com:ip:axis_data_fifo:2.0"
|
||||
},
|
||||
"hier_0_aurora_axis_0": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "master",
|
||||
"name": "m_axis",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S00_AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "s_axis",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M00_AXIS"
|
||||
}
|
||||
],
|
||||
"vlnv": "acs.eonerc.rwth-aachen.de:user:aurora_axis:1.16"
|
||||
},
|
||||
"pcie_0_axi_reset_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_gpio:2.0"
|
||||
},
|
||||
"hier_0_axi_fifo_mm_s_0": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "master",
|
||||
"name": "STR_TXD",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S02_AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "STR_RXD",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M02_AXIS"
|
||||
}
|
||||
],
|
||||
"vlnv": "xilinx.com:ip:axi_fifo_mm_s:4.2",
|
||||
"irqs": {
|
||||
"interrupt": "pcie_0_axi_pcie_intc_0:1"
|
||||
}
|
||||
},
|
||||
"hier_0_axi_dma_axi_dma_0": {
|
||||
"ports": [
|
||||
{
|
||||
"role": "master",
|
||||
"name": "MM2S",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S01_AXIS"
|
||||
},
|
||||
{
|
||||
"role": "slave",
|
||||
"name": "S2MM",
|
||||
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M01_AXIS"
|
||||
}
|
||||
],
|
||||
"vlnv": "xilinx.com:ip:axi_dma:7.1",
|
||||
"memory-view": {
|
||||
"M_AXI_MM2S": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296,
|
||||
"baseaddr": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_AXI_S2MM": {
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"BAR0": {
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296,
|
||||
"baseaddr": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"irqs": {
|
||||
"s2mm_introut": "pcie_0_axi_pcie_intc_0:3",
|
||||
"mm2s_introut": "pcie_0_axi_pcie_intc_0:2"
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_intc_0": {
|
||||
"vlnv": "acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:1.4"
|
||||
},
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_pcie:2.9",
|
||||
"memory-view": {
|
||||
"M_AXI": {
|
||||
"timer_0_axi_timer_0": {
|
||||
"Reg": {
|
||||
"highaddr": 20479,
|
||||
"size": 4096,
|
||||
"baseaddr": 16384
|
||||
}
|
||||
},
|
||||
"hier_0_axi_fifo_mm_s_0": {
|
||||
"Mem0": {
|
||||
"highaddr": 40959,
|
||||
"size": 8192,
|
||||
"baseaddr": 32768
|
||||
},
|
||||
"Mem1": {
|
||||
"highaddr": 57343,
|
||||
"size": 8192,
|
||||
"baseaddr": 49152
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_0": {
|
||||
"CTL0": {
|
||||
"highaddr": 536870911,
|
||||
"size": 268435456,
|
||||
"baseaddr": 268435456
|
||||
}
|
||||
},
|
||||
"hier_0_aurora_axis_0": {
|
||||
"reg0": {
|
||||
"highaddr": 12287,
|
||||
"size": 4096,
|
||||
"baseaddr": 8192
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_reset_0": {
|
||||
"Reg": {
|
||||
"highaddr": 32767,
|
||||
"size": 4096,
|
||||
"baseaddr": 28672
|
||||
}
|
||||
},
|
||||
"hier_0_axis_interconnect_0_axis_interconnect_0_xbar": {
|
||||
"Reg": {
|
||||
"highaddr": 24575,
|
||||
"size": 4096,
|
||||
"baseaddr": 20480
|
||||
}
|
||||
},
|
||||
"hier_0_axi_dma_axi_dma_0": {
|
||||
"Reg": {
|
||||
"highaddr": 16383,
|
||||
"size": 4096,
|
||||
"baseaddr": 12288
|
||||
}
|
||||
},
|
||||
"pcie_0_axi_pcie_intc_0": {
|
||||
"reg0": {
|
||||
"highaddr": 8191,
|
||||
"size": 4096,
|
||||
"baseaddr": 4096
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pcie_bars": {
|
||||
"BAR0": {
|
||||
"translation": 0
|
||||
}
|
||||
},
|
||||
"axi_bars": {
|
||||
"BAR0": {
|
||||
"highaddr": 4294967295,
|
||||
"size": 4294967296,
|
||||
"translation": 0,
|
||||
"baseaddr": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
fpga
2
fpga
|
@ -1 +1 @@
|
|||
Subproject commit 0a225cd3e15296372e71aae7983debdb4508d75d
|
||||
Subproject commit 05581018b85fad8202a5604ce62c0d80d77a0eb5
|
|
@ -411,14 +411,12 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
isInternal() const
|
||||
bool isInternal() const
|
||||
{
|
||||
return getFlags() & (int) Flags::INTERNAL;
|
||||
}
|
||||
|
||||
bool
|
||||
isHidden() const
|
||||
bool isHidden() const
|
||||
{
|
||||
return isInternal() || getFlags() & (int) Flags::HIDDEN;
|
||||
}
|
||||
|
@ -461,14 +459,14 @@ public:
|
|||
return vectorize;
|
||||
}
|
||||
|
||||
virtual std::string
|
||||
getName() const
|
||||
virtual
|
||||
std::string getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual std::string
|
||||
getDescription() const
|
||||
virtual
|
||||
std::string getDescription() const
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <villas/node/config.hpp>
|
||||
#include <villas/node.hpp>
|
||||
#include <villas/format.hpp>
|
||||
#include <villas/timing.hpp>
|
||||
|
||||
|
@ -19,15 +20,12 @@
|
|||
namespace villas {
|
||||
namespace node {
|
||||
|
||||
/* Forward declarations */
|
||||
class NodeCompat;
|
||||
|
||||
using namespace villas;
|
||||
|
||||
#define FPGA_DMA_VLNV
|
||||
#define FPGA_AURORA_VLNV "acs.eonerc.rwth-aachen.de:user:aurora_axis:"
|
||||
|
||||
struct fpga_node {
|
||||
class FpgaNode : public Node {
|
||||
|
||||
protected:
|
||||
int irqFd;
|
||||
int coalesce;
|
||||
bool polling;
|
||||
|
@ -37,41 +35,82 @@ struct fpga_node {
|
|||
std::shared_ptr<fpga::ip::Dma> dma;
|
||||
std::shared_ptr<fpga::ip::Node> intf;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
MemoryAccessor<int32_t> i;
|
||||
MemoryAccessor<float> f;
|
||||
} accessor;
|
||||
MemoryBlock::Ptr block;
|
||||
} in, out;
|
||||
std::unique_ptr<const MemoryBlock> blockRx;
|
||||
std::unique_ptr<const MemoryBlock> blockTx;
|
||||
|
||||
// Config only
|
||||
std::string cardName;
|
||||
std::string intfName;
|
||||
std::string dmaName;
|
||||
|
||||
protected:
|
||||
virtual
|
||||
int _read(Sample *smps[], unsigned cnt);
|
||||
|
||||
virtual
|
||||
int _write(Sample *smps[], unsigned cnt);
|
||||
|
||||
public:
|
||||
FpgaNode(const std::string &name = "");
|
||||
|
||||
virtual
|
||||
~FpgaNode();
|
||||
|
||||
virtual
|
||||
int parse(json_t *cfg, const uuid_t sn_uuid);
|
||||
|
||||
virtual
|
||||
const std::string & getDetails();
|
||||
|
||||
virtual
|
||||
int check();
|
||||
|
||||
virtual
|
||||
int prepare();
|
||||
|
||||
virtual
|
||||
std::vector<int> getPollFDs();
|
||||
};
|
||||
|
||||
int fpga_type_start(SuperNode *sn);
|
||||
|
||||
int fpga_type_stop();
|
||||
class FpgaNodeFactory : public NodeFactory {
|
||||
|
||||
int fpga_init(NodeCompat *n);
|
||||
public:
|
||||
using NodeFactory::NodeFactory;
|
||||
|
||||
int fpga_destroy(NodeCompat *n);
|
||||
virtual
|
||||
Node * make()
|
||||
{
|
||||
auto *n = new FpgaNode;
|
||||
|
||||
int fpga_parse(NodeCompat *n, json_t *json);
|
||||
init(n);
|
||||
|
||||
char * fpga_print(NodeCompat *n);
|
||||
return n;
|
||||
}
|
||||
|
||||
int fpga_check(NodeCompat *n);
|
||||
virtual
|
||||
int getFlags() const
|
||||
{
|
||||
return (int) NodeFactory::Flags::SUPPORTS_READ |
|
||||
(int) NodeFactory::Flags::SUPPORTS_WRITE |
|
||||
(int) NodeFactory::Flags::SUPPORTS_POLL;
|
||||
}
|
||||
|
||||
int fpga_prepare(NodeCompat *n);
|
||||
virtual
|
||||
std::string getName() const
|
||||
{
|
||||
return "fpga";
|
||||
}
|
||||
|
||||
int fpga_write(NodeCompat *n, struct Sample * const smps[], unsigned cnt);
|
||||
virtual
|
||||
std::string getDescription() const
|
||||
{
|
||||
return "VILLASfpga";
|
||||
}
|
||||
|
||||
int fpga_read(NodeCompat *n, struct Sample * const smps[], unsigned cnt);
|
||||
|
||||
int fpga_poll_fds(NodeCompat *n, int fds[]);
|
||||
virtual
|
||||
int start(SuperNode *sn);
|
||||
};
|
||||
|
||||
} /* namespace node */
|
||||
} /* namespace villas */
|
||||
|
|
|
@ -33,7 +33,6 @@ struct Pool {
|
|||
struct CQueue queue; /**< The queue which is used to keep track of free blocks */
|
||||
};
|
||||
|
||||
#define INLINE static inline __attribute__((unused))
|
||||
#define pool_buffer(p) ((char *) (p) + (p)->buffer_off)
|
||||
|
||||
/** Initiazlize a pool
|
||||
|
@ -56,29 +55,16 @@ int pool_destroy(struct Pool *p) __attribute__ ((warn_unused_result));
|
|||
* This number can be smaller than the requested \p cnt blocks
|
||||
* in case the pool currently holds less than \p cnt blocks.
|
||||
*/
|
||||
INLINE ssize_t pool_get_many(struct Pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_pull_many(&p->queue, blocks, cnt);
|
||||
}
|
||||
ssize_t pool_get_many(struct Pool *p, void *blocks[], size_t cnt);
|
||||
|
||||
/** Push \p cnt values which are giving by the array values to the stack. */
|
||||
INLINE ssize_t pool_put_many(struct Pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_push_many(&p->queue, blocks, cnt);
|
||||
}
|
||||
ssize_t pool_put_many(struct Pool *p, void *blocks[], size_t cnt);
|
||||
|
||||
/** Get a free memory block from pool. */
|
||||
INLINE void * pool_get(struct Pool *p)
|
||||
{
|
||||
void *ptr;
|
||||
return queue_pull(&p->queue, &ptr) == 1 ? ptr : nullptr;
|
||||
}
|
||||
void * pool_get(struct Pool *p);
|
||||
|
||||
/** Release a memory block back to the pool. */
|
||||
INLINE int pool_put(struct Pool *p, void *buf)
|
||||
{
|
||||
return queue_push(&p->queue, buf);
|
||||
}
|
||||
int pool_put(struct Pool *p, void *buf);
|
||||
|
||||
} /* namespace node */
|
||||
} /* namespace villas */
|
||||
|
|
|
@ -353,7 +353,7 @@ json_t * Config::expandIncludes(json_t *in)
|
|||
if (!incl)
|
||||
incl = other;
|
||||
else if (json_is_object(incl) && json_is_object(other)) {
|
||||
ret = json_object_update(incl, other);
|
||||
ret = json_object_update_recursive(incl, other);
|
||||
if (ret)
|
||||
throw ConfigError(str, "Can not mix object and array-typed include files");
|
||||
}
|
||||
|
|
|
@ -181,13 +181,13 @@ int ExecNode::_write(struct Sample * smps[], unsigned cnt)
|
|||
|
||||
const std::string & ExecNode::getDetails()
|
||||
{
|
||||
std::string wd = working_dir;
|
||||
if (wd.empty()) {
|
||||
char buf[128];
|
||||
wd = getcwd(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (details.empty()) {
|
||||
std::string wd = working_dir;
|
||||
if (wd.empty()) {
|
||||
char buf[128];
|
||||
wd = getcwd(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
details = fmt::format("exec={}, shell={}, flush={}, #environment={}, #arguments={}, working_dir={}",
|
||||
command,
|
||||
shell ? "yes" : "no",
|
||||
|
|
|
@ -20,20 +20,19 @@
|
|||
#include <villas/sample.hpp>
|
||||
#include <villas/super_node.hpp>
|
||||
|
||||
#include <villas/fpga/card.hpp>
|
||||
#include <villas/fpga/core.hpp>
|
||||
#include <villas/fpga/vlnv.hpp>
|
||||
#include <villas/fpga/ips/dma.hpp>
|
||||
|
||||
using namespace villas;
|
||||
using namespace villas::node;
|
||||
using namespace villas::fpga;
|
||||
using namespace villas::utils;
|
||||
|
||||
/* Forward declartions */
|
||||
static struct NodeCompatType p;
|
||||
|
||||
/* Global state */
|
||||
static fpga::PCIeCard::List cards;
|
||||
static std::map<fpga::ip::Dma, struct fpga_node *> dmaMap;
|
||||
static fpga::Card::List cards;
|
||||
static std::map<fpga::ip::Dma, FpgaNode *> dmaMap;
|
||||
|
||||
static std::shared_ptr<kernel::pci::DeviceList> pciDevices;
|
||||
static std::shared_ptr<kernel::vfio::Container> vfioContainer;
|
||||
|
@ -41,260 +40,166 @@ static std::shared_ptr<kernel::vfio::Container> vfioContainer;
|
|||
using namespace villas;
|
||||
using namespace villas::node;
|
||||
|
||||
int villas::node::fpga_type_start(SuperNode *sn)
|
||||
FpgaNode::FpgaNode(const std::string &name) :
|
||||
Node(name),
|
||||
irqFd(-1),
|
||||
coalesce(0),
|
||||
polling(true)
|
||||
{ }
|
||||
|
||||
FpgaNode::~FpgaNode()
|
||||
{ }
|
||||
|
||||
int FpgaNode::parse(json_t *cfg, const uuid_t sn_uuid)
|
||||
{
|
||||
vfioContainer = kernel::vfio::Container::create();
|
||||
pciDevices = std::make_shared<kernel::pci::DeviceList>();
|
||||
|
||||
// get the FPGA card plugin
|
||||
auto pcieCardPlugin = plugin::registry->lookup<fpga::PCIeCardFactory>("pcie");
|
||||
if (!pcieCardPlugin)
|
||||
throw RuntimeError("No FPGA PCIe plugin found");
|
||||
|
||||
json_t *json = sn->getConfig();
|
||||
json_t *fpgas = json_object_get(json, "fpgas");
|
||||
if (!fpgas)
|
||||
throw ConfigError(json, "node-config-fpgas", "No section 'fpgas' found in config");
|
||||
|
||||
// create all FPGA card instances using the corresponding plugin
|
||||
auto pcieCards = pcieCardPlugin->make(fpgas, pciDevices, vfioContainer);
|
||||
|
||||
cards.splice(cards.end(), pcieCards);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int villas::node::fpga_type_stop()
|
||||
{
|
||||
vfioContainer.reset(); // TODO: is this the proper way?
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int villas::node::fpga_init(NodeCompat *n)
|
||||
{
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
|
||||
f->coalesce = 0;
|
||||
f->irqFd = -1;
|
||||
f->polling = true;
|
||||
|
||||
new (&f->cardName) std::string();
|
||||
new (&f->dmaName) std::string();
|
||||
new (&f->intfName) std::string();
|
||||
|
||||
new (&f->card) std::shared_ptr<fpga::PCIeCard>();
|
||||
|
||||
new (&f->dma) std::shared_ptr<fpga::ip::Node>();
|
||||
new (&f->intf) std::shared_ptr<fpga::ip::Node>();
|
||||
|
||||
new (&f->in.block) std::unique_ptr<MemoryBlock>();
|
||||
new (&f->out.block) std::unique_ptr<MemoryBlock>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int villas::node::fpga_destroy(NodeCompat *n)
|
||||
{
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
|
||||
// using maiptr = MemoryAccessor<uint32_t>;
|
||||
// using mafptr = MemoryAccessor<float>;
|
||||
using mbptr = MemoryBlock::Ptr;
|
||||
using cptr = std::shared_ptr<fpga::PCIeCard>;
|
||||
using nptr = std::shared_ptr<fpga::ip::Node>;
|
||||
using dptr = std::shared_ptr<fpga::ip::Dma>;
|
||||
using sptr = std::string;
|
||||
|
||||
f->cardName.~sptr();
|
||||
f->dmaName.~sptr();
|
||||
f->intfName.~sptr();
|
||||
|
||||
f->card.~cptr();
|
||||
|
||||
f->dma.~dptr();
|
||||
f->intf.~nptr();
|
||||
|
||||
f->in.block.~mbptr();
|
||||
f->out.block.~mbptr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int villas::node::fpga_parse(NodeCompat *n, json_t *json)
|
||||
{
|
||||
int ret;
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
int ret = Node::parse(cfg, sn_uuid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
json_error_t err;
|
||||
|
||||
const char *card = nullptr;
|
||||
const char *intf = nullptr;
|
||||
const char *dma = nullptr;
|
||||
int polling = f->polling;
|
||||
int poll = polling;
|
||||
|
||||
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s, s?: i, s?: b }",
|
||||
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s, s?: i, s?: b }",
|
||||
"card", &card,
|
||||
"interface", &intf,
|
||||
"dma", &dma,
|
||||
"coalesce", &f->coalesce,
|
||||
"coalesce", &coalesce,
|
||||
"polling", &polling
|
||||
);
|
||||
if (ret)
|
||||
throw ConfigError(json, err, "node-config-node-fpga");
|
||||
throw ConfigError(cfg, err, "node-config-fpga", "Failed to parse configuration of node {}", *this);
|
||||
|
||||
if (card)
|
||||
f->cardName = card;
|
||||
cardName = card;
|
||||
|
||||
if (intf)
|
||||
f->intfName = intf;
|
||||
intfName = intf;
|
||||
|
||||
if (dma)
|
||||
f->dmaName = dma;
|
||||
dmaName = dma;
|
||||
|
||||
f->polling = polling; // cast int to bool
|
||||
polling = poll; // cast int to bool
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * villas::node::fpga_print(NodeCompat *n)
|
||||
const std::string & FpgaNode::getDetails()
|
||||
{
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
if (details.empty()) {
|
||||
auto &name = card ? card->name : cardName;
|
||||
|
||||
return strf("fpga=%s, dma=%s, if=%s, polling=%s, coalesce=%d",
|
||||
f->card->name.c_str(),
|
||||
f->dma->getInstanceName().c_str(),
|
||||
f->polling ? "yes" : "no",
|
||||
f->coalesce
|
||||
);
|
||||
details = fmt::format("fpga={}, dma={}, if={}, polling={}, coalesce={}",
|
||||
name,
|
||||
dma->getInstanceName(),
|
||||
polling ? "yes" : "no",
|
||||
coalesce
|
||||
);
|
||||
}
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
int villas::node::fpga_prepare(NodeCompat *n)
|
||||
int FpgaNode::check()
|
||||
{
|
||||
int ret;
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Select first FPGA card
|
||||
auto it = f->cardName.empty()
|
||||
int FpgaNode::prepare()
|
||||
{
|
||||
auto it = cardName.empty()
|
||||
? cards.begin()
|
||||
: std::find_if(cards.begin(), cards.end(), [f](const fpga::PCIeCard::Ptr &c) {
|
||||
return c->name == f->cardName;
|
||||
: std::find_if(cards.begin(), cards.end(), [this](const fpga::Card::Ptr &c) {
|
||||
return c->name == cardName;
|
||||
});
|
||||
|
||||
if (it == cards.end())
|
||||
throw ConfigError(json_object_get(n->getConfig(), "fpga"), "node-config-node-fpga-card", "Invalid FPGA card name: {}", f->cardName);
|
||||
throw ConfigError(json_object_get(config, "fpga"), "node-config-fpga-card", "Invalid FPGA card name: {}", cardName);
|
||||
|
||||
f->card = *it;
|
||||
card = *it;
|
||||
|
||||
// Select interface IP core
|
||||
auto intf = f->intfName.empty()
|
||||
? f->card->lookupIp(fpga::Vlnv(FPGA_AURORA_VLNV))
|
||||
: f->card->lookupIp(f->intfName);
|
||||
auto intfCore = intfName.empty()
|
||||
? card->lookupIp(fpga::Vlnv(FPGA_AURORA_VLNV))
|
||||
: card->lookupIp(intfName);
|
||||
if (!intfCore)
|
||||
throw ConfigError(config, "node-config-fpga-interface", "There is no interface IP with the name: {}", intfName);
|
||||
|
||||
intf = std::dynamic_pointer_cast<fpga::ip::Node>(intfCore);
|
||||
if (!intf)
|
||||
throw ConfigError(n->getConfig(), "node-config-node-fpga-interface", "There is no interface IP with the name: {}", f->intfName);
|
||||
|
||||
f->intf = std::dynamic_pointer_cast<fpga::ip::Node>(intf);
|
||||
if (!f->intf)
|
||||
throw RuntimeError("The IP {} is not a interface", *intf);
|
||||
|
||||
// Select DMA IP core
|
||||
auto dma = f->dmaName.empty()
|
||||
? f->card->lookupIp(fpga::Vlnv(FPGA_DMA_VLNV))
|
||||
: f->card->lookupIp(f->dmaName);
|
||||
if (!dma)
|
||||
throw ConfigError(n->getConfig(), "node-config-node-fpga-dma", "There is no DMA IP with the name: {}", f->dmaName);
|
||||
auto dmaCore = dmaName.empty()
|
||||
? card->lookupIp(fpga::Vlnv(FPGA_DMA_VLNV))
|
||||
: card->lookupIp(dmaName);
|
||||
if (!dmaCore)
|
||||
throw ConfigError(config, "node-config-fpga-dma", "There is no DMA IP with the name: {}", dmaName);
|
||||
|
||||
f->dma = std::dynamic_pointer_cast<fpga::ip::Dma>(dma);
|
||||
if (!f->dma)
|
||||
dma = std::dynamic_pointer_cast<fpga::ip::Dma>(dmaCore);
|
||||
if (!dma)
|
||||
throw RuntimeError("The IP {} is not a DMA controller", *dma);
|
||||
|
||||
ret = f->intf->connect(*(f->dma), true);
|
||||
int ret = intf->connect(*(dma), true);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to connect: {} -> {}",
|
||||
*(f->intf), *(f->dma)
|
||||
);
|
||||
throw RuntimeError("Failed to connect: {} -> {}", *(intf), *(dma));
|
||||
|
||||
auto &alloc = HostDmaRam::getAllocator();
|
||||
|
||||
f->in.block = std::move(alloc.allocateBlock(0x100 / sizeof(int32_t)));
|
||||
f->out.block = std::move(alloc.allocateBlock(0x100 / sizeof(int32_t)));
|
||||
auto memRx = alloc.allocate<uint32_t>(0x100 / sizeof(int32_t));
|
||||
auto memTx = alloc.allocate<uint32_t>(0x100 / sizeof(int32_t));
|
||||
|
||||
f->in.accessor.i = MemoryAccessor<int32_t>(*f->in.block);
|
||||
f->in.accessor.f = MemoryAccessor<float>(*f->in.block);
|
||||
blockRx = std::unique_ptr<const MemoryBlock>(&memRx.getMemoryBlock());
|
||||
blockTx = std::unique_ptr<const MemoryBlock>(&memTx.getMemoryBlock());
|
||||
|
||||
f->out.accessor.i = MemoryAccessor<int32_t>(*f->out.block);
|
||||
f->out.accessor.f = MemoryAccessor<float>(*f->out.block);
|
||||
dma->makeAccesibleFromVA(*blockRx);
|
||||
dma->makeAccesibleFromVA(*blockTx);
|
||||
|
||||
f->dma->makeAccesibleFromVA(*f->in.block);
|
||||
f->dma->makeAccesibleFromVA(*f->out.block);
|
||||
// Show some debugging infos
|
||||
auto &mm = MemoryManager::get();
|
||||
|
||||
f->dma->dump();
|
||||
f->intf->dump();
|
||||
MemoryManager::get().getGraph().dump();
|
||||
dma->dump();
|
||||
intf->dump();
|
||||
mm.getGraph().dump();
|
||||
|
||||
return 0;
|
||||
return Node::prepare();
|
||||
}
|
||||
|
||||
int villas::node::fpga_read(NodeCompat *n, struct Sample * const smps[], unsigned cnt)
|
||||
int FpgaNode::_read(Sample *smps[], unsigned cnt)
|
||||
{
|
||||
unsigned read;
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
struct Sample *smp = smps[0];
|
||||
Sample *smp = smps[0];
|
||||
|
||||
assert(cnt == 1);
|
||||
|
||||
f->dma->read(*f->in.block.get(), f->in.block->getSize()); // TODO: calc size
|
||||
const size_t bytesRead = f->dma->readComplete();
|
||||
dma->read(*blockRx, blockRx->getSize()); // TODO: calc size
|
||||
const size_t bytesRead = dma->readComplete();
|
||||
read = bytesRead / sizeof(int32_t);
|
||||
|
||||
for (unsigned i = 0; i < MIN(read, smp->capacity); i++) {
|
||||
auto sig = n->getInputSignals(false)->getByIndex(i);
|
||||
auto mem = MemoryAccessor<uint32_t>(*blockRx);
|
||||
|
||||
switch (sig->type) {
|
||||
case SignalType::INTEGER:
|
||||
smp->data[i].i = f->in.accessor.i[i];
|
||||
break;
|
||||
for (unsigned i = 0; i < MIN(read, smp->capacity); i++)
|
||||
smp->data[i].i = mem[i];
|
||||
|
||||
case SignalType::FLOAT:
|
||||
smp->data[i].f = f->in.accessor.f[i];
|
||||
break;
|
||||
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
|
||||
smp->signals = n->getInputSignals(false);
|
||||
smp->length = bytesRead / sizeof(uint32_t);
|
||||
smp->flags = (int) SampleFlags::HAS_DATA;
|
||||
smp->signals = in.signals;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
int villas::node::fpga_write(NodeCompat *n, struct Sample * const smps[], unsigned cnt)
|
||||
int FpgaNode::_write(Sample *smps[], unsigned cnt)
|
||||
{
|
||||
int written;
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
struct Sample *smp = smps[0];
|
||||
Sample *smp = smps[0];
|
||||
|
||||
assert(cnt == 1);
|
||||
|
||||
for (unsigned i = 0; i < smps[0]->length; i++) {
|
||||
auto sig = smp->signals->getByIndex(i);
|
||||
auto mem = MemoryAccessor<uint32_t>(*blockTx);
|
||||
|
||||
switch (sig->type) {
|
||||
case SignalType::INTEGER:
|
||||
f->out.accessor.i[i] = smps[0]->data[i].i;
|
||||
break;
|
||||
for (unsigned i = 0; i < smps[0]->length; i++)
|
||||
mem[i] = smps[0]->data[i].i;
|
||||
|
||||
case SignalType::FLOAT:
|
||||
f->out.accessor.f[i] = smps[0]->data[i].f;
|
||||
break;
|
||||
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
|
||||
bool state = f->dma->write(*f->out.block.get(), smp->length * sizeof(int32_t));
|
||||
bool state = dma->write(*blockTx, smp->length * sizeof(int32_t));
|
||||
if (!state)
|
||||
return -1;
|
||||
|
||||
|
@ -303,36 +208,37 @@ int villas::node::fpga_write(NodeCompat *n, struct Sample * const smps[], unsign
|
|||
return written;
|
||||
}
|
||||
|
||||
int villas::node::fpga_poll_fds(NodeCompat *n, int fds[])
|
||||
std::vector<int> FpgaNode::getPollFDs()
|
||||
{
|
||||
auto *f = n->getData<struct fpga_node>();
|
||||
std::vector<int> fds;
|
||||
|
||||
if (f->polling)
|
||||
return 0;
|
||||
else {
|
||||
fds[0] = f->irqFd;
|
||||
if (!polling)
|
||||
fds.push_back(irqFd);
|
||||
|
||||
return 1; /* The number of file descriptors which have been set in fds */
|
||||
}
|
||||
return fds;
|
||||
}
|
||||
|
||||
__attribute__((constructor(110)))
|
||||
static void register_plugin() {
|
||||
p.name = "fpga";
|
||||
p.description = "Communicate with VILLASfpga Xilinx FPGA boards";
|
||||
p.vectorize = 1;
|
||||
p.size = sizeof(struct fpga_node);
|
||||
p.type.start = fpga_type_start;
|
||||
p.type.stop = fpga_type_stop;
|
||||
p.init = fpga_init;
|
||||
p.destroy = fpga_destroy;
|
||||
p.prepare = fpga_prepare;
|
||||
p.parse = fpga_parse;
|
||||
p.print = fpga_print;
|
||||
p.read = fpga_read;
|
||||
p.write = fpga_write;
|
||||
p.poll_fds = fpga_poll_fds;
|
||||
int FpgaNodeFactory::start(SuperNode *sn)
|
||||
{
|
||||
vfioContainer = std::make_shared<kernel::vfio::Container>();
|
||||
pciDevices = std::make_shared<kernel::pci::DeviceList>();
|
||||
|
||||
static NodeCompatFactory ncp(&p);
|
||||
// Get the FPGA card plugin
|
||||
auto pcieCardPlugin = plugin::registry->lookup<fpga::PCIeCardFactory>("pcie");
|
||||
if (!pcieCardPlugin)
|
||||
throw RuntimeError("No FPGA PCIe plugin found");
|
||||
|
||||
json_t *json_cfg = sn->getConfig();
|
||||
json_t *json_fpgas = json_object_get(json_cfg, "fpgas");
|
||||
if (!json_fpgas)
|
||||
throw ConfigError(json_cfg, "node-config-fpgas", "No section 'fpgas' found in config");
|
||||
|
||||
// Create all FPGA card instances using the corresponding plugin
|
||||
auto piceCards = fpga::PCIeCardFactory::make(json_fpgas, pciDevices, vfioContainer);
|
||||
|
||||
cards.splice(cards.end(), piceCards);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FpgaNodeFactory p;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <villas/nodes/rtp.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <re/re_net.h>
|
||||
#include <re/re_main.h>
|
||||
#include <re/re_types.h>
|
||||
#include <re/re_mbuf.h>
|
||||
|
@ -548,7 +549,7 @@ retry: mbuf_set_pos(r->send_mb, RTP_HEADER_SIZE);
|
|||
mbuf_set_pos(r->send_mb, RTP_HEADER_SIZE);
|
||||
|
||||
/* Send dataset */
|
||||
ret = rtp_send(r->rs, &r->out.saddr_rtp, false, false, RTP_PACKET_TYPE, ts, r->send_mb);
|
||||
ret = rtp_send(r->rs, &r->out.saddr_rtp, false, false, RTP_PACKET_TYPE, ts, 0, r->send_mb);
|
||||
if (ret)
|
||||
throw RuntimeError("Error from rtp_send, reason: {}", ret);
|
||||
|
||||
|
@ -564,22 +565,6 @@ int villas::node::rtp_poll_fds(NodeCompat *n, int fds[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
int villas::node::rtp_netem_fds(NodeCompat *n, int fds[])
|
||||
{
|
||||
auto *r = n->getData<struct rtp>();
|
||||
|
||||
int m = 0;
|
||||
struct udp_sock *rtp = (struct udp_sock *) rtp_sock(r->rs);
|
||||
struct udp_sock *rtcp = (struct udp_sock *) rtcp_sock(r->rs);
|
||||
|
||||
fds[m++] = udp_sock_fd(rtp, AF_INET);
|
||||
|
||||
if (r->rtcp.enabled)
|
||||
fds[m++] = udp_sock_fd(rtcp, AF_INET);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
__attribute__((constructor(110)))
|
||||
static void register_plugin() {
|
||||
p.name = "rtp";
|
||||
|
@ -602,5 +587,4 @@ static void register_plugin() {
|
|||
p.write = rtp_write;
|
||||
p.reverse = rtp_reverse;
|
||||
p.poll_fds = rtp_poll_fds;
|
||||
p.netem_fds = rtp_netem_fds;
|
||||
}
|
||||
|
|
21
lib/pool.cpp
21
lib/pool.cpp
|
@ -62,3 +62,24 @@ int villas::node::pool_destroy(struct Pool *p)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t villas::node::pool_get_many(struct Pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_pull_many(&p->queue, blocks, cnt);
|
||||
}
|
||||
|
||||
ssize_t villas::node::pool_put_many(struct Pool *p, void *blocks[], size_t cnt)
|
||||
{
|
||||
return queue_push_many(&p->queue, blocks, cnt);
|
||||
}
|
||||
|
||||
void * villas::node::pool_get(struct Pool *p)
|
||||
{
|
||||
void *ptr;
|
||||
return queue_pull(&p->queue, &ptr) == 1 ? ptr : nullptr;
|
||||
}
|
||||
|
||||
int villas::node::pool_put(struct Pool *p, void *buf)
|
||||
{
|
||||
return queue_push(&p->queue, buf);
|
||||
}
|
||||
|
|
|
@ -16,21 +16,6 @@ MAKE_OPTS+="--jobs=${MAKE_THREADS}"
|
|||
git config --global http.postBuffer 524288000
|
||||
git config --global core.compression 0
|
||||
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
TARGET="package"
|
||||
CMAKE_OPTS+=" -DCPACK_GENERATOR=RPM"
|
||||
|
||||
# Prepare rpmbuild dir
|
||||
mkdir -p ~/rpmbuild/SOURCES
|
||||
mkdir -p rpms
|
||||
|
||||
dnf -y install \
|
||||
xmlto \
|
||||
systemd-devel
|
||||
else
|
||||
TARGET="install"
|
||||
fi
|
||||
|
||||
DIR=$(mktemp -d)
|
||||
pushd ${DIR}
|
||||
|
||||
|
@ -42,22 +27,18 @@ if ! pkg-config "criterion >= 2.3.1" && \
|
|||
mkdir -p Criterion/build
|
||||
pushd Criterion/build
|
||||
cmake ${CMAKE_OPTS} ..
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
# Build & Install libjansson
|
||||
if ! pkg-config "jansson >= 2.7" && \
|
||||
if ! pkg-config "jansson >= 2.13" && \
|
||||
[ -z "${SKIP_JANSSON}" ]; then
|
||||
git clone ${GIT_OPTS} --branch v2.14 https://github.com/akheron/jansson
|
||||
pushd jansson
|
||||
autoreconf -i
|
||||
./configure ${CONFIGURE_OPTS}
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -71,10 +52,8 @@ if ! ( pkg-config "lua >= 5.1" || \
|
|||
) && [ -z "${SKIP_LUA}" ]; then
|
||||
wget http://www.lua.org/ftp/lua-5.3.6.tar.gz -O - | tar -xz
|
||||
pushd lua-5.3.6
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} MYCFLAGS=-fPIC linux
|
||||
make ${MAKE_OPTS} MYCFLAGS=-fPIC install
|
||||
fi
|
||||
make ${MAKE_OPTS} MYCFLAGS=-fPIC linux
|
||||
make ${MAKE_OPTS} MYCFLAGS=-fPIC install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -89,7 +68,7 @@ if ! pkg-config "libmosquitto >= 1.4.15" && \
|
|||
-DWITH_APPS=OFF \
|
||||
-DDOCUMENTATION=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -100,7 +79,7 @@ if ! pkg-config "librabbitmq >= 0.8.0" && \
|
|||
mkdir -p rabbitmq-c/build
|
||||
pushd rabbitmq-c/build
|
||||
cmake ${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -114,7 +93,7 @@ if ! pkg-config "libzmq >= 2.2.0" && \
|
|||
-DZMQ_BUILD_TESTS=OFF \
|
||||
-DENABLE_CPACK=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -124,13 +103,7 @@ if [ -z "${SKIP_ETHERLAB}" ]; then
|
|||
pushd ethercat
|
||||
./bootstrap
|
||||
./configure --enable-userlib=yes --enable-kernel=no ${CONFIGURE_OPTS}
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
else
|
||||
wget https://etherlab.org/download/ethercat/ethercat-1.5.2.tar.bz2
|
||||
cp ethercat-1.5.2.tar.bz2 ~/rpmbuild/SOURCES
|
||||
rpmbuild -ba ethercat.spec
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -141,10 +114,7 @@ if ! pkg-config "libiec61850 >= 1.3.1" && \
|
|||
mkdir -p libiec61850/build
|
||||
pushd libiec61850/build
|
||||
cmake ${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
cp libiec61850/build/*.rpm rpms
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -155,10 +125,7 @@ if ! pkg-config "lib60870 >= 2.3.1" && \
|
|||
mkdir -p lib60870/build
|
||||
pushd lib60870/build
|
||||
cmake ${CMAKE_OPTS} ../lib60870-C
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
cp lib60870/build/*.rpm rpms
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -171,7 +138,7 @@ if ! pkg-config "rdkafka >= 1.5.0" && \
|
|||
cmake -DRDKAFKA_BUILD_TESTS=OFF \
|
||||
-DRDKAFKA_BUILD_EXAMPLES=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -183,7 +150,7 @@ if ! ( pkg-config "libcgraph >= 2.30" && \
|
|||
mkdir -p graphviz/build
|
||||
pushd graphviz/build
|
||||
cmake ${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -196,13 +163,7 @@ if ! pkg-config "libuldaq >= 1.2.0" && \
|
|||
./configure \
|
||||
--disable-examples \
|
||||
${CONFIGURE_OPTS}
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
else
|
||||
make dist
|
||||
cp fedora/uldaq_ldconfig.patch libuldaq-1.2.0.tar.gz ~/rpmbuild/SOURCES
|
||||
rpmbuild -ba fedora/uldaq.spec
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -216,9 +177,7 @@ if ! ( pkg-config "libnl-3.0 >= 3.2.25" && \
|
|||
./configure \
|
||||
--enable-cli=no \
|
||||
${CONFIGURE_OPTS}
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -232,9 +191,7 @@ if ! pkg-config "libconfig >= 1.4.9" && \
|
|||
--disable-tests \
|
||||
--disable-examples \
|
||||
--disable-doc
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -247,28 +204,16 @@ if ! pkg-config "comedilib >= 0.11.0" && \
|
|||
./configure \
|
||||
--disable-docbook \
|
||||
${CONFIGURE_OPTS}
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
else
|
||||
touch doc/pdf/comedilib.pdf # skip build of PDF which is broken..
|
||||
make dist
|
||||
cp comedilib-0.12.0.tar.gz ~/rpmbuild/SOURCES
|
||||
rpmbuild -ba comedilib.spec
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
# Build & Install libre
|
||||
if ! pkg-config "libre >= 0.5.6" && \
|
||||
if ! pkg-config "libre >= 2.9.0" && \
|
||||
[ -z "${SKIP_LIBRE}" ]; then
|
||||
git clone ${GIT_OPTS} --branch v0.6.1 https://github.com/creytiv/re.git
|
||||
git clone ${GIT_OPTS} --branch v2.9.0 https://github.com/baresip/re.git
|
||||
pushd re
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
else
|
||||
tar --transform 's|^\.|re-0.6.1|' -czvf ~/rpmbuild/SOURCES/re-0.6.1.tar.gz .
|
||||
rpmbuild -ba rpm/re.spec
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -284,9 +229,7 @@ if ! pkg-config "nanomsg >= 1.0.0" && \
|
|||
-DNN_ENABLE_DOC=OFF \
|
||||
-DNN_ENABLE_COVERAGE=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -297,9 +240,7 @@ if ! pkg-config "libxil >= 1.0.0" && \
|
|||
mkdir -p libxil/build
|
||||
pushd libxil/build
|
||||
cmake ${CMAKE_OPTS} ..
|
||||
if [ -z "${PACKAGE}" ]; then
|
||||
make ${MAKE_OPTS} install
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -312,7 +253,7 @@ if ! pkg-config "hiredis>1.0.0" && \
|
|||
cmake -DDISABLE_TESTS=ON \
|
||||
-DENABLE_SSL=ON \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -329,7 +270,7 @@ if [ -z "${SKIP_REDISPP}" -a -z "${SKIP_REDIS}" ]; then
|
|||
-DREDIS_PLUS_PLUS_BUILD_STATIC=OFF \
|
||||
-DREDIS_PLUS_PLUS_CXX_STANDARD=17 \
|
||||
${REDISPP_CMAKE_OPTS} ${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET} VERBOSE=1
|
||||
make ${MAKE_OPTS} install VERBOSE=1
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -342,10 +283,7 @@ if ! pkg-config "fmt >= 6.1.2" && \
|
|||
cmake -DBUILD_SHARED_LIBS=1 \
|
||||
-DFMT_TEST=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
cp fmt/build/*.rpm rpms
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -360,10 +298,7 @@ if ! pkg-config "spdlog >= 1.8.2" && \
|
|||
-DSPDLOG_BUILD_SHARED=ON \
|
||||
-DSPDLOG_BUILD_TESTS=OFF \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
cp spdlog/build/*.rpm rpms
|
||||
fi
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
|
@ -378,18 +313,14 @@ if ! pkg-config "libwebsockets >= 3.1.0" && \
|
|||
-DLWS_WITHOUT_EXTENSIONS=OFF \
|
||||
-DLWS_WITH_SERVER_STATUS=ON \
|
||||
${CMAKE_OPTS} ..
|
||||
make ${MAKE_OPTS} ${TARGET}
|
||||
make ${MAKE_OPTS} install
|
||||
popd
|
||||
fi
|
||||
|
||||
if [ -n "${PACKAGE}" ]; then
|
||||
cp ~/rpmbuild/RPMS/x86_64/*.rpm rpms
|
||||
fi
|
||||
|
||||
popd
|
||||
rm -rf ${DIR}
|
||||
|
||||
# Update linker cache
|
||||
if [ -z "${PACKAGE}" -a -z "${SKIP_LDCONFIG}" ]; then
|
||||
if [ -z "${SKIP_LDCONFIG}" ]; then
|
||||
ldconfig
|
||||
fi
|
||||
|
|
|
@ -79,7 +79,7 @@ static void * producer(void *ctx)
|
|||
|
||||
/* Wait for global start signal */
|
||||
while (p->start == 0)
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
|
||||
/* Wait for a random time */
|
||||
for (size_t i = 0; i != nops; i += 1)
|
||||
|
@ -89,7 +89,7 @@ static void * producer(void *ctx)
|
|||
for (intptr_t count = 0; count < p->iter_count; count++) {
|
||||
do {
|
||||
ret = queue_push(&p->queue, (void *) count);
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
} while (ret != 1);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ static void * consumer(void *ctx)
|
|||
|
||||
/* Wait for global start signal */
|
||||
while (p->start == 0)
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
|
||||
/* Wait for a random time */
|
||||
for (size_t i = 0; i != nops; i += 1)
|
||||
|
@ -138,7 +138,7 @@ void * producer_consumer(void *ctx)
|
|||
|
||||
/* Wait for global start signal */
|
||||
while (p->start == 0)
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
|
||||
/* Wait for a random time */
|
||||
for (size_t i = 0; i != nops; i += 1)
|
||||
|
@ -150,13 +150,13 @@ void * producer_consumer(void *ctx)
|
|||
for (intptr_t i = 0; i < p->batch_size; i++) {
|
||||
void *ptr = (void *) (iter * p->batch_size + i);
|
||||
while (!queue_push(&p->queue, ptr))
|
||||
pthread_yield(); /* queue full, let other threads proceed */
|
||||
sched_yield(); /* queue full, let other threads proceed */
|
||||
}
|
||||
|
||||
for (intptr_t i = 0; i < p->batch_size; i++) {
|
||||
void *ptr;
|
||||
while (!queue_pull(&p->queue, &ptr))
|
||||
pthread_yield(); /* queue empty, let other threads proceed */
|
||||
sched_yield(); /* queue empty, let other threads proceed */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ void * producer_consumer_many(void *ctx)
|
|||
|
||||
/* Wait for global start signal */
|
||||
while (p->start == 0)
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
|
||||
/* Wait for a random time */
|
||||
for (size_t i = 0; i != nops; i += 1)
|
||||
|
@ -190,14 +190,14 @@ void * producer_consumer_many(void *ctx)
|
|||
do {
|
||||
pushed += queue_push_many(&p->queue, &ptrs[pushed], p->batch_size - pushed);
|
||||
if (pushed != p->batch_size)
|
||||
pthread_yield(); /* queue full, let other threads proceed */
|
||||
sched_yield(); /* queue full, let other threads proceed */
|
||||
} while (pushed < p->batch_size);
|
||||
|
||||
int pulled = 0;
|
||||
do {
|
||||
pulled += queue_pull_many(&p->queue, &ptrs[pulled], p->batch_size - pulled);
|
||||
if (pulled != p->batch_size)
|
||||
pthread_yield(); /* queue empty, let other threads proceed */
|
||||
sched_yield(); /* queue empty, let other threads proceed */
|
||||
} while (pulled < p->batch_size);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue