Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions app/Package.resolved

This file was deleted.

2 changes: 1 addition & 1 deletion app/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.2
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
8 changes: 4 additions & 4 deletions app/Sources/app/Subcommands/Forward.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ class Forward: Subcommand {
// process/forward from -> to device using a specific queue (currently the queue is always 0)
private func process(from: Device, to: Device, queue: Int) {
// get queues
let rx = from.receiveQueues[queue]
let tx = to.transmitQueues[queue]
var rx = from.receiveQueues[queue]
var tx = to.transmitQueues[queue]

// receive packets
let packets = rx.fetchAvailablePackets(limit: batchSize)
var packets = rx.fetchAvailablePackets(limit: batchSize)
for packet in packets {
// touch each packet
packet.touch()
}

// transmit packets
let sentPackets = tx.transmit(packets, freeUnused: true)
let sentPackets = tx.transmit(&packets, freeUnused: true)

// keep track of lost packets due if not enough tx descriptors are available
lost += (packets.count - sentPackets)
Expand Down
8 changes: 5 additions & 3 deletions app/Sources/app/Subcommands/PacketGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ class PacketGen: Subcommand {

func loop() {
while(true) {
let packets = device.receiveQueues[0].fetchAvailablePackets()
var tmpReceiveQueue = device.receiveQueues[0]
let packets = tmpReceiveQueue.fetchAvailablePackets()

if packets.count > 0 {
Log.log("Got \(packets.count) packets", level: .info, component: "app")
}

let tx = device.transmitQueues[0]
var tx = device.transmitQueues[0]
guard let packet = tx.createDummyPacket() else {
fatalError("no packet available")
}
_ = tx.transmit([packet])
var tmpPacket = [packet]
_ = tx.transmit(&tmpPacket)

sleep(1)
}
Expand Down
6 changes: 4 additions & 2 deletions app/Sources/app/Subcommands/Simple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class Simple: Subcommand {
func loop() {
nextTime = .now() + .seconds(1)
while(true) {
let packets = device.receiveQueues[0].fetchAvailablePackets()
var tmpReceiveQueue = device.receiveQueues[0]
var packets = tmpReceiveQueue.fetchAvailablePackets()

if packets.count > 0 {
Log.log("Got \(packets.count) packets", level: .info, component: "app")
Expand All @@ -40,7 +41,8 @@ class Simple: Subcommand {
}
}

_ = device.transmitQueues[0].transmit(packets)
var tmpTransmitQueue = device.transmitQueues[0]
_ = tmpTransmitQueue.transmit(&packets)

sleep(1)

Expand Down
2 changes: 1 addition & 1 deletion ixy/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.2
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
6 changes: 3 additions & 3 deletions ixy/Sources/ixy/Common/Atomic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

/// Generic wrapper for accessing an object atomically
public final class Atomic<T> {
public struct Atomic<T> {
private let lock = DispatchSemaphore(value: 1)
private var _value: T

Expand All @@ -32,7 +32,7 @@ public final class Atomic<T> {
/// mutate the value suing a block
///
/// - Parameter transform: the block which can mutate the value
public func mutate(_ transform: (inout T) -> Void) {
public mutating func mutate(_ transform: (inout T) -> Void) {
lock.wait()
defer { lock.signal() }
transform(&_value)
Expand All @@ -41,7 +41,7 @@ public final class Atomic<T> {

// MARK: - Extension for Strideable types, which offer the possibility to be incremented
extension Atomic where T: Strideable {
public func increment(by: T.Stride = 1) -> T {
public mutating func increment(by: T.Stride = 1) -> T {
lock.wait()
defer { lock.signal() }
_value = _value.advanced(by: by)
Expand Down
6 changes: 3 additions & 3 deletions ixy/Sources/ixy/Common/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ func throwsError(_ block: () throws -> Void) -> Error? {
}

// MARK: - extensions for pretty-printing integers
public extension BinaryInteger {
extension BinaryInteger {
/// print the integer like a pointer (0xff00aa)
public var pointerString: String {
var pointerString: String {
return "0x" + String(self, radix: 16, uppercase: false)
}

/// print the integer like a hexadecimal (ff00aa)
public var hexString: String {
var hexString: String {
return String(self, radix: 16, uppercase: false)
}
}
23 changes: 14 additions & 9 deletions ixy/Sources/ixy/Common/File.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// a simple file wrapper class, which uses file descriptors to access the file
internal class File {
internal struct File: ~Copyable {
internal var fd: Int32
internal var closeOnDealloc: Bool
internal var path: String?
Expand All @@ -20,22 +20,27 @@ internal class File {
self.closeOnDealloc = closeOnDealloc
}

internal init(path: String, flags: Int32, createMode: mode_t? = nil) throws {
internal init(path: String, flags: Int32) throws {
guard let chars = path.cString(using: .utf8) else { throw FileError.internalError }
let pathPointer: UnsafePointer<CChar> = UnsafePointer(chars)
if let mode = createMode {
self.fd = open(pathPointer, flags, mode)
} else {
self.fd = open(pathPointer, flags)
}
guard self.fd >= 0 else { throw FileError.openError(errno) }
self.fd = open(pathPointer, flags)
//guard self.fd >= 0 else { throw FileError.openError(errno) }
self.closeOnDealloc = true
self.path = path
}

internal init(path: String, flags: Int32, createMode: mode_t) throws {
guard let chars = path.cString(using: .utf8) else { throw FileError.internalError }
let pathPointer: UnsafePointer<CChar> = UnsafePointer(chars)
self.fd = open(pathPointer, flags, createMode)
//guard self.fd >= 0 else { throw FileError.openError(errno) }
self.closeOnDealloc = true
self.path = path
}

deinit {
if closeOnDealloc {
close(fd)
close(fd)//fixme: close file descriptor
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions ixy/Sources/ixy/Common/FixedStack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

/// a generic fixed stack implementation which can be used as a stand in for an array, to check performance
class FixedStack<T> {
struct FixedStack<T> {
var objects: [T?]
var top: Int = 0

Expand All @@ -22,19 +22,19 @@ class FixedStack<T> {
self.top = -1
}

func initialize(from objects: [T]) {
mutating func initialize(from objects: [T]) {
for object in objects {
self.push(object)
}
}

func push(_ object: T) {
mutating func push(_ object: T) {
assert(top < objects.count, "stack unbalanced push")
top += 1
objects[top] = object
}

func pop() -> T? {
mutating func pop() -> T? {
assert(top >= 0, "stack unbalanced pop")
let object = objects[top]
objects[top] = nil
Expand Down
12 changes: 6 additions & 6 deletions ixy/Sources/ixy/Common/Log.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

/// basic logger with debug/info/warn/error levels and some components
public final class Log {
public struct Log {
static public var enableColors: Bool = true
static var componentLength: Int? = 6 {
didSet {
Expand Down Expand Up @@ -54,23 +54,23 @@ public final class Log {
}

internal static func log(_ message: @autoclosure () -> String, level: Level = .debug, component: Component) {
self.log(message, level: level, component: component.rawValue)
self.log(message(), level: level, component: component.rawValue)
}

internal static func error(_ message: @autoclosure () -> String, component: Component) {
log(message, level: .error, component: component)
log(message(), level: .error, component: component)
}

internal static func warn(_ message: @autoclosure () -> String, component: Component) {
log(message, level: .warn, component: component)
log(message(), level: .warn, component: component)
}

internal static func info(_ message: @autoclosure () -> String, component: Component) {
log(message, level: .info, component: component)
log(message(), level: .info, component: component)
}

internal static func debug(_ message: @autoclosure () -> String, component: Component) {
log(message, level: .debug, component: component)
log(message(), level: .debug, component: component)
}

internal static func formatComponent(_ component: String) -> String? {
Expand Down
8 changes: 5 additions & 3 deletions ixy/Sources/ixy/Common/Pagemap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ import Foundation

/// simple subclass for the pagemap file with easy initializiation based on Constants.pagemapPath and conversion
/// from virtual to physical pointer
class Pagemap: File {
struct Pagemap: ~Copyable {
let file: File
static var pagesize: UInt = {
return UInt(sysconf(Int32(_SC_PAGESIZE)))
}()

init() throws {
try super.init(path: Constants.pagemapPath, flags: O_RDONLY)
try file = File(path: Constants.pagemapPath, flags: O_RDONLY)
//try super.init(path: Constants.pagemapPath, flags: O_RDONLY)
}

func physical(from virtual: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? {
let virtualIntAddress = UInt(bitPattern: virtual)
// TODO: check if correct calculation due to possible precedence differences!
let offset: off_t = off_t(virtualIntAddress / Pagemap.pagesize * UInt(MemoryLayout<Int>.size))
do {
let pageNumber: UInt = try self.read(offset: offset)
let pageNumber: UInt = try file.read(offset: offset)
// TODO: check if correct calculation due to possible precedence differences!
let physicalIntAddress = ((pageNumber & 0x7f_ffff_ffff_ffff) * Pagemap.pagesize) + (virtualIntAddress % Pagemap.pagesize)
let physical = UnsafeMutableRawPointer(bitPattern: physicalIntAddress)
Expand Down
22 changes: 15 additions & 7 deletions ixy/Sources/ixy/Device/Config/DeviceConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@
import Foundation

/// simple wrapper class based on file for a pci device
internal class DeviceConfig: File {
internal struct DeviceConfig: ~Copyable {
let file: File
internal init(address: PCIAddress) throws {
let path = address.path + "/config"
try super.init(path: path, flags: O_RDONLY)
try file = File(path: path, flags: O_RDONLY)
}

var vendorID: UInt16 {
return (try? self.read(offset: 0x00)) ?? 0
return (try? file.read(offset: 0x00)) ?? 0
}

var deviceID: UInt16 {
return (try? self.read(offset: 0x02)) ?? 0
return (try? file.read(offset: 0x02)) ?? 0
}

var classCode: UInt32 {
Expand All @@ -28,22 +29,29 @@ internal class DeviceConfig: File {
// Datasheet P755
// Register at 0x08 = [RevID:8][ClassCode:24]
// -> read from 0x08 but discard first 8 bits
try code = self.read(offset: 0x08)
try code = file.read(offset: 0x08)
code = ((code >> 8) & 0xFF_FFFF)
} catch {
code = 0
}
return code
}

var description: String {
let vendor = String(self.vendorID, radix: 16, uppercase: true)
let device = String(self.deviceID, radix: 16, uppercase: true)
let classC = String(self.classCode, radix: 16, uppercase: true)
return "DeviceConfig(vendor=0x\(vendor), device=0x\(device), class=0x\(classC))"
}
}

// MARK: - CustomStringConvertible
extension DeviceConfig: CustomStringConvertible {
/*extension DeviceConfig: CustomStringConvertible {
var description: String {
let vendor = String(self.vendorID, radix: 16, uppercase: true)
let device = String(self.deviceID, radix: 16, uppercase: true)
let classC = String(self.classCode, radix: 16, uppercase: true)
return "DeviceConfig(vendor=0x\(vendor), device=0x\(device), class=0x\(classC))"
}
}
}*/

21 changes: 13 additions & 8 deletions ixy/Sources/ixy/Device/Device.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/// the base class for the Intel 82599
public class Device {
public struct Device {
public let address: PCIAddress
public let receiveQueueCount: UInt
public let transmitQueueCount: UInt
Expand Down Expand Up @@ -55,7 +55,7 @@ public class Device {
return (packetMempool, packetHugepage.memoryMap)
}

public func open() throws {
public mutating func open() throws {
// perform various steps to open and initialize the device (method names should be self-explanatory)
try createReceiveQueues()
try createTransmitQueues()
Expand All @@ -65,8 +65,12 @@ public class Device {

self.driver.initReceive(queues: self.receiveQueues)
self.driver.initTransmit(queues: self.transmitQueues)
self.receiveQueues.forEach({ $0.start() })
self.transmitQueues.forEach({ $0.start() })
for var receiveQueue in self.receiveQueues{
receiveQueue.start()
}
for var transmitQueue in self.transmitQueues{
transmitQueue.start()
}
self.driver.promiscuousMode = true

try self.driver.waitForLink()
Expand All @@ -77,8 +81,9 @@ public class Device {
private static func checkConfig(address: PCIAddress) throws {
// try to open device config
let config = try DeviceConfig(address: address)
let configDescription = config.description

Log.debug("Device Config: \(config)", component: .device)
Log.debug("Device Config: \(configDescription)", component: .device)

// check vendor
let vendor = config.vendorID
Expand All @@ -89,7 +94,7 @@ public class Device {
}

internal var stats: DeviceStats = DeviceStats(transmittedPackets: 0, transmittedBytes: 0, receivedPackets: 0, receivedBytes: 0)
public func fetchStats() -> DeviceStats {
public mutating func fetchStats() -> DeviceStats {
let newStats = self.driver.readStats()
self.stats += newStats
return self.stats
Expand All @@ -99,14 +104,14 @@ public class Device {
return self.driver.readStats()
}

internal func createReceiveQueues() throws {
internal mutating func createReceiveQueues() throws {
let driver = self.driver
self.receiveQueues = try (0..<self.receiveQueueCount).map { (Idx) -> ReceiveQueue in
return try ReceiveQueue.withHugepageMemory(index: Idx, packetMempool: self.packetMempool, descriptorCount: Constants.Queue.ringEntryCount, driver: driver)
}
}

internal func createTransmitQueues() throws {
internal mutating func createTransmitQueues() throws {
let driver = self.driver
self.transmitQueues = try (0..<self.transmitQueueCount).map { (Idx) -> TransmitQueue in
return try TransmitQueue.withHugepageMemory(index: Idx, packetMempool: self.packetMempool, descriptorCount: Constants.Queue.ringEntryCount, driver: driver)
Expand Down
Loading