// File: Barath-Kannan[P]SignalsAndSlots/test/SignalTest.cpp
// Function: SignalTest_MultiEmit_Test::TestBody()
TEST_F(SignalTest, MultiEmit){
    cout << "Instantiating signal object" << endl;

    Signal<int, int> testSignal;

    BasicTimer bt;
    BasicTimer bt2;
    cout << "Connecting signal" << endl;
    bt.start();
    int id = testSignal.connectSlot(ExecutorScheme::STRAND, staticSumFunction);
    bt.stop();
    cout << "Time to connect: " << bt.getElapsedMilliseconds() << "ms" << endl;

    cout << "Emitting signal" << endl;

    bt.start();
    list<thread> threads;
    const uint32_t nThreads = 64;
    std::atomic<uint32_t> threadsRemaining{nThreads};
    for (uint32_t i=0; i<nThreads; i++){
        threads.emplace_back([&, i](){
            for (uint32_t i=0; i<1000000; ++i){
                testSignal.emitSignal(1, 2);
            }
            uint32_t tr = threadsRemaining.fetch_sub(1);
            cout << "Threads remaining: " << tr-1 << endl;
            cout << "globalStaticInt: " << globalStaticIntX << endl;
        });
    }
    bt.stop();
    
    bt2.start();
    while (bt2.getElapsedSeconds() < 60.0) {
        if (globalStaticIntX == 1000000*3*nThreads) {
            bt2.stop();
            break;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    //ASSERT_LT(bt2.getElapsedSeconds(), 0.1);
    cout << "Time to emit: " << bt.getElapsedMilliseconds() << "ms" << endl;
    cout << "Time to emit and process: " << bt2.getElapsedMilliseconds() << "ms" << endl;
    cout << "Net time to process: " << bt2.getElapsedMilliseconds() - bt.getElapsedMilliseconds() << "ms" << endl;

    ASSERT_EQ(0, id);

    testSignal.disconnectAllSlots();
    for (auto &t : threads) t.join();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2f0, %rsp            # imm = 0x2F0
movq %rdi, -0x8(%rbp)
movq 0xdff62(%rip), %rdi     # 0xfafb8
leaq 0x8a662(%rip), %rsi     # 0xa56bf
callq 0xd640
movq %rax, %rdi
movq 0xdff24(%rip), %rsi     # 0xfaf90
callq 0xd6e0
leaq -0x120(%rbp), %rdi
callq 0x1c140
leaq -0x138(%rbp), %rdi
callq 0xfc20
jmp 0x1b08b
leaq -0x160(%rbp), %rdi
callq 0xfc20
jmp 0x1b099
movq 0xdff18(%rip), %rdi     # 0xfafb8
leaq 0x8a660(%rip), %rsi     # 0xa5707
callq 0xd640
movq %rax, -0x230(%rbp)
jmp 0x1b0b5
movq -0x230(%rbp), %rdi
movq 0xdfecd(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b0ca
leaq -0x138(%rbp), %rdi
callq 0xfde0
jmp 0x1b0d8
leaq -0x336f(%rip), %rsi     # 0x17d70
leaq -0x188(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x1c3d0
movq -0x240(%rbp), %rdx
leaq -0x120(%rbp), %rdi
movl $0x3, %esi
callq 0x1c350
movl %eax, -0x234(%rbp)
jmp 0x1b112
leaq -0x188(%rbp), %rdi
callq 0x1c460
movl -0x234(%rbp), %eax
movl %eax, -0x164(%rbp)
leaq -0x138(%rbp), %rdi
callq 0xfe30
jmp 0x1b138
movq 0xdfe79(%rip), %rdi     # 0xfafb8
leaq 0x8a5d3(%rip), %rsi     # 0xa5719
callq 0xd640
movq %rax, -0x248(%rbp)
jmp 0x1b154
leaq -0x138(%rbp), %rdi
callq 0xfd00
movsd %xmm0, -0x250(%rbp)
jmp 0x1b16a
movsd -0x250(%rbp), %xmm0
movq -0x248(%rbp), %rdi
callq 0xddc0
movq %rax, -0x258(%rbp)
jmp 0x1b187
movq -0x258(%rbp), %rdi
leaq 0x8c006(%rip), %rsi     # 0xa719b
callq 0xd640
movq %rax, -0x260(%rbp)
jmp 0x1b1a3
movq -0x260(%rbp), %rdi
movq 0xdfddf(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b1b8
movq 0xdfdf9(%rip), %rdi     # 0xfafb8
leaq 0x8a565(%rip), %rsi     # 0xa572b
callq 0xd640
movq %rax, -0x268(%rbp)
jmp 0x1b1d4
movq -0x268(%rbp), %rdi
movq 0xdfdae(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b1e9
leaq -0x138(%rbp), %rdi
callq 0xfde0
jmp 0x1b1f7
leaq -0x1a0(%rbp), %rdi
callq 0x1d150
movl $0x40, -0x1a4(%rbp)
movl 0x8a7d9(%rip), %eax     # 0xa59ec
movl %eax, -0x1a8(%rbp)
movl $0x0, -0x1ac(%rbp)
cmpl $0x40, -0x1ac(%rbp)
jae 0x1b2d1
movl -0x1ac(%rbp), %eax
movl %eax, -0x1c8(%rbp)
leaq -0x120(%rbp), %rax
movq %rax, -0x1c0(%rbp)
leaq -0x1a8(%rbp), %rax
movq %rax, -0x1b8(%rbp)
leaq -0x1a0(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x1b760
jmp 0x1b26d
jmp 0x1b26f
movl -0x1ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ac(%rbp)
jmp 0x1b223
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
jmp 0x1b740
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x1c460
jmp 0x1b740
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
jmp 0x1b734
leaq -0x138(%rbp), %rdi
callq 0xfe30
jmp 0x1b2df
leaq -0x160(%rbp), %rdi
callq 0xfde0
jmp 0x1b2ed
jmp 0x1b2ef
leaq -0x160(%rbp), %rdi
callq 0xfc60
movsd %xmm0, -0x270(%rbp)
jmp 0x1b305
movsd -0x270(%rbp), %xmm1
movsd 0x89e83(%rip), %xmm0    # 0xa5198
ucomisd %xmm1, %xmm0
jbe 0x1b36d
leaq 0x132552(%rip), %rdi    # 0x14d874
callq 0x1c740
cmpl $0xb71b000, %eax        # imm = 0xB71B000
jne 0x1b33e
leaq -0x160(%rbp), %rdi
callq 0xfe30
jmp 0x1b33c
jmp 0x1b36d
movl $0x64, -0x1d4(%rbp)
leaq -0x1d0(%rbp), %rdi
leaq -0x1d4(%rbp), %rsi
callq 0x1d220
jmp 0x1b35d
leaq -0x1d0(%rbp), %rdi
callq 0x1d170
jmp 0x1b36b
jmp 0x1b2ef
movq 0xdfc44(%rip), %rdi     # 0xfafb8
leaq 0x8a3c0(%rip), %rsi     # 0xa573b
callq 0xd640
movq %rax, -0x278(%rbp)
jmp 0x1b389
leaq -0x138(%rbp), %rdi
callq 0xfd00
movsd %xmm0, -0x280(%rbp)
jmp 0x1b39f
movsd -0x280(%rbp), %xmm0
movq -0x278(%rbp), %rdi
callq 0xddc0
movq %rax, -0x288(%rbp)
jmp 0x1b3bc
movq -0x288(%rbp), %rdi
leaq 0x8bdd1(%rip), %rsi     # 0xa719b
callq 0xd640
movq %rax, -0x290(%rbp)
jmp 0x1b3d8
movq -0x290(%rbp), %rdi
movq 0xdfbaa(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b3ed
movq 0xdfbc4(%rip), %rdi     # 0xfafb8
leaq 0x8a3ab(%rip), %rsi     # 0xa57a6
callq 0xd640
movq %rax, -0x298(%rbp)
jmp 0x1b409
leaq -0x160(%rbp), %rdi
callq 0xfd00
movsd %xmm0, -0x2a0(%rbp)
jmp 0x1b41f
movsd -0x2a0(%rbp), %xmm0
movq -0x298(%rbp), %rdi
callq 0xddc0
movq %rax, -0x2a8(%rbp)
jmp 0x1b43c
movq -0x2a8(%rbp), %rdi
leaq 0x8bd51(%rip), %rsi     # 0xa719b
callq 0xd640
movq %rax, -0x2b0(%rbp)
jmp 0x1b458
movq -0x2b0(%rbp), %rdi
movq 0xdfb2a(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b46d
movq 0xdfb44(%rip), %rdi     # 0xfafb8
leaq 0x8a346(%rip), %rsi     # 0xa57c1
callq 0xd640
movq %rax, -0x2b8(%rbp)
jmp 0x1b489
leaq -0x160(%rbp), %rdi
callq 0xfd00
movsd %xmm0, -0x2c0(%rbp)
jmp 0x1b49f
leaq -0x138(%rbp), %rdi
callq 0xfd00
movsd %xmm0, -0x2c8(%rbp)
jmp 0x1b4b5
movq -0x2b8(%rbp), %rdi
movsd -0x2c8(%rbp), %xmm1
movsd -0x2c0(%rbp), %xmm0
subsd %xmm1, %xmm0
callq 0xddc0
movq %rax, -0x2d0(%rbp)
jmp 0x1b4de
movq -0x2d0(%rbp), %rdi
leaq 0x8bcaf(%rip), %rsi     # 0xa719b
callq 0xd640
movq %rax, -0x2d8(%rbp)
jmp 0x1b4fa
movq -0x2d8(%rbp), %rdi
movq 0xdfa88(%rip), %rsi     # 0xfaf90
callq 0xd6e0
jmp 0x1b50f
movl $0x0, -0x1ec(%rbp)
leaq 0x9022f(%rip), %rsi     # 0xab74f
leaq 0x8f5d2(%rip), %rdx     # 0xaaaf9
xorl %eax, %eax
movl %eax, %r9d
leaq -0x1e8(%rbp), %rdi
leaq -0x1ec(%rbp), %rcx
leaq -0x164(%rbp), %r8
callq 0x1c580
jmp 0x1b548
leaq -0x1e8(%rbp), %rdi
callq 0x1c500
movb %al, -0x2d9(%rbp)
jmp 0x1b55c
movb -0x2d9(%rbp), %al
testb $0x1, %al
jne 0x1b568
jmp 0x1b584
jmp 0x1b649
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
jmp 0x1b6fb
leaq -0x1f8(%rbp), %rdi
callq 0x6f130
jmp 0x1b592
leaq -0x1e8(%rbp), %rdi
callq 0x1c520
movq %rax, -0x2e8(%rbp)
jmp 0x1b5a7
movq -0x2e8(%rbp), %r8
leaq 0x8a0f6(%rip), %rdx     # 0xa56ab
leaq -0x200(%rbp), %rdi
movl $0x2, %esi
movl $0x15e, %ecx            # imm = 0x15E
callq 0x6c7e0
jmp 0x1b5cd
leaq -0x200(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x6c8a0
jmp 0x1b5e2
leaq -0x200(%rbp), %rdi
callq 0x6c860
leaq -0x1f8(%rbp), %rdi
callq 0x1c540
movl $0x1, -0x204(%rbp)
jmp 0x1b653
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
jmp 0x1b638
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x140(%rbp)
movl %eax, -0x144(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x6c860
leaq -0x1f8(%rbp), %rdi
callq 0x1c540
jmp 0x1b6fb
movl $0x0, -0x204(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x1c560
movl -0x204(%rbp), %eax
testl %eax, %eax
jne 0x1b713
jmp 0x1b66f
leaq -0x120(%rbp), %rdi
callq 0x1c880
jmp 0x1b67d
leaq -0x1a0(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x210(%rbp), %rdi
callq 0x1d240
movq %rax, -0x218(%rbp)
movq -0x210(%rbp), %rdi
callq 0x1d270
movq %rax, -0x220(%rbp)
leaq -0x218(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x1d2a0
testb $0x1, %al
jne 0x1b6ca
jmp 0x1b709
leaq -0x218(%rbp), %rdi
callq 0x1d2d0
movq %rax, -0x228(%rbp)
movq -0x228(%rbp), %rdi
callq 0xdc40
jmp 0x1b6eb
jmp 0x1b6ed
leaq -0x218(%rbp), %rdi
callq 0x1d2f0
jmp 0x1b6b1
leaq -0x1e8(%rbp), %rdi
callq 0x1c560
jmp 0x1b734
movl $0x0, -0x204(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x1d310
leaq -0x120(%rbp), %rdi
callq 0x1c2f0
addq $0x2f0, %rsp            # imm = 0x2F0
popq %rbp
retq
leaq -0x1a0(%rbp), %rdi
callq 0x1d310
leaq -0x120(%rbp), %rdi
callq 0x1c2f0
movq -0x140(%rbp), %rdi
callq 0xdcb0
nopl (%rax,%rax)