Giter VIP home page Giter VIP logo

portus's Introduction

Portus Build Status

Portus is an implementation of a congestion control plane (CCP). It is a library that can be used to write new congestion control algorithms in user-space.

Congestion control algorithm implementations live in independent crates which use this library for common functionality. Each algorithm crate provides a binary which runs a CCP with that algorithm activated.

Further documentation is available on docs.rs.

Setup

  1. Install rust. See http://rust-lang.org/ for details.
  2. make. This will build and lint the portus library and bundled algorithm libraries and binaries, and run unit tests.

Notes

  • The ipc::netlink and ipc::kp modules will only compile on Linux. If the CCP kernel module (github.mit.edu/nebula/ccp-kernel) is loaded, the test will refuse to run.

Run

There are no algorithm binaries in this repository: it is just a library and runtime for CCP algorithms. You may be interested in https://github.com/ccp-project/generic-cong-avoid, which provides implementations of Reno and Cubic, or https://github.com/ccp-project/bbr, a BBR implementation.

portus's People

Contributors

aditiharini avatar akshayknarayan avatar fcangialosi avatar otavio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

portus's Issues

Implement ABC

(ECN is now supported, so this should be do-able)

Initial communication with datapath

It may be useful for the the CCP and datapath to briefly exchange messages when the CCP is first started to:

  1. Allow the CCP to set a backup algorithm in the datapath in case the CCP crashes / datapath is no longer able to communicate with the CCP
  2. Allow the datapath to communicate which features it supports and the CCP to handle this accordingly (e.g. the algorithm could check for a list of features it needs and exit if the selected datapath doesn't provide these)

This would involve adding a new message type..

Datapath program de-duplication

@fcangialosi 's example:

impl<T: Ipc> CongAlg<T> for Bbr<T> {
  fn name() ...
  fn create() ...

  fn install_datapath_programs() {
    self.probe_rtt_program_id = portus::install_global_program(b"
        (def ... )
        (when ... )
    ")
    self.probe_bw_program_id = portus::install_global_program(b"
        (def ... )
        (when ... )
    ")
  }

  fn on_report() {
    if self.mode == probe_rtt {
      self.datapath.use_program(self.probe_rtt_program_id)
    }
    if self.mode == probe_bw {
      self.datapath.use_program(self.probe_bw_program_id)
    }
  }
}

We should de-duplicate programs, so that we can save datapath memory by avoiding storing programs per-flow. Flows share the program instructions, but obviously their state remains independent.

This subsumes #2 and #6

portus should not return scope to user

as far as i can tell, there's no reason portus needs to return the scope object to the user, just for them to pass it back in get_field. the datapath object can internally store the current scope, and then we can move the implementation to datapath.get_field("field", report) instead of `report.get_field("field", scope).

this also makes #43 easy

std::sync::mpsc ipc backend

Add a std::sync::mpsc ipc backend so that ccp can communicate using inter-thread channels to a datapath (for example, an application-integrated datapath) more conveniently and efficiently.

the question about the aimd demo

hello ,i run the aimd demo,but i meet some problem.
it is the aimd demo,and i want to print some values.(in line 19-23)

import sys
import portus

class AIMDFlow():
    INIT_CWND = 10

    def __init__(self, datapath, datapath_info):
        self.datapath = datapath
        self.datapath_info = datapath_info
        self.init_cwnd = float(self.datapath_info.mss * AIMDFlow.INIT_CWND)
        self.cwnd = self.init_cwnd
        self.datapath.set_program("default", [("Cwnd", int(self.cwnd))])

    def on_report(self, r):
        if r.loss > 0 or r.sacked > 0:
            self.cwnd /= 2
        else:
            self.cwnd += (self.datapath_info.mss * (r.acked / self.cwnd))
        print(r.acked)
        print(r.loss)
        print(r.sacked)
        #print(r.inflight)
        #print(r.rtt)
        self.cwnd = max(self.cwnd, self.init_cwnd)
        self.datapath.update_field("Cwnd", int(self.cwnd))


class AIMD(portus.AlgBase):

    def datapath_programs(self):
        return {
                "default" : """\
                (def (Report
                    (volatile acked 0) 
                    (volatile sacked 0) 
                    (volatile loss 0) 
                    (volatile timeout false)
                    (volatile rtt 0)
                    (volatile inflight 0)
                ))
                (when true
                    (:= Report.inflight Flow.packets_in_flight)
                    (:= Report.rtt Flow.rtt_sample_us)
                    (:= Report.acked (+ Report.acked Ack.bytes_acked))
                    (:= Report.sacked (+ Report.sacked Ack.packets_misordered))
                    (:= Report.loss Ack.lost_pkts_sample)
                    (:= Report.timeout Flow.was_timeout)
                    (fallthrough)
                )
                (when (|| Report.timeout (> Report.loss 0))
                    (report)
                    (:= Micros 0)
                )
                (when (> Micros Flow.rtt_sample_us)
                    (report)
                    (:= Micros 0)
                )
            """
        }

    def new_flow(self, datapath, datapath_info):
        return AIMDFlow(datapath, datapath_info)

alg = AIMD()

portus.start("netlink", alg, debug=True)


i want to print the rtt and the inflight(although they are not be used in aimd)
the teminal output

0
0
10
Traceback (most recent call last):
  File "aimd.py", line 22, in on_report
    print(r.inflight)
Exception: Failed to get inflight: portus err: the requested field is in scope but was not found in the report
ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.454 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.455 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.455 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.456 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.456 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.457 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.457 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.458 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.458 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.459 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.459 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.460 ERRO slog-async: logger dropped messages due to channel overflow, count: 1
Jul 15 22:04:35.460 ERRO slog-async: logger dropped messages due to channel overflow, count: 1

i do not know why i can print the acked and the loss but i can not print the rtt and the inflight.
Thanks for your help!

the question of the performance of ccp-bbr in Pantheon

Hello,I want to test the performance of ccp-bbr in Pantheon.but i meet some question.
i open the ccp-bbr using sudo ./target/debug/bbr --ipc netlink,
and use the ccp.py in pantheon/src/wrappers

#!/usr/bin/env python

from subprocess import check_call

import arg_parser


def main():
    args = arg_parser.receiver_first()

    if args.option == 'deps':
        print 'iperf'
        return

    if args.option == 'receiver':
        
        cmd = ['iperf', '-s', '-p', args.port]
        check_call(cmd)
        return

    if args.option == 'sender':
        cmd = ['iperf', '-c', args.ip, '-p', args.port,'-i','1','-Z','ccp',
               '-t', '75']
        check_call(cmd)
        return


if __name__ == '__main__':
    main()

i test the local mode in Pantheon,but i get confused output.
pantheon_report.pdf

and it is my output in terminal.
截屏2021-07-15 下午8 12 45

I wonder what should i do if i want to test the algorithm in Pantheon.
thanks for your help!

API to switch between algorithms at runtime

Create API support for the following binary/application:

  • knows about many implementations of CongAlg (via Cargo.toml and extern create my_cool_algorithm)
  • provides a way to map 5-tuple (information in Create) to a congestion control algorithm
  • runs the selected congestion control algorithm for that flow.

To support this, we need an additional API which is not generic over trait CongAlg (because then only one impl CongAlg can be active at a time) and instead takes a Vec<Box<CongAlg>> or similar, and a function which can take a 5-tuple and map it to one of the Box<CongAlg>.

register multiple algortihms

in the current model, a calling application creates an instance alg of some struct implementing CongAlg and then (indirectly) calls portus::run_inner(..., alg), and portus assumes all new connections from the datapath should use this alg.

this limits applications to using one ccp algorithm at a time.

rather than having a separate ccp process for each algorithm, it probably makes more sense for a single process to be able to handle connections using different algorithms.

i think the minimally invasive change to support this would be to:

  • modify run_inner to instead take a list of CongAlgs rather than just a single one
  • have libccp send the name of the algorithm it wants to use in the Create message (for backwards-compatibility we could also specify the index of a default alg so that even if libccp leaves the algorithm field blank as it currently does, portus can still do something reasonable)
  • look up the appropriate CongAlg in the list and call new_flow on that

Python bindings don't compile

error[E0061]: this function takes 3 parameters but 2 parameters were supplied
   --> src/lib.rs:242:1
    |
242 | #[py::methods]
    | ^^^^^^^^^^^^^^ expected 3 parameters

error[E0308]: mismatched types
   --> src/lib.rs:242:1
    |
242 | #[py::methods]
    | ^^^^^^^^^^^^^^ expected struct `portus::lang::Scope`, found ()
    |
    = note: expected type `portus::lang::Scope`
               found type `()`

error: aborting due to 2 previous errors

Some errors occurred: E0061, E0308.
For more information about an error, try `rustc --explain E0061`.
error: Could not compile `pyportus`.

Bindings probably have to be updated to reflect #38

Project website

Could include the tutorial, and maybe some very-high level results /graphs from the paper (in a similar vein as the remy site)

Default fold function

Add default before the first fold is sent so that you can start getting things immediately.

Might be good to quantify the difference (if any) this makes.

Datapath program comments don't compile

They can be parsed as an expression successfully (Expr::new) but there's an error somewhere else in the compilation process.

Adding these two lines to the comment() test in src/lang/ast.rs shows this:

+ 528         use lang::compile;
+ 529         assert!(compile(foo, &[]).is_ok());

This also suggests that we should add this assert to all of the tests.

weird bug in integration test with channels

just leaving these stack traces we collected here for future reference in case we want to debug this later. would be good to have a mwe we can submit to the rust folks.

(background: test hangs when trying to drop the socket at the end, we attached gdp, and ran thread apply all bt)

1:

Thread 3 (Thread 0x7f8c8e5ff700 (LWP 34442)):
#0  <std::sync::mpsc::spsc_queue::Queue<T, ProducerAddition, ConsumerAddition>>::pop (self=0x7f8c8f733040) at /checkout/src/libstd/sync/mpsc/spsc_queue.rs:175
#1  0x000055f177b453c2 in <std::sync::mpsc::stream::Packet<T>>::drop_port (self=0x7f8c8f733040) at /checkout/src/libstd/sync/mpsc/stream.rs:336
#2  0x000055f177afbb10 in <std::sync::mpsc::Receiver<T> as core::ops::drop::Drop>::drop (self=0x7f8c8e00e020) at /checkout/src/libstd/sync/mpsc/mod.rs:1607
#3  0x000055f177994261 in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#4  0x000055f1779961bd in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#5  0x000055f1779930f6 in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#6  0x000055f177998c12 in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#7  0x000055f177a06e2a in <alloc::rc::Rc<T> as core::ops::drop::Drop>::drop (self=0x7f8c8e5fda30) at /checkout/src/liballoc/rc.rs:835
#8  0x000055f17799747e in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#9  0x000055f17799621f in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#10 0x000055f1779eafe8 in portus::run_inner (backend_builder=..., cfg=0x7f8c8e5fe6a8, continue_listening=...) at /home/frank/portus/src/lib.rs:537
#11 0x000055f1779e5cda in portus::spawn::{{closure}} () at /home/frank/portus/src/lib.rs:388
#12 0x000055f177a051d8 in std::sys_common::backtrace::__rust_begin_short_backtrace (f=...) at /checkout/src/libstd/sys_common/backtrace.rs:136
#13 0x000055f177987f1a in std::thread::Builder::spawn::{{closure}}::{{closure}} () at /checkout/src/libstd/thread/mod.rs:409
#14 0x000055f1779de98d in <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once (self=..., _args=()) at /checkout/src/libstd/panic.rs:305
#15 0x000055f1779c4e8c in std::panicking::try::do_call (data=0x7f8c8e5fe9b8 "") at /checkout/src/libstd/panicking.rs:310
#16 0x000055f177bc3b0a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#17 0x000055f1779c4022 in std::panicking::try (f=...) at /checkout/src/libstd/panicking.rs:289
#18 0x000055f1779debda in std::panic::catch_unwind (f=...) at /checkout/src/libstd/panic.rs:374
#19 0x000055f177985f69 in std::thread::Builder::spawn::{{closure}} () at /checkout/src/libstd/thread/mod.rs:408
#20 0x000055f1779887e7 in <F as alloc::boxed::FnBox<A>>::call_box (self=0x7f8c8fc3f000, args=()) at /checkout/src/liballoc/boxed.rs:640
#21 0x000055f177bb0e8b in _$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h7bc0b8be53b3c638 () at /checkout/src/liballoc/boxed.rs:650
#22 std::sys_common::thread::start_thread () at libstd/sys_common/thread.rs:24
#23 0x000055f177ba02f6 in std::sys::unix::thread::Thread::new::thread_start () at libstd/sys/unix/thread.rs:90
#24 0x00007f8c90ffb6da in start_thread (arg=0x7f8c8e5ff700) at pthread_create.c:456
#25 0x00007f8c90b1ed7f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:105

Thread 2 (Thread 0x7f8c901ff700 (LWP 34433)):
#0  0x00007f8c90ffc9dd in pthread_join (threadid=140241660802816, thread_return=0x0) at pthread_join.c:90
#1  0x000055f177ba045c in std::sys::unix::thread::Thread::join () at libstd/sys/unix/thread.rs:176
#2  0x000055f177b426bb in <std::thread::JoinInner<T>>::join (self=0x7f8c901fdf30) at /checkout/src/libstd/thread/mod.rs:1203
#3  0x000055f177b42726 in <std::thread::JoinHandle<T>>::join (self=...) at /checkout/src/libstd/thread/mod.rs:1325
#4  0x000055f177b3a038 in portus::CCPHandle::wait (self=...) at /home/frank/portus/src/lib.rs:338
#5  0x000055f1779cf0fe in libccp_integration_test::scenarios::run_test (log=..., num_flows=2) at src/scenarios/mod.rs:140
#6  0x000055f17796faa4 in libccp_integration_test::scenarios::twoflow::test::test () at src/scenarios/twoflow.rs:77
#7  0x000055f177a055ca in libccp_integration_test::__test::TESTS::{{closure}} () at src/scenarios/twoflow.rs:72
#8  0x000055f177992b3e in core::ops::function::FnOnce::call_once () at /checkout/src/libcore/ops/function.rs:223
#9  0x000055f177a37e1f in test::run_test::{{closure}} () at libtest/lib.rs:1451
#10 core::ops::function::FnOnce::call_once () at /checkout/src/libcore/ops/function.rs:223
#11 <F as alloc::boxed::FnBox<A>>::call_box () at /checkout/src/liballoc/boxed.rs:640
#12 0x000055f177bc3b0a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#13 0x000055f177a5458e in std::panicking::try () at /checkout/src/libstd/panicking.rs:289
#14 std::panic::catch_unwind () at /checkout/src/libstd/panic.rs:374
#15 test::run_test::run_test_inner::{{closure}} () at libtest/lib.rs:1406
#16 std::sys_common::backtrace::__rust_begin_short_backtrace () at /checkout/src/libstd/sys_common/backtrace.rs:136
#17 0x000055f177a59465 in std::thread::Builder::spawn::{{closure}}::{{closure}} () at /checkout/src/libstd/thread/mod.rs:409
#18 <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once () at /checkout/src/libstd/panic.rs:305
#19 std::panicking::try::do_call () at /checkout/src/libstd/panicking.rs:310
#20 0x000055f177bc3b0a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#21 0x000055f177a4aa17 in std::panicking::try () at /checkout/src/libstd/panicking.rs:289
#22 std::panic::catch_unwind () at /checkout/src/libstd/panic.rs:374
#23 std::thread::Builder::spawn::{{closure}} () at /checkout/src/libstd/thread/mod.rs:408
#24 <F as alloc::boxed::FnBox<A>>::call_box () at /checkout/src/liballoc/boxed.rs:640
#25 0x000055f177bb0e8b in _$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h7bc0b8be53b3c638 () at /checkout/src/liballoc/boxed.rs:650
#26 std::sys_common::thread::start_thread () at libstd/sys_common/thread.rs:24
#27 0x000055f177ba02f6 in std::sys::unix::thread::Thread::new::thread_start () at libstd/sys/unix/thread.rs:90
#28 0x00007f8c90ffb6da in start_thread (arg=0x7f8c901ff700) at pthread_create.c:456
#29 0x00007f8c90b1ed7f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:105

2:

Thread 3 (Thread 0x7f4d973ff700 (LWP 33459)):
#0  0x00005581bc83ef51 in <std::sync::mpsc::spsc_queue::Queue<T, ProducerAddition, ConsumerAddition>>::pop (self=0x7f4d98333040) at /checkout/src/libstd/sync/mpsc/spsc_queue.rs:177
#1  0x00005581bc8816f2 in <std::sync::mpsc::stream::Packet<T>>::drop_port (self=0x7f4d98333040) at /checkout/src/libstd/sync/mpsc/stream.rs:336
#2  0x00005581bc837b40 in <std::sync::mpsc::Receiver<T> as core::ops::drop::Drop>::drop (self=0x7f4d973fd2a0) at /checkout/src/libstd/sync/mpsc/mod.rs:1607
#3  0x00005581bc8197e1 in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#4  0x00005581bc81a25d in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#5  0x00005581bc84ea4c in <portus::ipc::chan::Socket<T>>::__close (self=0x7f4d96e0e010) at /home/frank/portus/src/ipc/chan.rs:37
#6  0x00005581bc8559cb in <portus::ipc::chan::Socket<portus::ipc::Blocking> as portus::ipc::Ipc>::close (self=0x7f4d96e0e010) at /home/frank/portus/src/ipc/chan.rs:60
#7  0x00005581bc71e14a in <portus::ipc::Backend<'a, T> as core::ops::drop::Drop>::drop::{{closure}} (s=0x7f4d96e0e010) at /home/frank/portus/src/ipc/mod.rs:158
#8  0x00005581bc6b6dd6 in <core::result::Result<T, E>>::and_then (self=..., op=...) at /checkout/src/libcore/result.rs:621
#9  0x00005581bc71e116 in <portus::ipc::Backend<'a, T> as core::ops::drop::Drop>::drop (self=0x7f4d973fda30) at /home/frank/portus/src/ipc/mod.rs:156
#10 0x00005581bc6d21d1 in core::ptr::drop_in_place () at /checkout/src/libcore/ptr.rs:59
#11 0x00005581bc726fe8 in portus::run_inner (backend_builder=..., cfg=0x7f4d973fe6a8, continue_listening=...) at /home/frank/portus/src/lib.rs:537
#12 0x00005581bc721cda in portus::spawn::{{closure}} () at /home/frank/portus/src/lib.rs:388
#13 0x00005581bc7411d8 in std::sys_common::backtrace::__rust_begin_short_backtrace (f=...) at /checkout/src/libstd/sys_common/backtrace.rs:136
#14 0x00005581bc6c3f1a in std::thread::Builder::spawn::{{closure}}::{{closure}} () at /checkout/src/libstd/thread/mod.rs:409
#15 0x00005581bc71a98d in <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once (self=..., _args=()) at /checkout/src/libstd/panic.rs:305
#16 0x00005581bc700e8c in std::panicking::try::do_call (data=0x7f4d973fe9b8 "") at /checkout/src/libstd/panicking.rs:310
#17 0x00005581bc8ffe3a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#18 0x00005581bc700022 in std::panicking::try (f=...) at /checkout/src/libstd/panicking.rs:289
#19 0x00005581bc71abda in std::panic::catch_unwind (f=...) at /checkout/src/libstd/panic.rs:374
#20 0x00005581bc6c1f69 in std::thread::Builder::spawn::{{closure}} () at /checkout/src/libstd/thread/mod.rs:408
#21 0x00005581bc6c47e7 in <F as alloc::boxed::FnBox<A>>::call_box (self=0x7f4d9883f000, args=()) at /checkout/src/liballoc/boxed.rs:640
#22 0x00005581bc8ed1bb in _$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h7bc0b8be53b3c638 () at /checkout/src/liballoc/boxed.rs:650
#23 std::sys_common::thread::start_thread () at libstd/sys_common/thread.rs:24
#24 0x00005581bc8dc626 in std::sys::unix::thread::Thread::new::thread_start () at libstd/sys/unix/thread.rs:90
#25 0x00007f4d99b856da in start_thread (arg=0x7f4d973ff700) at pthread_create.c:456
#26 0x00007f4d996a8d7f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:105

Thread 2 (Thread 0x7f4d98dff700 (LWP 33450)):
#0  0x00007f4d99b869dd in pthread_join (threadid=139971226760960, thread_return=0x0) at pthread_join.c:90
#1  0x00005581bc8dc78c in std::sys::unix::thread::Thread::join () at libstd/sys/unix/thread.rs:176
#2  0x00005581bc87e9eb in <std::thread::JoinInner<T>>::join (self=0x7f4d98dfdf30) at /checkout/src/libstd/thread/mod.rs:1203
#3  0x00005581bc87ea56 in <std::thread::JoinHandle<T>>::join (self=...) at /checkout/src/libstd/thread/mod.rs:1325
#4  0x00005581bc876368 in portus::CCPHandle::wait (self=...) at /home/frank/portus/src/lib.rs:338
#5  0x00005581bc70b0fe in libccp_integration_test::scenarios::run_test (log=..., num_flows=2) at src/scenarios/mod.rs:140
---Type <return> to continue, or q <return> to quit---
#6  0x00005581bc6abaa4 in libccp_integration_test::scenarios::twoflow::test::test () at src/scenarios/twoflow.rs:77
#7  0x00005581bc7415ca in libccp_integration_test::__test::TESTS::{{closure}} () at src/scenarios/twoflow.rs:72
#8  0x00005581bc6ceb3e in core::ops::function::FnOnce::call_once () at /checkout/src/libcore/ops/function.rs:223
#9  0x00005581bc773e1f in test::run_test::{{closure}} () at libtest/lib.rs:1451
#10 core::ops::function::FnOnce::call_once () at /checkout/src/libcore/ops/function.rs:223
#11 <F as alloc::boxed::FnBox<A>>::call_box () at /checkout/src/liballoc/boxed.rs:640
#12 0x00005581bc8ffe3a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#13 0x00005581bc79058e in std::panicking::try () at /checkout/src/libstd/panicking.rs:289
#14 std::panic::catch_unwind () at /checkout/src/libstd/panic.rs:374
#15 test::run_test::run_test_inner::{{closure}} () at libtest/lib.rs:1406
#16 std::sys_common::backtrace::__rust_begin_short_backtrace () at /checkout/src/libstd/sys_common/backtrace.rs:136
#17 0x00005581bc795465 in std::thread::Builder::spawn::{{closure}}::{{closure}} () at /checkout/src/libstd/thread/mod.rs:409
#18 <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once () at /checkout/src/libstd/panic.rs:305
#19 std::panicking::try::do_call () at /checkout/src/libstd/panicking.rs:310
#20 0x00005581bc8ffe3a in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:105
#21 0x00005581bc786a17 in std::panicking::try () at /checkout/src/libstd/panicking.rs:289
#22 std::panic::catch_unwind () at /checkout/src/libstd/panic.rs:374
#23 std::thread::Builder::spawn::{{closure}} () at /checkout/src/libstd/thread/mod.rs:408
#24 <F as alloc::boxed::FnBox<A>>::call_box () at /checkout/src/liballoc/boxed.rs:640
#25 0x00005581bc8ed1bb in _$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h7bc0b8be53b3c638 () at /checkout/src/liballoc/boxed.rs:650
#26 std::sys_common::thread::start_thread () at libstd/sys_common/thread.rs:24
#27 0x00005581bc8dc626 in std::sys::unix::thread::Thread::new::thread_start () at libstd/sys/unix/thread.rs:90
#28 0x00007f4d99b856da in start_thread (arg=0x7f4d98dff700) at pthread_create.c:456
#29 0x00007f4d996a8d7f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:105

Log Levels

portus::algs::make_logger() should take a log level argument.

Primitives Extensions API

Some datapaths may not support certain primitives (for example, QUIC does not currently support ECN).

To handle these cases, datapath programs which query datapath-unsupported primitives should not compile on those datapaths.

This requires multiple changes:

  1. Extract a "minimal set" of primitives that all datapaths must support.
  2. Create an "Extensions API" so datapaths can define custom additional primitives (in libccp)
  3. Allow datapaths to express to the compiler which primitives they support, so the compiler knows what should compile.
  4. Modify the error handling in the compiler to explain the idea of unsupported primitives to users.

IPC should do serialization at last possible opportunity

For channel-type communication mechanisms (#36), there's no need for serialization, so doing it and passing IPC a byte array is inefficient.

Instead, ipc::send could take an impl AsRawMsg and do the serialization as the last step when necessary (otherwise just passing the struct along the channel with serialization = a no-op)

Catch up mTCP

Get mTCP datapath up to date with all of the latest API changes, re-run some of the experiments for the camera-ready, and release the code.

Tutorial

  1. Tutorial for getting started with ccp: setup, how to write an algorithm, explain the API
  2. A sample starter repo (portus submodule, Makefile, initial src/lib.rs, etc.) or an initialization script that creates all of this

default program

Currently, until the CCP runs create and it responds with a set program message, all packets received for that flow will not be received by any datapath program. It may be useful, especially for low-RTT paths or cases where CCP is dealing with many flows at once, to have a default program that runs immediately when a flow begins so that it is not dependent on the time it takes CCP to respond and install a program.

One potential idea is to add a default_program() -> (String, Option<args>) method to CongAlg (or to add it to the return value of init_programs) but the problem is that installing programs returns a scope, and you would have no way to save or access this scope later. Passing the scope to create seems weird. We might need to restructure things to make this more natural.

Implement DCTCP

Already partially implemented, just need to update to use the new API and handle the comment from the previous issue:

DCTCP cuts its cwnd upon every ECN-marked packet, based on the existing alpha estimate.

So, we should update the window in ccp like so: cwnd *= (1-old_alpha/2)^(k-1), where old_alpha is the alpha value before the new RTTs worth of ECN fractions, and k is the number of packets marked in the past RTT.

Then, update alpha using the EWMA estimator as normal.

Remove submodules

We currently have libccp and ccp-kernel (which also submodules libccp) as submodules in this repo purely for the purpose of integration testing. This causes a bit of a headache when we make changes in libccp and everything has to be propagated up. I think it would be just as good (and remove the dependencies) if we instead created a script that just git clones the repos when the integration test is run, rather than explicitly having them as submodules. Travis CI will still work essentially the same, just the repo won't specifically track the submodules. Should be a simple change.

python: fix ownership and memory allocation

pyo3 documentation is rather sparse, so python bindings work, but are a bit buggy, and my hunch is that it's because there are some bugs with ownership and (lack of) memory de-allocation.

Potentially related, ctrl+c doesn't kill a python algorithm, so that should be fixed too.

Unable to install pyportus from source

I have to build pyporuts from source since the latest python version of it could not be found in pip. I followed the instructions in python/README.md but could not proceed with it.

System Info:

Ubuntu 18.04
Linux kernel: 4.15.0-70-generic
Python: Python 3.6.0 (default)[GCC 7.4.0] on linux
pip: Python3-pip
cargo: cargo 1.37.0
rustc: rustc 1.37.0

I installed rustc & cargo by sudo apt install rustc and installed setuptool_rust by sudo pip3 install setuptool_rust . I also modified build.py in setuptool_rust following the README.

Error Message:

cargo rustc +nightly --lib --manifest-path Cargo.toml --features pyo3/python3 pyo3/extension-module --verbose -- --crate-type cdylib
   Compiling spin v0.4.10
error[E0554]: #![feature] may not be used on the stable release channel
 --> /home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/spin-0.4.10/src/lib.rs:6:35
  |
6 | #![cfg_attr(feature = "const_fn", feature(const_fn))]
  |                                   ^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
error: Could not compile `spin`.

To learn more, run the command again with --verbose.
error: cargo failed with code: 101

I found it doesn't compile whether or not add nightly in build.py.

Looking forward to your kind help. Thanks!

the question about the aimd demo

hello ,i run the aimd demo,but i meet some problem.

import sys
import portus

class AIMDFlow():
    INIT_CWND = 10

    def __init__(self, datapath, datapath_info):
        self.datapath = datapath
        self.datapath_info = datapath_info
        self.init_cwnd = float(self.datapath_info.mss * AIMDFlow.INIT_CWND)
        self.cwnd = self.init_cwnd
        self.datapath.set_program("default", [("Cwnd", int(self.cwnd))])

    def on_report(self, r):
        if r.loss > 0 or r.sacked > 0:
            self.cwnd /= 2
        else:
            self.cwnd += (self.datapath_info.mss * (r.acked / self.cwnd))
        print(r.acked)
        print(r.loss)
        print(r.sacked)
        #print(r.inflight)
        #print(r.rtt)
        self.cwnd = max(self.cwnd, self.init_cwnd)
        self.datapath.update_field("Cwnd", int(self.cwnd))


class AIMD(portus.AlgBase):

    def datapath_programs(self):
        return {
                "default" : """\
                (def (Report
                    (volatile acked 0) 
                    (volatile sacked 0) 
                    (volatile loss 0) 
                    (volatile timeout false)
                    (volatile rtt 0)
                    (volatile inflight 0)
                ))
                (when true
                    (:= Report.inflight Flow.packets_in_flight)
                    (:= Report.rtt Flow.rtt_sample_us)
                    (:= Report.acked (+ Report.acked Ack.bytes_acked))
                    (:= Report.sacked (+ Report.sacked Ack.packets_misordered))
                    (:= Report.loss Ack.lost_pkts_sample)
                    (:= Report.timeout Flow.was_timeout)
                    (fallthrough)
                )
                (when (|| Report.timeout (> Report.loss 0))
                    (report)
                    (:= Micros 0)
                )
                (when (> Micros Flow.rtt_sample_us)
                    (report)
                    (:= Micros 0)
                )
            """
        }

    def new_flow(self, datapath, datapath_info):
        return AIMDFlow(datapath, datapath_info)

alg = AIMD()

portus.start("netlink", alg, debug=True)


i want to print the rtt and the inflight(although they are not be used in aimd)
the teminal output

0
0
10
Traceback (most recent call last):
  File "aimd.py", line 22, in on_report
    print(r.inflight)
Exception: Failed to get inflight: portus err: the requested field is in scope but was not found in the report
ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.454 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.455 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.455 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.456 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.456 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.457 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.457 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.458 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.458 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.459 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.459 ERRO on_report() failed to complete, sid: 1
Jul 15 22:04:35.460 ERRO slog-async: logger dropped messages due to channel overflow, count: 1
Jul 15 22:04:35.460 ERRO slog-async: logger dropped messages due to channel overflow, count: 1

i do not know the reason why i can print the acked and the loss but i can not print the rtt and the inflight.
Thanks for your help!

nit: in python, init_programs should not take self

This is confusing, as it may seem like one can call datapath methods in init_programs, but datapath and datapath_info have not been created yet. This involves changing the rust code to call a python class method rather than creating a shim instance and calling it as an instance method.

More compiler checks

Towards mitigating bugs in datapath programs, it'd be nice if the compiler

  1. Required when clauses to have at least one statement (must indicate an error because otherwise the clause does nothing)
  2. No statements outside of a when clause (it will never have a chance to execute, so it's probably not what the user intended)

Question about running multiple congestion control algorithms at the same time

About running multiple algorithms at the same time, I have read #85, but I wonder if there is an easier way for me to perform multiple emulation experiments at the same time without modifying the source code?

Algorithms implemented use args like --ipc netlink, does it mean that I cannot run multiple ccp_kernel to perform multiple CCAs at the same time?

Or which file in source code should I modify to support this feature?

Datapath program versioning

Sometimes, we may get a report from an old fold function even after we install a new one. In this case, the variables may no longer exist, or worse they may point to a different value.

We should add fields to the install and report messages that version the reports, so we can discard out-of-date ones.

Flow aggregation

create an interface and a proof-of-concept implementation which performs congestion control on several flows as a single unit.

To start off, let's write a reno implementation which equalizes its window across its sub-flows.

portus and libccp api version numbers

we should tag versions for the interface between portus and libccp. when portus starts up, it should send it's version to the datapath, and only be allowed to proceed if the version matches. the main annoyance is that we need to remember to bump this version each time we change the api, and i'm not sure if there's a more elegant way than just keeping a constant inside both that we try to remember to update manually.

Potential bug of stuck

I have been testing BBR (update branch) and found that BBR always got stuck (no more console outputs) some time after beginning.
For example,

Jan 23 09:26:02.768 INFO switching to PROBE_BW, min rtt (us): 41764, Rate (5/4): 1.25, bottle rate (Mbps): 1, Rate (3/4): 0.75, cwnd: 10441
Jan 23 09:26:02.768 INFO PROBE_RTT, min_rtt (us): 41764
Jan 23 09:26:05.258 INFO probe_bw, bottle rate (Mbps): 1, rate (Mbps): 0, elapsed: 0.522
Jan 23 09:26:05.258 INFO new min_rtt, bottle rate: 1, min_rtt (us): 196893
Jan 23 09:26:05.259 INFO new_flow
Jan 23 09:26:05.259 INFO switching to PROBE_BW, min rtt (us): 196893, Rate (5/4): 1.25, bottle rate (Mbps): 1, Rate (3/4): 0.75, cwnd: 49223

after 09:26:05, I got no more outputs.

After tracing down the flow, I found the stuck point always at the "send_msg(&buf[..])" function. Specifically, it is either at
portus->lib.rs->set_program->self.sender.send_msg(&buf[..])?; (around line 186)
or
portus->lib.rs->update_field->self.sender.send_msg(&buf[..])?; (around line 230).

This is identified by adding println! lines in the files, the output of which is as below:
Jan 23 16:14:53.025 INFO new min_rtt, bottle rate: 1, min_rtt (us): 7288
in portus: while ...........
in portus: new measurement ...........
in bbr: on_report--------------------
in bbr, on_report: ProbeBw --------------------
in bbr, on_report: ProbeBw, before init --------------------
in bbr: install_probe_bw--------------------
in portus: update_field .................
Jan 23 16:14 in portus: update_field, before send_msg, buf: [3, 0, 38, 0, 59, 0, 0, 0, 2, 0, 0, 0, 2, 4, 0, 0, 0, 101, 255, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 90, 98, 2, 0, 0, 0, 0, 0]
:53.040 INFO probe_bw, bottle rate (Mbps): 1, rate (Mbps): 0, elapsed: 0.717
Jan 23 16:14:53.041 INFO new min_rtt, bottle rate: 1, min_rtt (us): 261525
Jan 23 16:14:53.041 INFO new_flow
Jan 23 16:14:53.041 INFO switching to PROBE_BW, min rtt (us): 261525, Rate (5/4): 1.25, bottle rate (Mbps): 1, Rate (3/4): 0.75, cwnd: 65381
(then it gets stuck and gives no more output)

I suspect the reason is that the TCP connection is destroyed unexpectedly, e.g. due to timeout.

Environment:
Ubuntu 18.04, default kernel.
Wireless network connection, unstable.

Hope the team can fix it.
Thanks.

the question about the Learning-based algorithm

Hello ,i am m trying to integrate our learning-based algorithms into the ccp,but i meet some problem.
it is the AIMD demo , and the only different part from the origin demo in line 20(self.actor = model.Network([5,8], 6, 1e-4))
i can run the origin demo ,but i can not run the demo that adds the line 20.

import sys
import portus
import time
import numpy as np
import datagram_pb2
import model
from os import path


class AIMDFlow():
    INIT_CWND = 10

    def __init__(self, datapath, datapath_info):
        self.datapath = datapath
        self.datapath_info = datapath_info
        self.init_cwnd = float(self.datapath_info.mss * AIMDFlow.INIT_CWND)
        self.cwnd = self.init_cwnd
        self.datapath.set_program("default", [("Cwnd", int(self.cwnd))])
        # the only different part from the origin demo
        self.actor = model.Network([5,8], 6, 1e-4)

    def on_report(self, r):
        if r.loss > 0 or r.sacked > 0:
            self.cwnd /= 2
        else:
            self.cwnd += (self.datapath_info.mss * (r.acked / self.cwnd))
        self.cwnd = max(self.cwnd, self.init_cwnd)
        self.datapath.update_field("Cwnd", int(self.cwnd))


class AIMD(portus.AlgBase):

    def datapath_programs(self):
        return {
                "default" : """\
                (def (Report
                    (volatile acked 0) 
                    (volatile sacked 0) 
                    (volatile loss 0) 
                    (volatile timeout false)
                    (volatile rtt 0)
                    (volatile inflight 0)
                ))
                (when true
                    (:= Report.inflight Flow.packets_in_flight)
                    (:= Report.rtt Flow.rtt_sample_us)
                    (:= Report.acked (+ Report.acked Ack.bytes_acked))
                    (:= Report.sacked (+ Report.sacked Ack.packets_misordered))
                    (:= Report.loss Ack.lost_pkts_sample)
                    (:= Report.timeout Flow.was_timeout)
                    (fallthrough)
                )
                (when (|| Report.timeout (> Report.loss 0))
                    (report)
                    (:= Micros 0)
                )
                (when (> Micros Flow.rtt_sample_us)
                    (report)
                    (:= Micros 0)
                )
            """
        }

    def new_flow(self, datapath, datapath_info):
        return AIMDFlow(datapath, datapath_info)

alg = AIMD()

portus.start("netlink", alg, debug=True)

and it is my model.py,everytime when it run to the line ( self.pi = self.CreateNetwork(inputs=self.inputs) ),it report Segmentation fault.(i`m sure that this part can run successfully apart from ccp )

class Network():
    def CreateNetwork(self, inputs):
        with tf.variable_scope('actor'):
            pi = tf.contrib.layers.fully_connected(inputs, self.a_dim)
        return pi
    def __init__(self, state_dim, action_dim, learning_rate):
        self.s_dim = state_dim
        self.a_dim = action_dim
        self.lr_rate = learning_rate

        self.sess = tf.Session()

        self.inputs = tf.placeholder(tf.float32, [None, self.s_dim[0], self.s_dim[1]])
      
        self.pi = self.CreateNetwork(inputs=self.inputs)
        self.real_out = tf.clip_by_value(self.pi, ACTION_EPS, 1. - ACTION_EPS)
        
        self.sess.run(tf.global_variables_initializer())
    

so,i wonder whether ccp does not support learning-based algorithms.
What should I do if I want to integrate the algorithm?

I would be very grateful for your suggestions

channel IPC sometimes segfaults when running integration tests

[integration-multiflow] ~/mit/portus/integration_tests/libccp_integration $ RUST_BACKTRACE=1 DYLD_LIBRARY_PATH=./libccp cargo +nightly t twoflow -- --test-threads=1
    Finished dev [unoptimized + debuginfo] target(s) in 0.13s
     Running target/debug/deps/libccp_integration_test-a88f2155dd0d9e04

running 1 test
test scenarios::twoflow::test::test ... Sep 24 13:38:16.912 INFO starting CCP, ipc: channel, algorithm: integration-test
reading...
Sep 24 13:38:16.913 DEBG creating new flow, dst_port: 4, dst_ip: 3, src_port: 1, src_ip: 0, mss: 1500, init_cwnd: 15000, sid: 1
reading...
start flow 1
reading...
Sep 24 13:38:16.913 DEBG creating new flow, dst_port: 4, dst_ip: 3, src_port: 1, src_ip: 0, mss: 1500, init_cwnd: 15000, sid: 2
start flow 2
reading...
reading...
thread '<unnamed>' panicked at 'assertion failed: (*next).value.is_some()', libstd/sync/mpsc/spsc_queue.rs:178:13
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at libstd/panicking.rs:477
   5: core::num::NonZeroUsize::get
             at libstd/panicking.rs:411
   6: portus::lang::datapath::Scope::update_type::{{closure}}
             at libstd/macros.rs:72
   7: portus::lang::compile::{{closure}}
             at libstd/sync/mpsc/stream.rs:229
   8: core::fmt::Arguments::new_v1
             at libstd/sync/mpsc/mod.rs:1105
   9: core::fmt::Arguments::new_v1
             at libstd/sync/mpsc/mod.rs:1322
  10: portus::lang::prog::event::unify_types
             at /Users/frank/mit/portus/src/ipc/chan.rs:54
  11: <portus::ipc::Backend<'a, T>>::get_next_read
             at /Users/frank/mit/portus/src/ipc/mod.rs:132
  12: <portus::ipc::Backend<'a, T>>::next
             at /Users/frank/mit/portus/src/ipc/mod.rs:114
  13: portus::run_inner
             at /Users/frank/mit/portus/src/lib.rs:457
  14: portus::spawn::{{closure}}
             at /Users/frank/mit/portus/src/lib.rs:387
thread '<unnamed>' panicked at 'assertion failed: (*next).value.is_some()', libstd/sync/mpsc/spsc_queue.rs:178:13
stack backtrace:
   0:        0x104cb825f - std::sys::unix::backtrace::tracing::imp::unwind_backtrace::h52c6c58e2488ad49
                               at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1:        0x104ca603d - std::sys_common::backtrace::print::hd645e3463a7df38f
                               at libstd/sys_common/backtrace.rs:71
                               at libstd/sys_common/backtrace.rs:59
   2:        0x104cbace3 - std::panicking::default_hook::{{closure}}::h2252caa0d2730de3
                               at libstd/panicking.rs:211
   3:        0x104cbaa6c - std::panicking::default_hook::h6fc6a32840d7680d
                               at libstd/panicking.rs:227
   4:        0x104cbb3d7 - <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get::h4e4ef2b1b5e2faec
                               at libstd/panicking.rs:477
   5:        0x104c877c7 - core::num::NonZeroUsize::get::h657d709dc0d0d5bb
                               at libstd/panicking.rs:411
   6:        0x104bc2768 - portus::lang::datapath::Scope::update_type::{{closure}}::h5c9e5cb85df241da
                               at libstd/macros.rs:72
   7:        0x104c1c991 - portus::lang::compile::{{closure}}::hbfa3015ee533d543
                               at libstd/sync/mpsc/stream.rs:336
   8:        0x104c383d4 - core::fmt::Arguments::new_v1::h18e1991bfecbff73
                               at libstd/sync/mpsc/mod.rs:1635
   9:        0x104c22c24 - core::ptr::drop_in_place::h8f0d41b801d60396
                               at libcore/ptr.rs:59
  10:        0x104c20d37 - core::ptr::drop_in_place::h293aed3fde557528
                               at libcore/ptr.rs:59
  11:        0x104c17ca4 - <portus::ipc::chan::Socket<T>>::__close::h27c0b92ecc3296e0
                               at /Users/frank/mit/portus/src/ipc/chan.rs:37
  12:        0x104c0eceb - portus::lang::prog::event::unify_types::hca78fbc48bef4d6b
                               at /Users/frank/mit/portus/src/ipc/chan.rs:60
  13:        0x104acd40b - <portus::ipc::Backend<'a, T> as core::ops::drop::Drop>::drop::{{closure}}::h02e833a4ff2b5d2a
                               at /Users/frank/mit/portus/src/ipc/mod.rs:150
  14:        0x104b0a223 - <core::result::Result<T, E>>::and_then::h06807b8d8981aba0
                               at libcore/result.rs:647
  15:        0x104acd3d2 - <portus::ipc::Backend<'a, T> as core::ops::drop::Drop>::drop::h28de79c0c03b83d6
                               at /Users/frank/mit/portus/src/ipc/mod.rs:148
  16:        0x104a98524 - core::ptr::drop_in_place::h5857a98a545659b2
                               at libcore/ptr.rs:59
  17:        0x104b349b3 - portus::run_inner::h8dffc9add6d669a8
                               at /Users/frank/mit/portus/src/lib.rs:529
  18:        0x104b30131 - portus::spawn::{{closure}}::h81ba64926f5a4f54
                               at /Users/frank/mit/portus/src/lib.rs:387
  19:        0x104b435cc - std::sys_common::backtrace::__rust_begin_short_backtrace::h57f6332f9eecf14e
                               at libstd/sys_common/backtrace.rs:136
  20:        0x104b532f9 - std::thread::Builder::spawn::{{closure}}::{{closure}}::h8e035ce7a53717af
                               at libstd/thread/mod.rs:409
  21:        0x104aee1fc - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h61895d659ae673d7
                               at libstd/panic.rs:313
  22:        0x104afd9d5 - std::panicking::try::do_call::hd1c82b81c98ef99f
                               at libstd/panicking.rs:310
  23:        0x104cc8ece - panic_unwind::imp::find_eh_action::{{closure}}::hbd7b3b81641e1b8f
                               at libpanic_unwind/lib.rs:102
  24:        0x104afb5b3 - std::panicking::try::h37f37985af36493f
                               at libstd/panicking.rs:289
  25:        0x104aee9d9 - std::panic::catch_unwind::h91a8b7ed4a185e0e
                               at libstd/panic.rs:392
  26:        0x104b51b3d - std::thread::Builder::spawn::{{closure}}::hafc1c88b5ded1f00
                               at libstd/thread/mod.rs:408
  27:        0x104b53ef7 - <F as alloc::boxed::FnBox<A>>::call_box::hd369c317dab86cfd
                               at liballoc/boxed.rs:661
  28:        0x104cba3a7 - std::sys_common::thread::start_thread::hea6bc09bd7f77d31
                               at liballoc/boxed.rs:671
                               at libstd/sys_common/thread.rs:24
  29:        0x104ca4f68 - std::sys::unix::thread::Thread::new::thread_start::h1e13f57e9a40a88d
                               at libstd/sys/unix/thread.rs:90
  30:     0x7fffac73c93a - _pthread_body
  31:     0x7fffac73c886 - _pthread_start
thread panicked while panicking. aborting.
error: process didn't exit successfully: `/Users/frank/mit/portus/integration_tests/libccp_integration/target/debug/deps/libccp_integration_test-a88f2155dd0d9e04 twoflow --test-threads=1` (signal: 4, SIGILL: illegal instruction)

IPC Benchmark

  • Create a new benchmark for IPC: one which also measures the staleness of data (benchmark using both netlink, unix sockets + character device), including process scheduling overhead
  • possibly, figure out a way to update written messages with more up-to-date ones, in case a message is written, and a new one arrives before the process is scheduled.
  • The benchmark should also quantify the impact of reserving a core for the userspace process.

(Although we don't need to add this to the paper anymore, it might be nice to know this for discussions at sigcomm).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.