// File: Barath-Kannan[P]SignalsAndSlots/test/SignalTest_Parametrized.cpp
// Function: SignalTestParametrized_Correctness_Test::TestBody()
TEST_P(SignalTestParametrized, Correctness) {
    std::vector<uint32_t> doneFlags(params.nEmissions, 0);
    auto func = ([this, &doneFlags](sigType x) {
        volatile sigType v = x;
        for (uint32_t i = 0; i < params.nOperations; i++) {
            v+=x;
        }
        doneFlags[x] = 1;
        completedFunctions++;
    });

    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;
    
    std::list<thread> emitters;
    thread emitter([this, &signal]() {
        bt2.start();
        bt.start();
        for (counter=0; counter<params.nEmissions; ++counter) {
            signal.emitSignal(counter);
        }
        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();
    for (uint32_t i=0; i<params.nEmissions; i++) ASSERT_TRUE(doneFlags[i]);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x3b0(%rbp)
movl 0x1c(%rax), %eax
movq %rax, -0x3a8(%rbp)
movl $0x0, -0x24(%rbp)
leaq -0x25(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
callq 0x53370
movq -0x3a8(%rbp), %rsi
movq -0x3a0(%rbp), %rcx
leaq -0x20(%rbp), %rdi
leaq -0x24(%rbp), %rdx
callq 0x53390
jmp 0x4e178
leaq -0x25(%rbp), %rdi
callq 0x53410
movq -0x3b0(%rbp), %rax
movq %rax, -0x48(%rbp)
leaq -0x20(%rbp), %rcx
movq %rcx, -0x40(%rbp)
movzbl 0x28(%rax), %esi
andl $0x1, %esi
leaq -0x160(%rbp), %rdi
callq 0x52f30
jmp 0x4e1a9
movq 0xace08(%rip), %rdi     # 0xfafb8
leaq 0x59094(%rip), %rsi     # 0xa724b
callq 0xd640
movq %rax, -0x3b8(%rbp)
jmp 0x4e1c5
movq -0x3b8(%rbp), %rdi
movq -0x3b0(%rbp), %rax
movl 0x18(%rax), %esi
callq 0xd9b0
movq %rax, -0x3c0(%rbp)
jmp 0x4e1e4
movq -0x3c0(%rbp), %rdi
leaq 0x59065(%rip), %rsi     # 0xa7257
callq 0xd640
movq %rax, -0x3c8(%rbp)
jmp 0x4e200
movq -0x3c8(%rbp), %rdi
movq 0xacd82(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4e215
movl $0x0, -0x164(%rbp)
movq -0x3b0(%rbp), %rcx
movl -0x164(%rbp), %eax
cmpl 0x18(%rcx), %eax
jae 0x4e2ed
movq -0x3b0(%rbp), %rax
movl 0x2c(%rax), %eax
movl %eax, -0x3d4(%rbp)
leaq -0x188(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
leaq -0x48(%rbp), %rsi
callq 0x4e7c0
movl -0x3d4(%rbp), %esi
movq -0x3d0(%rbp), %rdx
leaq -0x160(%rbp), %rdi
callq 0x52f60
jmp 0x4e277
leaq -0x188(%rbp), %rdi
callq 0x52fe0
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x4e21f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x25(%rbp), %rdi
callq 0x53410
jmp 0x4e7ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e7a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e799
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x52fe0
jmp 0x4e799
movq -0x3b0(%rbp), %rax
movq %rax, -0x240(%rbp)
leaq -0x238(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x4e850
movl $0x1f4, -0x24c(%rbp)    # imm = 0x1F4
leaq -0x248(%rbp), %rdi
leaq -0x24c(%rbp), %rsi
callq 0x1d220
jmp 0x4e32d
leaq -0x218(%rbp), %rdi
leaq -0x238(%rbp), %rsi
leaq -0x248(%rbp), %rdx
callq 0x53000
jmp 0x4e349
leaq -0x238(%rbp), %rdi
callq 0x23f80
movq -0x3b0(%rbp), %rax
movq %rax, -0x308(%rbp)
leaq -0x300(%rbp), %rdi
leaq -0x308(%rbp), %rsi
callq 0x4e8e0
movl $0x1, -0x314(%rbp)
leaq -0x310(%rbp), %rdi
leaq -0x314(%rbp), %rsi
callq 0x1d220
jmp 0x4e395
leaq -0x2e0(%rbp), %rdi
leaq -0x300(%rbp), %rsi
leaq -0x310(%rbp), %rdx
callq 0x53000
jmp 0x4e3b1
leaq -0x300(%rbp), %rdi
callq 0x23f80
movq 0xacbf4(%rip), %rdi     # 0xfafb8
leaq 0x58e97(%rip), %rsi     # 0xa7262
callq 0xd640
movq %rax, -0x3e0(%rbp)
jmp 0x4e3d9
movq -0x3e0(%rbp), %rdi
movq 0xacba9(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4e3ee
leaq -0x330(%rbp), %rdi
callq 0x1d150
movq -0x3b0(%rbp), %rax
movq %rax, -0x348(%rbp)
leaq -0x160(%rbp), %rax
movq %rax, -0x340(%rbp)
leaq -0x338(%rbp), %rdi
leaq -0x348(%rbp), %rsi
callq 0x4e970
jmp 0x4e42b
movq 0xacb86(%rip), %rdi     # 0xfafb8
leaq 0x58e44(%rip), %rsi     # 0xa727d
callq 0xd640
movq %rax, -0x3e8(%rbp)
jmp 0x4e447
movq -0x3e8(%rbp), %rdi
movq 0xacb3b(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4e45c
movq 0xacb55(%rip), %rdi     # 0xfafb8
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x11, %esi
callq 0x53110
jmp 0x4e479
leaq -0x338(%rbp), %rdi
callq 0xdc40
jmp 0x4e487
movq 0xacb2a(%rip), %rdi     # 0xfafb8
leaq 0x58e00(%rip), %rsi     # 0xa7295
callq 0xd640
movq %rax, -0x3f0(%rbp)
jmp 0x4e4a3
movq -0x3f0(%rbp), %rdi
movq 0xacadf(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x4e4b8
leaq -0x2e0(%rbp), %rdi
callq 0x53140
jmp 0x4e4c6
movq -0x3b0(%rbp), %rdi
addq $0x48, %rdi
callq 0xfe30
jmp 0x4e4d8
leaq -0x218(%rbp), %rdi
callq 0x53160
jmp 0x4e4e6
movl $0x0, -0x34c(%rbp)
movq -0x3b0(%rbp), %rcx
movl -0x34c(%rbp), %eax
cmpl 0x1c(%rcx), %eax
jae 0x4e711
movl -0x34c(%rbp), %eax
movl %eax, %esi
leaq -0x20(%rbp), %rdi
callq 0x53430
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x360(%rbp), %rdi
callq 0x53450
jmp 0x4e52c
leaq -0x360(%rbp), %rdi
callq 0x1c500
movb %al, -0x3f1(%rbp)
jmp 0x4e540
movb -0x3f1(%rbp), %al
testb $0x1, %al
jne 0x4e54f
jmp 0x4e5d2
jmp 0x4e6cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x238(%rbp), %rdi
callq 0x23f80
jmp 0x4e799
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x300(%rbp), %rdi
callq 0x23f80
jmp 0x4e78d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e781
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e775
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e769
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e703
leaq -0x368(%rbp), %rdi
callq 0x6f130
jmp 0x4e5e0
leaq 0x58cf7(%rip), %rdx     # 0xa72de
leaq 0x58cfd(%rip), %rcx     # 0xa72eb
leaq 0x58cfc(%rip), %r8      # 0xa72f1
leaq -0x390(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x711b0
jmp 0x4e60a
leaq -0x390(%rbp), %rdi
callq 0xd260
movq %rax, %r8
leaq 0x58c9d(%rip), %rdx     # 0xa72bd
leaq -0x370(%rbp), %rdi
movl $0x2, %esi
movl $0xa9, %ecx
callq 0x6c7e0
jmp 0x4e638
leaq -0x370(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x6c8a0
jmp 0x4e64d
leaq -0x370(%rbp), %rdi
callq 0x6c860
leaq -0x390(%rbp), %rdi
callq 0xde48
leaq -0x368(%rbp), %rdi
callq 0x1c540
movl $0x1, -0x394(%rbp)
jmp 0x4e6d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e6bd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4e6b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x6c860
leaq -0x390(%rbp), %rdi
callq 0xde48
leaq -0x368(%rbp), %rdi
callq 0x1c540
jmp 0x4e703
movl $0x0, -0x394(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x1c560
movl -0x394(%rbp), %eax
testl %eax, %eax
jne 0x4e71b
jmp 0x4e6ed
jmp 0x4e6ef
movl -0x34c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34c(%rbp)
jmp 0x4e4f0
leaq -0x360(%rbp), %rdi
callq 0x1c560
jmp 0x4e769
movl $0x0, -0x394(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x12ca0
leaq -0x330(%rbp), %rdi
callq 0x1d310
leaq -0x2e0(%rbp), %rdi
callq 0x53190
leaq -0x218(%rbp), %rdi
callq 0x53190
leaq -0x160(%rbp), %rdi
callq 0x53210
leaq -0x20(%rbp), %rdi
callq 0x53490
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
leaq -0x338(%rbp), %rdi
callq 0x12ca0
leaq -0x330(%rbp), %rdi
callq 0x1d310
leaq -0x2e0(%rbp), %rdi
callq 0x53190
leaq -0x218(%rbp), %rdi
callq 0x53190
leaq -0x160(%rbp), %rdi
callq 0x53210
leaq -0x20(%rbp), %rdi
callq 0x53490
movq -0x30(%rbp), %rdi
callq 0xdcb0
nopw (%rax,%rax)