// File: Barath-Kannan[P]SignalsAndSlots/test/SignalTest_Parametrized.cpp
// Function: SignalTestParametrized_LengthyUsage_Test::TestBody()
TEST_P(SignalTestParametrized, LengthyUsage) {
    auto func = ([this](sigType x) {
        std::this_thread::sleep_for(std::chrono::nanoseconds(params.nOperations*1000));
        completedFunctions.fetch_add(1);
    });

    Signal<sigType> signal(params.threadSafe);
    cout << "Connecting " << params.nConnections << " functions" << endl;
    for (uint32_t i = 0; i < params.nConnections; i++) {
        signal.connectSlot(params.scheme, func);
    }

    FunctionTimeRegular<> printer([this]() {
        cout << "Total elements emitted: " << counter << " / " << params.nEmissions << fixed << endl;
        cout << "Emission rate: " << (double) counter / bt.getElapsedMilliseconds() << fixed << "m/ms" << endl;
        cout << "Total elements processed: " << completedFunctions << " / " << params.nEmissions * params.nConnections << fixed << endl;
        cout << "Operation rate: " << (double) completedFunctions * params.nOperations / bt2.getElapsedNanoseconds() << "m/ns" << endl;
        return (bt2.getElapsedSeconds() < 6000);
    }, std::chrono::milliseconds(500));

    FunctionTimeRegular<> checkFinished([this]() {
        return (completedFunctions != params.nEmissions * params.nConnections);
    }, std::chrono::milliseconds(1));

    cout << "Starting emission thread: " << endl;
    
    thread emitter([this, &signal]() {
        bt2.start();
        bt.start();
        for (counter=0; counter<params.nEmissions; ++counter) {
            signal.emitSignal(1);
        }
        bt.stop();
    });
    cout << "Emission thread spawned" << endl;
    
    cout.precision(std::numeric_limits<double>::max_digits10);
    emitter.join();
    cout << "Emission completed" << endl;
    checkFinished.join();
    bt2.stop();
    printer.stopAndJoin();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x350, %rsp            # imm = 0x350
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x310(%rbp)
movq %rax, -0x10(%rbp)
movzbl 0x28(%rax), %esi
andl $0x1, %esi
leaq -0x128(%rbp), %rdi
callq 0x52f30
movq 0xac550(%rip), %rdi     # 0xfafb8
leaq 0x587dc(%rip), %rsi     # 0xa724b
callq 0xd640
movq %rax, -0x308(%rbp)
jmp 0x4ea7d
movq -0x308(%rbp), %rdi
movq -0x310(%rbp), %rax
movl 0x18(%rax), %esi
callq 0xd9b0
movq %rax, -0x318(%rbp)
jmp 0x4ea9c
movq -0x318(%rbp), %rdi
leaq 0x587ad(%rip), %rsi     # 0xa7257
callq 0xd640
movq %rax, -0x320(%rbp)
jmp 0x4eab8
movq -0x320(%rbp), %rdi
movq 0xac4ca(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4eacd
movl $0x0, -0x138(%rbp)
movq -0x310(%rbp), %rcx
movl -0x138(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4eb86
movq -0x310(%rbp), %rax
movl 0x2c(%rax), %eax
movl %eax, -0x32c(%rbp)
leaq -0x158(%rbp), %rdi
movq %rdi, -0x328(%rbp)
leaq -0x10(%rbp), %rsi
callq 0x4ee50
movl -0x32c(%rbp), %esi
movq -0x328(%rbp), %rdx
leaq -0x128(%rbp), %rdi
callq 0x52f60
jmp 0x4eb2f
leaq -0x158(%rbp), %rdi
callq 0x52fe0
movl -0x138(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x138(%rbp)
jmp 0x4ead7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
jmp 0x4ee36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x52fe0
jmp 0x4ee36
movq -0x310(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0x208(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x4eee0
movl $0x1f4, -0x21c(%rbp)    # imm = 0x1F4
leaq -0x218(%rbp), %rdi
leaq -0x21c(%rbp), %rsi
callq 0x1d220
jmp 0x4ebc6
leaq -0x1e8(%rbp), %rdi
leaq -0x208(%rbp), %rsi
leaq -0x218(%rbp), %rdx
callq 0x53000
jmp 0x4ebe2
leaq -0x208(%rbp), %rdi
callq 0x23f80
movq -0x310(%rbp), %rax
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x4ef70
movl $0x1, -0x2e4(%rbp)
leaq -0x2e0(%rbp), %rdi
leaq -0x2e4(%rbp), %rsi
callq 0x1d220
jmp 0x4ec2e
leaq -0x2b0(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
leaq -0x2e0(%rbp), %rdx
callq 0x53000
jmp 0x4ec4a
leaq -0x2d0(%rbp), %rdi
callq 0x23f80
movq 0xac35b(%rip), %rdi     # 0xfafb8
leaq 0x585fe(%rip), %rsi     # 0xa7262
callq 0xd640
movq %rax, -0x338(%rbp)
jmp 0x4ec72
movq -0x338(%rbp), %rdi
movq 0xac310(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4ec87
movq -0x310(%rbp), %rax
movq %rax, -0x300(%rbp)
leaq -0x128(%rbp), %rax
movq %rax, -0x2f8(%rbp)
leaq -0x2f0(%rbp), %rdi
leaq -0x300(%rbp), %rsi
callq 0x4f000
jmp 0x4ecb8
movq 0xac2f9(%rip), %rdi     # 0xfafb8
leaq 0x585b7(%rip), %rsi     # 0xa727d
callq 0xd640
movq %rax, -0x340(%rbp)
jmp 0x4ecd4
movq -0x340(%rbp), %rdi
movq 0xac2ae(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4ece9
movq 0xac2c8(%rip), %rdi     # 0xfafb8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x11, %esi
callq 0x53110
jmp 0x4ed06
leaq -0x2f0(%rbp), %rdi
callq 0xdc40
jmp 0x4ed14
movq 0xac29d(%rip), %rdi     # 0xfafb8
leaq 0x58573(%rip), %rsi     # 0xa7295
callq 0xd640
movq %rax, -0x348(%rbp)
jmp 0x4ed30
movq -0x348(%rbp), %rdi
movq 0xac252(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4ed45
leaq -0x2b0(%rbp), %rdi
callq 0x53140
jmp 0x4ed53
movq -0x310(%rbp), %rdi
addq $0x48, %rdi
callq 0xfe30
jmp 0x4ed65
leaq -0x1e8(%rbp), %rdi
callq 0x53160
jmp 0x4ed73
leaq -0x2f0(%rbp), %rdi
callq 0x12ca0
leaq -0x2b0(%rbp), %rdi
callq 0x53190
leaq -0x1e8(%rbp), %rdi
callq 0x53190
leaq -0x128(%rbp), %rdi
callq 0x53210
addq $0x350, %rsp            # imm = 0x350
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x23f80
jmp 0x4ee36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x23f80
jmp 0x4ee2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
jmp 0x4ee1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x130(%rbp)
movl %eax, -0x134(%rbp)
leaq -0x2f0(%rbp), %rdi
callq 0x12ca0
leaq -0x2b0(%rbp), %rdi
callq 0x53190
leaq -0x1e8(%rbp), %rdi
callq 0x53190
leaq -0x128(%rbp), %rdi
callq 0x53210
movq -0x130(%rbp), %rdi
callq 0xdcb0
nop